From 8a135339490675891f192657b5479c0dc7ad9f66 Mon Sep 17 00:00:00 2001
From: Sylvain Becker <[EMAIL REDACTED]>
Date: Sun, 1 Jan 2023 17:20:41 +0100
Subject: [PATCH] Handle error return value for SDL_GetSwapInterval
---
docs/README-migration.md | 1 +
include/SDL3/SDL_video.h | 10 ++++++----
src/dynapi/SDL_dynapi_procs.h | 2 +-
src/render/opengl/SDL_render_gl.c | 21 ++++++++++++++++++---
src/render/opengles2/SDL_render_gles2.c | 21 ++++++++++++++++++---
src/video/SDL_video.c | 19 ++++++++++++++-----
test/testgl2.c | 11 ++++++++++-
7 files changed, 68 insertions(+), 17 deletions(-)
diff --git a/docs/README-migration.md b/docs/README-migration.md
index 24e06265c6d4..52c3adfd23d2 100644
--- a/docs/README-migration.md
+++ b/docs/README-migration.md
@@ -838,6 +838,7 @@ SDL_SetWindowBrightness and SDL_SetWindowGammaRamp have been removed from the AP
Programs which have access to shaders can implement more robust versions of those functions using custom shader code rendered as a post-process effect.
+'SDL_GL_GetSwapInterval()' takes 'interval' as an output parameter and returns -1 on error.
Removed 'SDL_GL_CONTEXT_EGL' from OpenGL configuration attributes
You can instead use 'SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);'
diff --git a/include/SDL3/SDL_video.h b/include/SDL3/SDL_video.h
index d041cc56269b..aef9928563d9 100644
--- a/include/SDL3/SDL_video.h
+++ b/include/SDL3/SDL_video.h
@@ -1989,18 +1989,20 @@ extern DECLSPEC int SDLCALL SDL_GL_SetSwapInterval(int interval);
* Get the swap interval for the current OpenGL context.
*
* If the system can't determine the swap interval, or there isn't a valid
- * current context, this function will return 0 as a safe default.
+ * current context, this function will set *interval to 0 as a safe default.
*
- * \returns 0 if there is no vertical retrace synchronization, 1 if the buffer
+ * \param interval Output interval value. 0 if there is no vertical retrace synchronization, 1 if the buffer
* swap is synchronized with the vertical retrace, and -1 if late
- * swaps happen immediately instead of waiting for the next retrace;
+ * swaps happen immediately instead of waiting for the next retrace
+ *
+ * \returns 0 on success or -1 error.
* call SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_GL_SetSwapInterval
*/
-extern DECLSPEC int SDLCALL SDL_GL_GetSwapInterval(void);
+extern DECLSPEC int SDLCALL SDL_GL_GetSwapInterval(int *interval);
/**
* Update a window with OpenGL rendering.
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index c7682df04140..069178d22a0c 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -224,7 +224,7 @@ SDL_DYNAPI_PROC(SDL_GLContext,SDL_GL_GetCurrentContext,(void),(),return)
SDL_DYNAPI_PROC(SDL_Window*,SDL_GL_GetCurrentWindow,(void),(),return)
SDL_DYNAPI_PROC(void,SDL_GL_GetDrawableSize,(SDL_Window *a, int *b, int *c),(a,b,c),)
SDL_DYNAPI_PROC(void*,SDL_GL_GetProcAddress,(const char *a),(a),return)
-SDL_DYNAPI_PROC(int,SDL_GL_GetSwapInterval,(void),(),return)
+SDL_DYNAPI_PROC(int,SDL_GL_GetSwapInterval,(int *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_GL_LoadLibrary,(const char *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_GL_MakeCurrent,(SDL_Window *a, SDL_GLContext b),(a,b),return)
SDL_DYNAPI_PROC(void,SDL_GL_ResetAttributes,(void),(),)
diff --git a/src/render/opengl/SDL_render_gl.c b/src/render/opengl/SDL_render_gl.c
index 5fcad4a55553..cfa3c8d80352 100644
--- a/src/render/opengl/SDL_render_gl.c
+++ b/src/render/opengl/SDL_render_gl.c
@@ -1651,6 +1651,7 @@ static int GL_UnbindTexture(SDL_Renderer *renderer, SDL_Texture *texture)
static int GL_SetVSync(SDL_Renderer *renderer, const int vsync)
{
int retval;
+ int interval = 0;
if (vsync) {
retval = SDL_GL_SetSwapInterval(1);
} else {
@@ -1659,7 +1660,13 @@ static int GL_SetVSync(SDL_Renderer *renderer, const int vsync)
if (retval != 0) {
return retval;
}
- if (SDL_GL_GetSwapInterval() > 0) {
+
+ retval = SDL_GL_GetSwapInterval(&interval);
+ if (retval < 0) {
+ return retval;
+ }
+
+ if (interval > 0) {
renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
} else {
renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC;
@@ -1804,8 +1811,16 @@ static SDL_Renderer *GL_CreateRenderer(SDL_Window *window, Uint32 flags)
} else {
SDL_GL_SetSwapInterval(0);
}
- if (SDL_GL_GetSwapInterval() > 0) {
- renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
+
+ {
+ int interval = 0;
+ if (SDL_GL_GetSwapInterval(&interval) < 0) {
+ /* Error */
+ } else {
+ if (interval > 0) {
+ renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
+ }
+ }
}
/* Check for debug output support */
diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c
index 312d97487050..e41ca0a4d66a 100644
--- a/src/render/opengles2/SDL_render_gles2.c
+++ b/src/render/opengles2/SDL_render_gles2.c
@@ -1962,6 +1962,7 @@ static int GLES2_RenderPresent(SDL_Renderer *renderer)
static int GLES2_SetVSync(SDL_Renderer *renderer, const int vsync)
{
int retval;
+ int interval = 0;
if (vsync) {
retval = SDL_GL_SetSwapInterval(1);
} else {
@@ -1970,7 +1971,13 @@ static int GLES2_SetVSync(SDL_Renderer *renderer, const int vsync)
if (retval != 0) {
return retval;
}
- if (SDL_GL_GetSwapInterval() > 0) {
+
+ retval = SDL_GL_GetSwapInterval(&interval);
+ if (retval < 0) {
+ return retval;
+ }
+
+ if (interval > 0) {
renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
} else {
renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC;
@@ -2131,8 +2138,16 @@ static SDL_Renderer *GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
} else {
SDL_GL_SetSwapInterval(0);
}
- if (SDL_GL_GetSwapInterval() > 0) {
- renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
+
+ {
+ int interval = 0;
+ if (SDL_GL_GetSwapInterval(&interval) < 0) {
+ /* Error */
+ } else {
+ if (interval > 0) {
+ renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
+ }
+ }
}
/* Check for debug output support */
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index 55c8da223ea9..b77aff093715 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -4053,16 +4053,25 @@ int SDL_GL_SetSwapInterval(int interval)
}
}
-int SDL_GL_GetSwapInterval(void)
+int SDL_GL_GetSwapInterval(int *interval)
{
+ if (interval == NULL) {
+ return SDL_InvalidParamError("interval");
+ }
+
+ *interval = 0;
+
if (_this == NULL) {
- return 0;
+ return SDL_SetError("no video driver");;
} else if (SDL_GL_GetCurrentContext() == NULL) {
- return 0;
+ return SDL_SetError("no current context");;
} else if (_this->GL_GetSwapInterval) {
- return _this->GL_GetSwapInterval(_this);
- } else {
+ int val = _this->GL_GetSwapInterval(_this);
+
+ *interval = val;
return 0;
+ } else {
+ return SDL_SetError("not implemented");;
}
}
diff --git a/test/testgl2.c b/test/testgl2.c
index c8c7ddee7301..8b2bf758770d 100644
--- a/test/testgl2.c
+++ b/test/testgl2.c
@@ -209,6 +209,8 @@ int main(int argc, char *argv[])
int status;
int dw, dh;
int swap_interval = 0;
+ int interval = 0;
+ int ret_interval = 0;
/* Enable standard application logging */
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
@@ -293,7 +295,14 @@ int main(int argc, char *argv[])
SDL_GetCurrentDisplayMode(0, &mode);
SDL_Log("Screen BPP : %" SDL_PRIu32 "\n", SDL_BITSPERPIXEL(mode.format));
- SDL_Log("Swap Interval : %d\n", SDL_GL_GetSwapInterval());
+
+ ret_interval = SDL_GL_GetSwapInterval(&interval);
+ if (ret_interval < 0) {
+ SDL_Log("Swap Interval : %d error: %s\n", interval, SDL_GetError());
+ } else {
+ SDL_Log("Swap Interval : %d\n", interval);
+ }
+
SDL_GetWindowSize(state->windows[0], &dw, &dh);
SDL_Log("Window Size : %d,%d\n", dw, dh);
SDL_GL_GetDrawableSize(state->windows[0], &dw, &dh);