From 0810c5ac0da88850875f607da6c3239f2736e5cb Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 6 Feb 2026 13:39:36 -0500 Subject: [PATCH] video: Force GL_FRAMEBUFFER_SRGB state at OpenGL context creation time. The default varies between OpenGL and OpenGL ES, so try to force it to what the app actually requested with SDL_GL_FRAMEBUFFER_SRGB_CAPABLE. Fixes #14898. (cherry picked from commit 083c6b8872493fadbefddf26070e462b240a8b10) --- src/video/SDL_video.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 287e0b482c..0f123d1edc 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -61,6 +61,11 @@ #define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC #endif +// This is always the same number between the various EXT/ARB/GLES extensions. +#ifndef GL_FRAMEBUFFER_SRGB +#define GL_FRAMEBUFFER_SRGB 0x8DB9 +#endif + #ifdef SDL_PLATFORM_EMSCRIPTEN #include #endif @@ -4794,6 +4799,7 @@ void SDL_GL_UnloadLibrary(void) typedef GLenum (APIENTRY* PFNGLGETERRORPROC) (void); typedef void (APIENTRY* PFNGLGETINTEGERVPROC) (GLenum pname, GLint *params); typedef const GLubyte *(APIENTRY* PFNGLGETSTRINGPROC) (GLenum name); +typedef const void (APIENTRY* PFNGLENABLEPROC) (GLenum cap); #ifndef SDL_VIDEO_OPENGL typedef const GLubyte *(APIENTRY* PFNGLGETSTRINGIPROC) (GLenum name, GLuint index); #endif @@ -5404,6 +5410,8 @@ SDL_GLContext SDL_GL_CreateContext(SDL_Window *window) return NULL; } + const bool srgb_requested = (_this->gl_config.framebuffer_srgb_capable > 0); + ctx = _this->GL_CreateContext(_this, window); // Creating a context is assumed to make it current in the SDL driver. @@ -5413,6 +5421,25 @@ SDL_GLContext SDL_GL_CreateContext(SDL_Window *window) SDL_SetTLS(&_this->current_glwin_tls, window, NULL); SDL_SetTLS(&_this->current_glctx_tls, ctx, NULL); } + + // try to force the window framebuffer to the requested sRGB state. + PFNGLENABLEPROC glToggleFunc = (PFNGLENABLEPROC) SDL_GL_GetProcAddress(srgb_requested ? "glEnable" : "glDisable"); + PFNGLGETSTRINGPROC glGetStringFunc = (PFNGLGETSTRINGPROC)SDL_GL_GetProcAddress("glGetString"); + if (glToggleFunc && glGetStringFunc) { + bool supported = isAtLeastGL3((const char *)glGetStringFunc(GL_VERSION)); // no extensions needed in OpenGL 3+ or GLES 3+. + if (!supported) { + if (_this->gl_config.profile_mask & SDL_GL_CONTEXT_PROFILE_ES) { + supported = SDL_GL_ExtensionSupported("GL_EXT_sRGB_write_control"); + } else { + supported = SDL_GL_ExtensionSupported("GL_EXT_framebuffer_sRGB") || SDL_GL_ExtensionSupported("GL_ARB_framebuffer_sRGB"); + } + } + + if (supported) { + glToggleFunc(GL_FRAMEBUFFER_SRGB); + } + } + return ctx; }