mirror of
https://github.com/AxioDL/metaforce.git
synced 2025-05-13 16:31:21 +00:00
Improve frame limiter on Windows
This commit is contained in:
parent
eae0696bea
commit
8a046832eb
@ -81,29 +81,35 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
bool m_initialized;
|
|
||||||
double m_countPerNs;
|
|
||||||
|
|
||||||
void NanoSleep(const duration_t duration) {
|
void NanoSleep(const duration_t duration) {
|
||||||
if (!m_initialized) {
|
static bool initialized = false;
|
||||||
|
static double countPerNs;
|
||||||
|
static size_t numSleeps = 0;
|
||||||
|
|
||||||
|
// QueryPerformanceFrequency's result is constant, but calling it occasionally
|
||||||
|
// appears to stabilize QueryPerformanceCounter. Without it, the game drifts
|
||||||
|
// from 60hz to 144hz. (Cursed, but I suspect it's NVIDIA/G-SYNC related)
|
||||||
|
if (!initialized || numSleeps++ % 1000 == 0) {
|
||||||
LARGE_INTEGER freq;
|
LARGE_INTEGER freq;
|
||||||
QueryPerformanceFrequency(&freq);
|
if (QueryPerformanceFrequency(&freq) == 0) {
|
||||||
m_countPerNs = static_cast<double>(freq.QuadPart) / 1000000000.0;
|
spdlog::warn("QueryPerformanceFrequency failed: {}", GetLastError());
|
||||||
m_initialized = true;
|
return;
|
||||||
|
}
|
||||||
|
countPerNs = static_cast<double>(freq.QuadPart) / 1e9;
|
||||||
|
initialized = true;
|
||||||
|
numSleeps = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD ms = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
|
LARGE_INTEGER start, current;
|
||||||
auto tickCount = static_cast<LONGLONG>(static_cast<double>(duration.count()) * m_countPerNs);
|
QueryPerformanceCounter(&start);
|
||||||
LARGE_INTEGER count;
|
LONGLONG ticksToWait = static_cast<LONGLONG>(duration.count() * countPerNs);
|
||||||
QueryPerformanceCounter(&count);
|
if (DWORD ms = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count(); ms > 1) {
|
||||||
if (ms > 10) {
|
::Sleep(ms - 1);
|
||||||
// Adjust for Sleep overhead
|
|
||||||
::Sleep(ms - 10);
|
|
||||||
}
|
}
|
||||||
auto end = count.QuadPart + tickCount;
|
|
||||||
do {
|
do {
|
||||||
QueryPerformanceCounter(&count);
|
QueryPerformanceCounter(¤t);
|
||||||
} while (count.QuadPart < end);
|
_mm_pause(); // Yield CPU
|
||||||
|
} while (current.QuadPart - start.QuadPart < ticksToWait);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void NanoSleep(const duration_t duration) { std::this_thread::sleep_for(duration); }
|
void NanoSleep(const duration_t duration) { std::this_thread::sleep_for(duration); }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user