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:
Vadim Zeitlin
2011-11-27 19:50:08 +00:00
parent c439998525
commit 54647bb750
2 changed files with 57 additions and 30 deletions

View File

@@ -95,50 +95,70 @@
#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)
{
#if 0
// __WXMSW__
LARGE_INTEGER frequency_li;
::QueryPerformanceFrequency( &frequency_li );
m_frequency = frequency_li.QuadPart;
if (m_frequency == 0)
#ifdef __WXMSW__
if ( !gs_perfCounter.init )
{
wxCriticalSectionLocker lock(gs_perfCounter.cs);
::QueryPerformanceFrequency(&gs_perfCounter.freq);
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;
}
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_pauseCount = 0;
}
long wxStopWatch::GetElapsedTime() const
{
#if 0
//__WXMSW__
if (m_frequency == 0)
#ifdef __WXMSW__
LARGE_INTEGER counter;
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
return (wxGetLocalTimeMillis() - m_t0).GetLo();
}
long wxStopWatch::Time() const