added re-creating renderer and textures when changing video vsync mode
authorHolger Schemel <info@artsoft.org>
Sat, 5 Sep 2020 19:25:24 +0000 (21:25 +0200)
committerHolger Schemel <info@artsoft.org>
Sat, 5 Sep 2020 19:30:33 +0000 (21:30 +0200)
When not using OpenGL renderer, changing video vsync mode requires
re-creating renderer and textures with changed vsync settings.

(This uses code for re-creating the screen that was a part of function
"ToggleFullscreenOrChangeWindowScalingIfNeeded()", but that was never
used after support for SDL 1.2 was removed with commit d3e24bbf.)

src/screens.c
src/tools.c
src/tools.h

index 9c5a86fd482db0b9defdac9d88de2982695fa427..4b8921c26929f9cca9c302b52d6676e8aa538962 100644 (file)
@@ -5329,7 +5329,7 @@ static void execSetupGraphics(void)
   SDLSetScreenRenderingMode(setup.screen_rendering_mode);
 
   // screen vsync mode may have changed at this point
-  SDLSetScreenVsyncMode(setup.vsync_mode);
+  ChangeVsyncModeIfNeeded();
 }
 
 static void execSetupChooseWindowSize(void)
index dba9f4737024d7ed95304c616b3dbbb99f1d073f..8ac74ac7178eb4d7f10247e9c6302ac594df460e 100644 (file)
@@ -9272,22 +9272,35 @@ void ToggleFullscreenOrChangeWindowScalingIfNeeded(void)
 
     return;
   }
+}
+
+void ChangeVsyncModeIfNeeded(void)
+{
+  int setup_vsync_mode = VSYNC_MODE_STR_TO_INT(setup.vsync_mode);
+  int video_vsync_mode = video.vsync_mode;
 
-  if (change_fullscreen ||
-      change_window_scaling_percent)
+  // if setup and video vsync mode are already matching, nothing do do
+  if (setup_vsync_mode == video_vsync_mode)
+    return;
+
+  // if renderer is using OpenGL, vsync mode can directly be changed
+  SDLSetScreenVsyncMode(setup.vsync_mode);
+
+  // if vsync mode unchanged, try re-creating renderer to set vsync mode
+  if (video.vsync_mode == video_vsync_mode)
   {
     Bitmap *tmp_backbuffer = CreateBitmap(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH);
 
-    // save backbuffer content which gets lost when toggling fullscreen mode
+    // save backbuffer content which gets lost when re-creating screen
     BlitBitmap(backbuffer, tmp_backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
 
-    if (change_window_scaling_percent)
-    {
-      // keep window mode, but change window scaling
-      video.fullscreen_enabled = TRUE;         // force new window scaling
-    }
+    // force re-creating screen and renderer to set new vsync mode
+    video.fullscreen_enabled = !setup.fullscreen;
+
+    // when creating new renderer, destroy textures linked to old renderer
+    FreeAllImageTextures();    // needs old renderer to free the textures
 
-    // toggle fullscreen
+    // re-create screen and renderer (including change of vsync mode)
     ChangeVideoModeIfNeeded(setup.fullscreen);
 
     // set setup value according to successfully changed fullscreen mode
@@ -9295,12 +9308,17 @@ void ToggleFullscreenOrChangeWindowScalingIfNeeded(void)
 
     // restore backbuffer content from temporary backbuffer backup bitmap
     BlitBitmap(tmp_backbuffer, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
-
     FreeBitmap(tmp_backbuffer);
 
     // update visible window/screen
     BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+
+    // when changing vsync mode, re-create textures for new renderer
+    InitImageTextures();
   }
+
+  // set setup value according to successfully changed vsync mode
+  setup.vsync_mode = VSYNC_MODE_INT_TO_STR(video.vsync_mode);
 }
 
 static void JoinRectangles(int *x, int *y, int *width, int *height,
index cf4b74b298e8e95afaecb3c66a32b35c95e60878..2743d41d460281f54ea71b86878983f10a2a1561 100644 (file)
@@ -284,6 +284,7 @@ void ResetFontStatus(void);
 void SetLevelSetInfo(char *, int);
 
 void ToggleFullscreenOrChangeWindowScalingIfNeeded(void);
+void ChangeVsyncModeIfNeeded(void);
 void ChangeViewportPropertiesIfNeeded(void);
 
 boolean CheckIfAllViewportsHaveChanged(void);