SDL: Calculate simulated vsync interval based on display refresh rate

From e2753e19e8b09a5f2bfa7b7ce493e7e022dedba4 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 15 Sep 2022 08:02:14 -0700
Subject: [PATCH] Calculate simulated vsync interval based on display refresh
 rate

---
 src/render/SDL_render.c    | 23 ++++++++++++++++++++++-
 src/render/SDL_sysrender.h |  1 +
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c
index aa6bd402fee..aaf2e85b20f 100644
--- a/src/render/SDL_render.c
+++ b/src/render/SDL_render.c
@@ -933,6 +933,26 @@ static SDL_RenderLineMethod SDL_GetRenderLineMethod()
     }
 }
 
+static void SDL_CalculateSimulatedVSyncInterval(SDL_Renderer *renderer, SDL_Window *window)
+{
+    /* FIXME: SDL refresh rate API should return numerator/denominator */
+    int refresh_rate = 0;
+    int display_index = SDL_GetWindowDisplayIndex(window);
+    SDL_DisplayMode mode;
+
+    if (display_index < 0) {
+        display_index = 0;
+    }
+    if (SDL_GetDesktopDisplayMode(display_index, &mode) == 0) {
+        refresh_rate = mode.refresh_rate;
+    }
+    if (!refresh_rate) {
+        /* Pick a good default refresh rate */
+        refresh_rate = 60;
+    }
+    renderer->simulate_vsync_interval = (1000 / refresh_rate);
+}
+
 SDL_Renderer *
 SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags)
 {
@@ -1022,6 +1042,7 @@ SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags)
             renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
         }
     }
+    SDL_CalculateSimulatedVSyncInterval(renderer, window);
 
     VerifyDrawQueueFunctions(renderer);
 
@@ -4273,7 +4294,7 @@ static void
 SDL_RenderSimulateVSync(SDL_Renderer * renderer)
 {
     Uint32 now, elapsed;
-    const Uint32 interval = (1000 / 60); /* FIXME: What FPS? */
+    const Uint32 interval = renderer->simulate_vsync_interval;
 
     if (!interval) {
         /* We can't do sub-ms delay, so just return here */
diff --git a/src/render/SDL_sysrender.h b/src/render/SDL_sysrender.h
index 6deb5b2ee10..86d5eaa6436 100644
--- a/src/render/SDL_sysrender.h
+++ b/src/render/SDL_sysrender.h
@@ -211,6 +211,7 @@ struct SDL_Renderer
     /* Whether we should simulate vsync */
     SDL_bool wanted_vsync;
     SDL_bool simulate_vsync;
+    Uint32 simulate_vsync_interval;
     Uint32 last_present;
 
     /* The logical resolution for rendering */