From 808a3f573f2afcb7701b79cf5f3e3fae3f55ae9f Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 8 Oct 2025 21:42:01 -0400 Subject: [PATCH] egl: Better attempt at retrying surface creation w/o EGL_EXT_present_opaque. Fixes #13094. --- src/video/SDL_egl.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/video/SDL_egl.c b/src/video/SDL_egl.c index fa5d428d36..23cc00ba20 100644 --- a/src/video/SDL_egl.c +++ b/src/video/SDL_egl.c @@ -1250,12 +1250,9 @@ EGLSurface SDL_EGL_CreateSurface(SDL_VideoDevice *_this, SDL_Window *window, Nat // max 16 key+value pairs, plus terminator. EGLint attribs[33]; int attr = 0; - bool use_opaque_ext; - + EGLSurface surface; - use_opaque_ext = true; -try: if (!SDL_EGL_ChooseConfig(_this)) { return EGL_NO_SURFACE; } @@ -1284,8 +1281,11 @@ try: } } + int opaque_ext_idx = -1; + #ifdef EGL_EXT_present_opaque - if (SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_EXT_present_opaque") && use_opaque_ext) { + if (SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_EXT_present_opaque")) { + opaque_ext_idx = attr; bool allow_transparent = false; if (window && (window->flags & SDL_WINDOW_TRANSPARENT)) { allow_transparent = true; @@ -1321,15 +1321,18 @@ try: attribs[attr++] = EGL_NONE; - surface = _this->egl_data->eglCreateWindowSurface( - _this->egl_data->egl_display, - _this->egl_data->egl_config, - nw, &attribs[0]); + surface = _this->egl_data->eglCreateWindowSurface(_this->egl_data->egl_display, _this->egl_data->egl_config, nw, &attribs[0]); if (surface == EGL_NO_SURFACE) { - if (_this->egl_data->eglGetError() == EGL_BAD_ATTRIBUTE && use_opaque_ext) { - use_opaque_ext = false; - goto try; + // we had a report of Nvidia drivers that report EGL_BAD_ATTRIBUTE if you try to + // use EGL_PRESENT_OPAQUE_EXT, even when EGL_EXT_present_opaque is reported as available. + // If we used it, try a second time without this attribute. + if ((_this->egl_data->eglGetError() == EGL_BAD_ATTRIBUTE) && (opaque_ext_idx >= 0)) { + SDL_memmove(&attribs[opaque_ext_idx], &attribs[opaque_ext_idx + 2], sizeof (attribs[0]) * ((attr - opaque_ext_idx) - 2)); + surface = _this->egl_data->eglCreateWindowSurface(_this->egl_data->egl_display, _this->egl_data->egl_config, nw, &attribs[0]); } + } + + if (surface == EGL_NO_SURFACE) { SDL_EGL_SetError("unable to create an EGL window surface", "eglCreateWindowSurface"); }