Improve screen vector timing somewhat.

This patch tries to improve the accuracy of our
screen refresh timing. Notably, it tries to ensure
we don't introduce extra delay in our timing based
on how long the screen vector takes to evaluate.

We also try to ensure we only call SDL_Delay when
we have at least 1ms to wait.
This commit is contained in:
~d6 2023-05-09 16:07:17 -04:00 committed by Devine Lu Linvega
parent 09d9990a62
commit 310ba97ef6
1 changed files with 16 additions and 13 deletions

View File

@ -456,28 +456,31 @@ handle_events(Uxn *u)
static int static int
run(Uxn *u) run(Uxn *u)
{ {
Uint64 now = SDL_GetPerformanceCounter(), frame_end, frame_interval = SDL_GetPerformanceFrequency() / 60; Uint64 next_refresh = 0;
Uint64 now = SDL_GetPerformanceCounter();
Uint64 frame_interval = SDL_GetPerformanceFrequency() / 60;
for(;;) { for(;;) {
Uint16 screen_vector; Uint16 screen_vector;
/* .System/halt */ /* .System/halt */
if(u->dev[0x0f]) if(u->dev[0x0f])
return system_error("Run", "Ended."); return system_error("Run", "Ended.");
frame_end = now + frame_interval; now = SDL_GetPerformanceCounter();
exec_deadline = now + deadline_interval; exec_deadline = now + deadline_interval;
if(!handle_events(u)) if(!handle_events(u))
return 0; return 0;
screen_vector = PEEK2(&u->dev[0x20]); screen_vector = PEEK2(&u->dev[0x20]);
if(BENCH || now >= next_refresh) {
now = SDL_GetPerformanceCounter();
next_refresh = now + frame_interval;
uxn_eval(u, screen_vector); uxn_eval(u, screen_vector);
if(uxn_screen.x2) if(uxn_screen.x2)
redraw(); redraw();
now = SDL_GetPerformanceCounter();
if(screen_vector) {
if(!BENCH && ((Sint64)(frame_end - now)) > 0) {
SDL_Delay((frame_end - now) / ms_interval);
now = frame_end;
} }
} else if(BENCH);
SDL_WaitEvent(NULL); else if(screen_vector || uxn_screen.x2) {
Uint64 delay_ms = (next_refresh - now) / ms_interval;
if(delay_ms > 0) SDL_Delay(delay_ms);
} else SDL_WaitEvent(NULL);
} }
} }