From ff543723c4a09235eac7d30ebda21bde4beda8ca Mon Sep 17 00:00:00 2001 From: Andrei Alexeyev Date: Mon, 16 Mar 2026 02:19:59 +0100 Subject: [PATCH] Fix SDL_HINT_OPENGL_ES_DRIVER interaction with SDL_HINT_OPENGL_LIBRARY for x11 and windows If SDL_HINT_OPENGL_ES_DRIVER is enabled and a GLES context is requested, don't try to load the WGL/GLX library. Doing so may fail, because SDL_HINT_OPENGL_LIBRARY may have been set to a custom libGLESv2 (e.g. ANGLE). This effectively restores the SDL2 behavior. Other video drivers shouldn't be affected, because they always use EGL for GLES. Incidentally, this patch also fixes a missing GL_GetEGLSurface callback in the X11 fallback path. --- src/video/windows/SDL_windowsopengl.c | 38 +++++++++++++++++-------- src/video/x11/SDL_x11opengl.c | 41 +++++++++++++++++---------- 2 files changed, 52 insertions(+), 27 deletions(-) diff --git a/src/video/windows/SDL_windowsopengl.c b/src/video/windows/SDL_windowsopengl.c index 5e3b79c196..b87f90e6b4 100644 --- a/src/video/windows/SDL_windowsopengl.c +++ b/src/video/windows/SDL_windowsopengl.c @@ -106,10 +106,35 @@ typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC hDC, #define SetPixelFormat _this->gl_data->wglSetPixelFormat #endif +static bool WIN_GL_LoadLibrary_EGLFallback(SDL_VideoDevice *_this, const char *path) +{ +#ifdef SDL_VIDEO_OPENGL_EGL + WIN_GL_UnloadLibrary(_this); + _this->GL_LoadLibrary = WIN_GLES_LoadLibrary; + _this->GL_GetProcAddress = WIN_GLES_GetProcAddress; + _this->GL_UnloadLibrary = WIN_GLES_UnloadLibrary; + _this->GL_CreateContext = WIN_GLES_CreateContext; + _this->GL_MakeCurrent = WIN_GLES_MakeCurrent; + _this->GL_SetSwapInterval = WIN_GLES_SetSwapInterval; + _this->GL_GetSwapInterval = WIN_GLES_GetSwapInterval; + _this->GL_SwapWindow = WIN_GLES_SwapWindow; + _this->GL_DestroyContext = WIN_GLES_DestroyContext; + _this->GL_GetEGLSurface = WIN_GLES_GetEGLSurface; + return WIN_GLES_LoadLibrary(_this, path); +#else + return SDL_SetError("SDL not configured with EGL support"); +#endif +} + bool WIN_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path) { void *handle; + if ((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) && + SDL_GetHintBoolean(SDL_HINT_OPENGL_ES_DRIVER, false)) { + return WIN_GL_LoadLibrary_EGLFallback(_this, path); + } + if (path == NULL) { path = SDL_GetHint(SDL_HINT_OPENGL_LIBRARY); } @@ -740,19 +765,8 @@ SDL_GLContext WIN_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window) if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES && WIN_GL_UseEGL(_this)) { #ifdef SDL_VIDEO_OPENGL_EGL // Switch to EGL based functions - WIN_GL_UnloadLibrary(_this); - _this->GL_LoadLibrary = WIN_GLES_LoadLibrary; - _this->GL_GetProcAddress = WIN_GLES_GetProcAddress; - _this->GL_UnloadLibrary = WIN_GLES_UnloadLibrary; - _this->GL_CreateContext = WIN_GLES_CreateContext; - _this->GL_MakeCurrent = WIN_GLES_MakeCurrent; - _this->GL_SetSwapInterval = WIN_GLES_SetSwapInterval; - _this->GL_GetSwapInterval = WIN_GLES_GetSwapInterval; - _this->GL_SwapWindow = WIN_GLES_SwapWindow; - _this->GL_DestroyContext = WIN_GLES_DestroyContext; - _this->GL_GetEGLSurface = WIN_GLES_GetEGLSurface; - if (!WIN_GLES_LoadLibrary(_this, NULL)) { + if (!WIN_GL_LoadLibrary_EGLFallback(_this, NULL)) { return NULL; } diff --git a/src/video/x11/SDL_x11opengl.c b/src/video/x11/SDL_x11opengl.c index 07e895d46c..9724913c73 100644 --- a/src/video/x11/SDL_x11opengl.c +++ b/src/video/x11/SDL_x11opengl.c @@ -163,6 +163,26 @@ typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display *dpy, static void X11_GL_InitExtensions(SDL_VideoDevice *_this); +static bool X11_GL_LoadLibrary_EGLFallback(SDL_VideoDevice *_this, const char *path) +{ +#ifdef SDL_VIDEO_OPENGL_EGL + X11_GL_UnloadLibrary(_this); + _this->GL_LoadLibrary = X11_GLES_LoadLibrary; + _this->GL_GetProcAddress = X11_GLES_GetProcAddress; + _this->GL_UnloadLibrary = X11_GLES_UnloadLibrary; + _this->GL_CreateContext = X11_GLES_CreateContext; + _this->GL_MakeCurrent = X11_GLES_MakeCurrent; + _this->GL_SetSwapInterval = X11_GLES_SetSwapInterval; + _this->GL_GetSwapInterval = X11_GLES_GetSwapInterval; + _this->GL_SwapWindow = X11_GLES_SwapWindow; + _this->GL_DestroyContext = X11_GLES_DestroyContext; + _this->GL_GetEGLSurface = X11_GLES_GetEGLSurface; + return X11_GLES_LoadLibrary(_this, path); +#else + return SDL_SetError("SDL not configured with EGL support"); +#endif +} + bool X11_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path) { Display *display; @@ -172,6 +192,11 @@ bool X11_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path) return SDL_SetError("OpenGL context already created"); } + if ((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) && + SDL_GetHintBoolean(SDL_HINT_OPENGL_ES_DRIVER, false)) { + return X11_GL_LoadLibrary_EGLFallback(_this, path); + } + // Load the OpenGL library if (path == NULL) { path = SDL_GetHint(SDL_HINT_OPENGL_LIBRARY); @@ -254,21 +279,7 @@ bool X11_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path) if (((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) || SDL_GetHintBoolean(SDL_HINT_VIDEO_FORCE_EGL, false)) && X11_GL_UseEGL(_this)) { -#ifdef SDL_VIDEO_OPENGL_EGL - X11_GL_UnloadLibrary(_this); - _this->GL_LoadLibrary = X11_GLES_LoadLibrary; - _this->GL_GetProcAddress = X11_GLES_GetProcAddress; - _this->GL_UnloadLibrary = X11_GLES_UnloadLibrary; - _this->GL_CreateContext = X11_GLES_CreateContext; - _this->GL_MakeCurrent = X11_GLES_MakeCurrent; - _this->GL_SetSwapInterval = X11_GLES_SetSwapInterval; - _this->GL_GetSwapInterval = X11_GLES_GetSwapInterval; - _this->GL_SwapWindow = X11_GLES_SwapWindow; - _this->GL_DestroyContext = X11_GLES_DestroyContext; - return X11_GLES_LoadLibrary(_this, NULL); -#else - return SDL_SetError("SDL not configured with EGL support"); -#endif + return X11_GL_LoadLibrary_EGLFallback(_this, NULL); } return true;