Use ::QueryPerformanceCounter() for wxStopWatch implementation in wxMSW.
QueryPerformanceCounter() provides higher resolution and precision for measuring time under MSW, even though it suffers from some problems in older Windows versions. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@69834 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -25,6 +25,13 @@
|
|||||||
wxLogMessage("And calling it twice took $ldms in all", sw.Time());
|
wxLogMessage("And calling it twice took $ldms in all", sw.Time());
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
|
Since wxWidgets 2.9.3 this class uses @c ::QueryPerformanceCounter()
|
||||||
|
function under MSW to measure the elapsed time. It provides higher
|
||||||
|
precision than the usual timer functions but can suffer from bugs in its
|
||||||
|
implementation in some Windows XP versions. If you encounter such problems,
|
||||||
|
installing a Microsoft hot fix from http://support.microsoft.com/?id=896256
|
||||||
|
could be necessary.
|
||||||
|
|
||||||
@library{wxbase}
|
@library{wxbase}
|
||||||
@category{misc}
|
@category{misc}
|
||||||
|
|
||||||
|
@@ -95,50 +95,70 @@
|
|||||||
|
|
||||||
#if wxUSE_STOPWATCH
|
#if wxUSE_STOPWATCH
|
||||||
|
|
||||||
|
#ifdef __WXMSW__
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
struct PerfCounter
|
||||||
|
{
|
||||||
|
PerfCounter()
|
||||||
|
{
|
||||||
|
init = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CanBeUsed() const
|
||||||
|
{
|
||||||
|
return freq.QuadPart != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxCriticalSection cs;
|
||||||
|
LARGE_INTEGER freq;
|
||||||
|
bool init;
|
||||||
|
} gs_perfCounter;
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
#endif // __WXMSW__
|
||||||
|
|
||||||
void wxStopWatch::Start(long t)
|
void wxStopWatch::Start(long t)
|
||||||
{
|
{
|
||||||
#if 0
|
#ifdef __WXMSW__
|
||||||
// __WXMSW__
|
if ( !gs_perfCounter.init )
|
||||||
LARGE_INTEGER frequency_li;
|
{
|
||||||
::QueryPerformanceFrequency( &frequency_li );
|
wxCriticalSectionLocker lock(gs_perfCounter.cs);
|
||||||
m_frequency = frequency_li.QuadPart;
|
::QueryPerformanceFrequency(&gs_perfCounter.freq);
|
||||||
if (m_frequency == 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_t0 = wxGetLocalTimeMillis() - t;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
LARGE_INTEGER counter_li;
|
|
||||||
::QueryPerformanceCounter( &counter_li );
|
|
||||||
wxLongLong counter = counter_li.QuadPart;
|
|
||||||
m_t0 = (counter * 10000 / m_frequency) - t*10;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
m_t0 = wxGetLocalTimeMillis() - t;
|
|
||||||
#endif
|
|
||||||
m_pause = 0;
|
m_pause = 0;
|
||||||
m_pauseCount = 0;
|
m_pauseCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
long wxStopWatch::GetElapsedTime() const
|
long wxStopWatch::GetElapsedTime() const
|
||||||
{
|
{
|
||||||
#if 0
|
#ifdef __WXMSW__
|
||||||
//__WXMSW__
|
LARGE_INTEGER counter;
|
||||||
if (m_frequency == 0)
|
if ( gs_perfCounter.CanBeUsed() && ::QueryPerformanceCounter(&counter) )
|
||||||
{
|
{
|
||||||
return (wxGetLocalTimeMillis() - m_t0).GetLo();
|
wxLongLong delta(counter.QuadPart);
|
||||||
|
delta -= m_t0;
|
||||||
|
|
||||||
|
return ((delta*1000)/gs_perfCounter.freq.QuadPart).GetLo();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
LARGE_INTEGER counter_li;
|
|
||||||
::QueryPerformanceCounter( &counter_li );
|
|
||||||
wxLongLong counter = counter_li.QuadPart;
|
|
||||||
wxLongLong res = (counter * 10000 / m_frequency) - m_t0;
|
|
||||||
return res.GetLo() / 10;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
return (wxGetLocalTimeMillis() - m_t0).GetLo();
|
|
||||||
#endif
|
#endif
|
||||||
|
return (wxGetLocalTimeMillis() - m_t0).GetLo();
|
||||||
}
|
}
|
||||||
|
|
||||||
long wxStopWatch::Time() const
|
long wxStopWatch::Time() const
|
||||||
|
Reference in New Issue
Block a user