mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-18 11:19:10 +00:00
Always use hsTimer for profile stats.
This fixes the weird flickering and inaccurate numbers that were showing up on Windows.
This commit is contained in:
@ -42,134 +42,10 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
#include "plProfileManager.h"
|
||||
#include "plProfile.h"
|
||||
#include "hsTimer.h"
|
||||
#include "hsWindows.h"
|
||||
|
||||
|
||||
static uint32_t gCyclesPerMS = 0;
|
||||
|
||||
#ifdef HS_BUILD_FOR_WIN32
|
||||
#define USE_FAST_TIMER
|
||||
#endif
|
||||
|
||||
#ifdef USE_FAST_TIMER
|
||||
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable : 4035) // disable no return value warning
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define forceinline __forceinline
|
||||
#else
|
||||
#define forceinline inline
|
||||
#endif
|
||||
|
||||
forceinline uint32_t GetPentiumCounter()
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
__asm {
|
||||
xor eax,eax // VC won't realize that eax is modified w/out this
|
||||
// instruction to modify the val.
|
||||
// Problem shows up in release mode builds
|
||||
_emit 0x0F // Pentium high-freq counter to edx;eax
|
||||
_emit 0x31 // only care about low 32 bits in eax
|
||||
|
||||
xor edx,edx // so VC gets that edx is modified
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#pragma warning (pop)
|
||||
|
||||
|
||||
|
||||
static uint32_t GetProcSpeed()
|
||||
{
|
||||
const char* keypath[] =
|
||||
{
|
||||
"HARDWARE",
|
||||
"DESCRIPTION",
|
||||
"System",
|
||||
"CentralProcessor",
|
||||
"0"
|
||||
};
|
||||
|
||||
HKEY hKey = HKEY_LOCAL_MACHINE;
|
||||
|
||||
int numKeys = sizeof(keypath) / sizeof(char*);
|
||||
for (int i = 0; i < numKeys; i++)
|
||||
{
|
||||
HKEY thisKey = NULL;
|
||||
bool success = (RegOpenKeyEx(hKey, keypath[i], 0, KEY_READ, &thisKey) == ERROR_SUCCESS);
|
||||
|
||||
RegCloseKey(hKey);
|
||||
hKey = thisKey;
|
||||
|
||||
if (!success)
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD value=0, size=sizeof(DWORD);
|
||||
bool success = (RegQueryValueEx(hKey, "~MHz", 0, NULL, (BYTE*)&value, &size) == ERROR_SUCCESS);
|
||||
RegCloseKey(hKey);
|
||||
|
||||
return value*1000000;
|
||||
}
|
||||
|
||||
uint32_t GetProcSpeedAlt()
|
||||
{
|
||||
const uint32_t kSamplePeriodMS = 250;
|
||||
|
||||
// Raise priority to avoid interference from other threads.
|
||||
int priority = GetThreadPriority(GetCurrentThread());
|
||||
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
|
||||
|
||||
uint32_t startTicks, endTicks;
|
||||
uint64_t pcStart, pcEnd;
|
||||
|
||||
// Count number of processor cycles inside the specified interval
|
||||
QueryPerformanceCounter((LARGE_INTEGER*)&pcStart);
|
||||
startTicks = plProfileManager::GetTime();
|
||||
Sleep(kSamplePeriodMS);
|
||||
endTicks = plProfileManager::GetTime();
|
||||
QueryPerformanceCounter((LARGE_INTEGER*)&pcEnd);
|
||||
|
||||
// Restore thread priority.
|
||||
SetThreadPriority(GetCurrentThread(), priority);
|
||||
|
||||
// Calculate Rdtsc/PerformanceCounter ratio;
|
||||
uint32_t numTicks = endTicks - startTicks;
|
||||
uint64_t pcDiff = pcEnd - pcStart;
|
||||
|
||||
double ratio = double(numTicks) / double(pcDiff);
|
||||
uint64_t pcFreq;
|
||||
QueryPerformanceFrequency((LARGE_INTEGER*)&pcFreq);
|
||||
|
||||
// Calculate CPU frequency.
|
||||
uint64_t cpuFreq = uint64_t(pcFreq * ratio);
|
||||
|
||||
return (uint32_t)cpuFreq;
|
||||
}
|
||||
|
||||
#define GetProfileTicks() GetPentiumCounter()
|
||||
#define TicksToMSec(t) (float(t) / float(gCyclesPerMS))
|
||||
|
||||
#else
|
||||
|
||||
#define GetProfileTicks() hsTimer::GetTicks()
|
||||
#define TicksToMSec(t) hsTimer::GetMilliSeconds<float>(t)
|
||||
|
||||
#endif // USE_FAST_TIMER
|
||||
|
||||
|
||||
plProfileManager::plProfileManager() : fLastAvgTime(0), fProcessorSpeed(0)
|
||||
{
|
||||
#ifdef USE_FAST_TIMER
|
||||
fProcessorSpeed = GetProcSpeed();
|
||||
// Registry stuff only works on NT OS's, have to calc it otherwise
|
||||
if (fProcessorSpeed == 0)
|
||||
fProcessorSpeed = GetProcSpeedAlt();
|
||||
|
||||
gCyclesPerMS = fProcessorSpeed / 1000;
|
||||
#endif
|
||||
}
|
||||
|
||||
plProfileManager::~plProfileManager()
|
||||
@ -251,7 +127,7 @@ void plProfileManager::EndFrame()
|
||||
|
||||
uint64_t plProfileManager::GetTime()
|
||||
{
|
||||
return GetProfileTicks();
|
||||
return hsTimer::GetTicks();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -301,7 +177,7 @@ void plProfileBase::UpdateAvg()
|
||||
uint64_t plProfileBase::GetValue()
|
||||
{
|
||||
if (hsCheckBits(fDisplayFlags, kDisplayTime))
|
||||
return (uint64_t)TicksToMSec(fValue);
|
||||
return hsTimer::GetMilliSeconds<uint64_t>(fValue);
|
||||
else
|
||||
return fValue;
|
||||
}
|
||||
@ -346,11 +222,11 @@ void plProfileBase::IPrintValue(uint64_t value, char* buf, bool printType)
|
||||
}
|
||||
else if (hsCheckBits(fDisplayFlags, kDisplayFPS))
|
||||
{
|
||||
sprintf(buf, "%.2f", 1000.0f / TicksToMSec(value));
|
||||
sprintf(buf, "%.2f", 1000.0f / hsTimer::GetMilliSeconds<float>(value));
|
||||
}
|
||||
else if (hsCheckBits(fDisplayFlags, kDisplayTime))
|
||||
{
|
||||
sprintf(buf, "%.2f", TicksToMSec(value));
|
||||
sprintf(buf, "%.2f", hsTimer::GetMilliSeconds<float>(value));
|
||||
if (printType)
|
||||
strcat(buf, " ms");
|
||||
}
|
||||
@ -524,12 +400,12 @@ void plProfileVar::IBeginTiming()
|
||||
if( hsCheckBits( fDisplayFlags, kDisplayResetEveryBegin ) )
|
||||
fValue = 0;
|
||||
|
||||
fValue -= GetProfileTicks();
|
||||
fValue -= hsTimer::GetTicks();
|
||||
}
|
||||
|
||||
void plProfileVar::IEndTiming()
|
||||
{
|
||||
fValue += GetProfileTicks();
|
||||
fValue += hsTimer::GetTicks();
|
||||
|
||||
fTimerSamples++;
|
||||
|
||||
|
Reference in New Issue
Block a user