SDL: Fixed bug #6816 - SDL_RenderSetVSync doesn't disable vsync for software renderer

From bf76fc6b05d9adad82e09e76119171a55f954ed3 Mon Sep 17 00:00:00 2001
From: Sylvain <[EMAIL REDACTED]>
Date: Sun, 1 Jan 2023 23:05:25 +0100
Subject: [PATCH] Fixed bug #6816 - SDL_RenderSetVSync doesn't disable vsync
 for software renderer

---
 src/render/SDL_render.c |  9 +++++++++
 src/video/SDL_video.c   | 14 ++++++++++++++
 src/video/SDL_video_c.h |  2 ++
 3 files changed, 25 insertions(+)

diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c
index 8b9c9809b238..8d1c1cd80472 100644
--- a/src/render/SDL_render.c
+++ b/src/render/SDL_render.c
@@ -25,6 +25,7 @@
 #include "SDL_sysrender.h"
 #include "software/SDL_render_sw_c.h"
 #include "../video/SDL_pixels_c.h"
+#include "../video/SDL_video_c.h"
 
 #if defined(__ANDROID__)
 #include "../core/android/SDL_android.h"
@@ -4485,6 +4486,14 @@ int SDL_SetRenderVSync(SDL_Renderer *renderer, int vsync)
 
     renderer->wanted_vsync = vsync ? SDL_TRUE : SDL_FALSE;
 
+    /* for the software renderer, forward eventually the call to the WindowTexture renderer */
+    if (renderer->info.flags & SDL_RENDERER_SOFTWARE) {
+        if (SDL_SetWindowTextureVSync(renderer->window, vsync) == 0) {
+            renderer->simulate_vsync = SDL_FALSE;
+            return 0;
+        }
+    }
+
     if (!renderer->SetVSync ||
         renderer->SetVSync(renderer, vsync) < 0) {
         renderer->simulate_vsync = vsync ? SDL_TRUE : SDL_FALSE;
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index 2ac6c7ccad61..99d6fdb69699 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -358,6 +358,20 @@ static void SDL_DestroyWindowTexture(SDL_VideoDevice *unused, SDL_Window *window
     SDL_free(data);
 }
 
+int SDL_SetWindowTextureVSync(SDL_Window *window, int vsync)
+{
+    SDL_WindowTextureData *data;
+
+    data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA);
+    if (data == NULL) {
+        return -1;
+    }
+    if (data->renderer == NULL ) {
+        return -1;
+    }
+    return SDL_SetRenderVSync(data->renderer, vsync);
+}
+
 static int SDLCALL cmpmodes(const void *A, const void *B)
 {
     const SDL_DisplayMode *a = (const SDL_DisplayMode *)A;
diff --git a/src/video/SDL_video_c.h b/src/video/SDL_video_c.h
index 887f38ef3e7f..4a949140a711 100644
--- a/src/video/SDL_video_c.h
+++ b/src/video/SDL_video_c.h
@@ -55,4 +55,6 @@ extern int SDL_VideoInit(const char *driver_name);
  */
 extern void SDL_VideoQuit(void);
 
+extern int SDL_SetWindowTextureVSync(SDL_Window *window, int vsync);
+
 #endif /* SDL_video_c_h_ */