Commit f1e4685806f3badcc77a1db856cafd7e63643ce6

Francisco Javier Trujillo Mata 2022-08-26T17:58:59

Adding specific SDL_Hint for the dynamic VSYNC

diff --git a/docs/README-ps2.md b/docs/README-ps2.md
index 3a0724f..b27b57d 100644
--- a/docs/README-ps2.md
+++ b/docs/README-ps2.md
@@ -16,6 +16,10 @@ cmake --build build
 cmake --install build
 ```
 
+## Hints
+The PS2 port has a special Hint for having a dynamic VSYNC. The Hint is `SDL_HINT_PS2_DYNAMIC_VSYNC`.
+If you enabled the dynamic vsync having as well `SDL_RENDERER_PRESENTVSYNC` enabled, then if the app is not able to run at 60 FPS, automatically the `vsync` will be disabled having a better performance, instead of droping FPS to 30.
+
 ## Notes
 If you trying to debug a SDL app through [ps2client](https://github.com/ps2dev/ps2client) you need to avoid the IOP reset, otherwise you will lose the conection with your computer.
 So to avoid the reset of the IOP CPU, you need to call to the macro `SDL_PS2_SKIP_IOP_RESET();`.
diff --git a/include/SDL_hints.h b/include/SDL_hints.h
index 48f4f36..4e1f993 100644
--- a/include/SDL_hints.h
+++ b/include/SDL_hints.h
@@ -1406,6 +1406,17 @@ extern "C" {
 #define SDL_HINT_RENDER_VSYNC               "SDL_RENDER_VSYNC"
 
 /**
+ *  \brief  A variable controlling if VSYNC is automatically disable if doesn't reach the enough FPS
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - It will be using VSYNC as defined in the main flag. Default
+ *    "1"       - If VSYNC was previously enabled, then it will disable VSYNC if doesn't reach enough speed
+ *
+ *  By default SDL does not enable the automatic VSYNC
+ */
+#define SDL_HINT_PS2_DYNAMIC_VSYNC    "SDL_PS2_DYNAMIC_VSYNC"
+
+/**
  * \brief A variable to control whether the return key on the soft keyboard
  *        should hide the soft keyboard on Android and iOS.
  *
diff --git a/src/render/ps2/SDL_render_ps2.c b/src/render/ps2/SDL_render_ps2.c
index b4c7c8f..ec89663 100644
--- a/src/render/ps2/SDL_render_ps2.c
+++ b/src/render/ps2/SDL_render_ps2.c
@@ -63,7 +63,7 @@ typedef struct
     GSGLOBAL *gsGlobal;
     uint64_t drawColor;
     int32_t vsync_callback_id;
-    SDL_bool vsync; /* wether we do vsync */
+    uint8_t vsync; /* 0 (Disabled), 1 (Enabled), 2 (Dynamic) */
 } PS2_RenderData;
 
 
@@ -660,14 +660,18 @@ PS2_RenderPresent(SDL_Renderer * renderer)
     PS2_RenderData *data = (PS2_RenderData *) renderer->driverdata;
 
     if (data->gsGlobal->DoubleBuffering == GS_SETTING_OFF) {
-		if (data->vsync)
+		if (data->vsync == 2) // Dynamic
             gsKit_sync(data->gsGlobal);
+        else if (data->vsync == 1)
+            gsKit_vsync_wait();
 		gsKit_queue_exec(data->gsGlobal);
     } else {
 		gsKit_queue_exec(data->gsGlobal);
 		gsKit_finish();
-		if (data->vsync)
+		if (data->vsync == 2) // Dynamic
             gsKit_sync(data->gsGlobal);
+        else if (data->vsync == 1)
+            gsKit_vsync_wait();
 		gsKit_flip(data->gsGlobal);
 	}
 	gsKit_TexManager_nextFrame(data->gsGlobal);
@@ -718,7 +722,8 @@ static int
 PS2_SetVSync(SDL_Renderer * renderer, const int vsync)
 {
     PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata;
-    data->vsync = vsync;
+    SDL_bool dynamicVsync = SDL_GetHintBoolean(SDL_HINT_PS2_DYNAMIC_VSYNC, SDL_FALSE);
+    data->vsync = vsync ? (dynamicVsync ? 2 : 1) : 0;
     return 0;
 }
 
@@ -729,6 +734,7 @@ PS2_CreateRenderer(SDL_Window * window, Uint32 flags)
     PS2_RenderData *data;
     GSGLOBAL *gsGlobal;
     ee_sema_t sema;
+    SDL_bool dynamicVsync;
 
     renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
     if (!renderer) {
@@ -781,11 +787,8 @@ PS2_CreateRenderer(SDL_Window * window, Uint32 flags)
     gsKit_clear(gsGlobal, GS_BLACK);
 
     data->gsGlobal = gsGlobal;
-    if (flags & SDL_RENDERER_PRESENTVSYNC) {
-        data->vsync = SDL_TRUE;
-    } else {
-        data->vsync = SDL_FALSE;
-    }	
+    dynamicVsync = SDL_GetHintBoolean(SDL_HINT_PS2_DYNAMIC_VSYNC, SDL_FALSE);
+    data->vsync = flags & SDL_RENDERER_PRESENTVSYNC ? (dynamicVsync ? 2 : 1) : 0;
 
     renderer->WindowEvent = PS2_WindowEvent;
     renderer->CreateTexture = PS2_CreateTexture;