Skip to content

Commit

Permalink
Better framepacing - Windows SDL Edition (Kenix3#330)
Browse files Browse the repository at this point in the history
* Use high-resolution timer on Win 10

* Better timing for windows

Couldn't figure out that stuff for other compilers, OSes and architectures. sorry
  • Loading branch information
Spodi authored Oct 2, 2023
1 parent 6671d7e commit 3abe308
Showing 1 changed file with 18 additions and 2 deletions.
20 changes: 18 additions & 2 deletions src/graphic/Fast3D/gfx_sdl2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "gfx_screen_config.h"
#ifdef _WIN32
#include <WTypesbase.h>
#include <Windows.h>
#endif

#define GFX_BACKEND_NAME "SDL"
Expand Down Expand Up @@ -318,7 +319,12 @@ static void gfx_sdl_init(const char* game_name, const char* gfx_api_name, bool s
#endif

#ifdef _WIN32
timer = CreateWaitableTimer(nullptr, false, nullptr);
// Use high-resolution timer by default on Windows 10 (so that NtSetTimerResolution (...) hacks are not needed)
timer = CreateWaitableTimerExW(nullptr, nullptr, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
// Fallback to low resolution timer if unsupported by the OS
if (timer == nullptr) {
timer = CreateWaitableTimer(nullptr, false, nullptr);
}
#endif

char title[512];
Expand Down Expand Up @@ -535,7 +541,11 @@ static inline void sync_framerate_with_timer(void) {
t = qpc_to_100ns(SDL_GetPerformanceCounter());

const int64_t next = previous_time + 10 * FRAME_INTERVAL_US_NUMERATOR / FRAME_INTERVAL_US_DENOMINATOR;
const int64_t left = next - t;
int64_t left = next - t;
#ifdef _WIN32
// We want to exit a bit early, so we can busy-wait the rest to never miss the deadline
left -= 15000UL;
#endif
if (left > 0) {
#ifndef _WIN32
const timespec spec = { 0, left * 100 };
Expand All @@ -549,6 +559,12 @@ static inline void sync_framerate_with_timer(void) {
#endif
}

#ifdef _WIN32
do {
YieldProcessor(); // TODO: Find a way for other compilers, OSes and architectures
t = qpc_to_100ns(SDL_GetPerformanceCounter());
} while (t < next);
#endif
t = qpc_to_100ns(SDL_GetPerformanceCounter());
if (left > 0 && t - next < 10000) {
// In case it takes some time for the application to wake up after sleep,
Expand Down

0 comments on commit 3abe308

Please sign in to comment.