Added wxStopWatch::TimeInMicro() for better precision time measurement.
Also simplify/streamline wxStopWatch implementation and replace confusingly named m_pause with more clear m_elapsedBeforePause. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@69835 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -95,11 +95,11 @@
|
||||
|
||||
#if wxUSE_STOPWATCH
|
||||
|
||||
#ifdef __WXMSW__
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
#ifdef __WXMSW__
|
||||
|
||||
struct PerfCounter
|
||||
{
|
||||
PerfCounter()
|
||||
@@ -117,53 +117,79 @@ struct PerfCounter
|
||||
bool init;
|
||||
} gs_perfCounter;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
#endif // __WXMSW__
|
||||
|
||||
void wxStopWatch::Start(long t)
|
||||
const int MILLISECONDS_PER_SECOND = 1000;
|
||||
const int MICROSECONDS_PER_SECOND = 1000*1000;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void wxStopWatch::DoStart()
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
if ( !gs_perfCounter.init )
|
||||
{
|
||||
wxCriticalSectionLocker lock(gs_perfCounter.cs);
|
||||
::QueryPerformanceFrequency(&gs_perfCounter.freq);
|
||||
|
||||
// Just a sanity check: it's not supposed to happen but verify that
|
||||
// ::QueryPerformanceCounter() succeeds so that we can really use it.
|
||||
LARGE_INTEGER counter;
|
||||
if ( !::QueryPerformanceCounter(&counter) )
|
||||
{
|
||||
wxLogDebug("QueryPerformanceCounter() unexpected failed (%s), "
|
||||
"will not use it.", wxSysErrorMsg());
|
||||
|
||||
gs_perfCounter.freq.QuadPart = 0;
|
||||
}
|
||||
|
||||
gs_perfCounter.init = true;
|
||||
}
|
||||
|
||||
LARGE_INTEGER counter;
|
||||
if ( gs_perfCounter.CanBeUsed() && ::QueryPerformanceCounter(&counter) )
|
||||
{
|
||||
m_t0 = counter.QuadPart - t*gs_perfCounter.freq.QuadPart/1000;
|
||||
}
|
||||
else // Fall back to the generic code below.
|
||||
#endif // __WXMSW__
|
||||
{
|
||||
m_t0 = wxGetLocalTimeMillis() - t;
|
||||
}
|
||||
|
||||
m_pause = 0;
|
||||
m_pauseCount = 0;
|
||||
m_t0 = GetCurrentClockValue();
|
||||
}
|
||||
|
||||
long wxStopWatch::GetElapsedTime() const
|
||||
wxLongLong wxStopWatch::GetClockFreq() const
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
LARGE_INTEGER counter;
|
||||
if ( gs_perfCounter.CanBeUsed() && ::QueryPerformanceCounter(&counter) )
|
||||
{
|
||||
wxLongLong delta(counter.QuadPart);
|
||||
delta -= m_t0;
|
||||
// Under MSW we use the high resolution performance counter timer which has
|
||||
// its own frequency (usually related to the CPU clock speed).
|
||||
if ( gs_perfCounter.CanBeUsed() )
|
||||
return gs_perfCounter.freq.QuadPart;
|
||||
#endif // __WXMSW__
|
||||
|
||||
return ((delta*1000)/gs_perfCounter.freq.QuadPart).GetLo();
|
||||
}
|
||||
#endif
|
||||
return (wxGetLocalTimeMillis() - m_t0).GetLo();
|
||||
// Currently milliseconds are used everywhere else.
|
||||
return MILLISECONDS_PER_SECOND;
|
||||
}
|
||||
|
||||
long wxStopWatch::Time() const
|
||||
void wxStopWatch::Start(long t0)
|
||||
{
|
||||
return m_pauseCount ? m_pause : GetElapsedTime();
|
||||
DoStart();
|
||||
|
||||
m_t0 -= (wxLongLong(t0)*GetClockFreq())/MILLISECONDS_PER_SECOND;
|
||||
}
|
||||
|
||||
wxLongLong wxStopWatch::GetCurrentClockValue() const
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
if ( gs_perfCounter.CanBeUsed() )
|
||||
{
|
||||
LARGE_INTEGER counter;
|
||||
::QueryPerformanceCounter(&counter);
|
||||
return counter.QuadPart;
|
||||
}
|
||||
#endif // __WXMSW__
|
||||
|
||||
return wxGetLocalTimeMillis();
|
||||
}
|
||||
|
||||
wxLongLong wxStopWatch::TimeInMicro() const
|
||||
{
|
||||
const wxLongLong elapsed(m_pauseCount ? m_elapsedBeforePause
|
||||
: GetCurrentClockValue() - m_t0);
|
||||
|
||||
return (elapsed*MICROSECONDS_PER_SECOND)/GetClockFreq();
|
||||
}
|
||||
|
||||
#endif // wxUSE_STOPWATCH
|
||||
|
||||
Reference in New Issue
Block a user