SDL3: SDL_render_gl(render name: opengl) dose not support transparent on Linux/X11 (Bug #11273) (#11274)

SDL3: SDL_render_gl(render name: opengl) dose not support transparent on Linux/X11:

Create SDL window with SDL_WINDOW_TRANSPARENT flag;
Create "opengl" renderer for the window;
The window can't shown with errors:
X Error of failed request: BadMatch (invalid parameter attributes)
Major opcode of failed request: 130 (MIT-SHM)
Minor opcode of failed request: 3 (X_ShmPutImage)
Bug reason:
SDL_x11window.c:490 : bool X11_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props)
SDL_x11window.c:566 : vinfo = X11_GL_GetVisual(_this, display, screen, transparent);[XVisualInfo *vinfo]
the X11_GL_GetVisual function returns a vinfo dose not support transparent.

Fix:
SDL_x11opengl.c:637 : XVisualInfo *X11_GL_GetVisual(SDL_VideoDevice *_this, Display *display, int screen, bool transparent)
X11_GL_GetVisual should returns a vinfo support transparent when transparent is true.
This commit is contained in:
rhett-lee
2024-10-20 11:21:50 +08:00
committed by GitHub
parent dcbb2f11a8
commit e0321ca5b6

View File

@@ -608,6 +608,32 @@ static int X11_GL_GetAttributes(SDL_VideoDevice *_this, Display *display, int sc
return i;
}
//get the first transparent Visual
static XVisualInfo* X11_GL_GetTransparentVisualInfo(Display *display, int screen)
{
XVisualInfo* visualinfo = NULL;
XVisualInfo vi_in;
int out_count = 0;
vi_in.screen = screen;
visualinfo = X11_XGetVisualInfo(display, VisualScreenMask, &vi_in, &out_count);
if (visualinfo != NULL) {
int i = 0;
for (i = 0; i < out_count; i++) {
XVisualInfo* v = &visualinfo[i];
Uint32 format = X11_GetPixelFormatFromVisualInfo(display, v);
if (SDL_ISPIXELFORMAT_ALPHA(format)) {
vi_in.screen = screen;
vi_in.visualid = v->visualid;
X11_XFree(visualinfo);
visualinfo = X11_XGetVisualInfo(display, VisualScreenMask | VisualIDMask, &vi_in, &out_count);
break;
}
}
}
return visualinfo;
}
XVisualInfo *X11_GL_GetVisual(SDL_VideoDevice *_this, Display *display, int screen, bool transparent)
{
// 64 seems nice.
@@ -666,6 +692,18 @@ XVisualInfo *X11_GL_GetVisual(SDL_VideoDevice *_this, Display *display, int scre
}
}
if (transparent && vinfo) {
Uint32 format = X11_GetPixelFormatFromVisualInfo(display, vinfo);
if (!SDL_ISPIXELFORMAT_ALPHA(format)) {
// not transparent!
XVisualInfo* visualinfo = X11_GL_GetTransparentVisualInfo(display, screen);
if (visualinfo != NULL) {
X11_XFree(vinfo);
vinfo = visualinfo;
}
}
}
if (!vinfo) {
SDL_SetError("Couldn't find matching GLX visual");
}
@@ -814,6 +852,26 @@ SDL_GLContext X11_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window)
&fbcount);
}
if (transparent && (framebuffer_config != NULL)) {
int i;
for (i = 0; i < fbcount; i++) {
XVisualInfo* vinfo_temp = _this->gl_data->glXGetVisualFromFBConfig(display, framebuffer_config[i]);
if ( vinfo_temp != NULL) {
Uint32 format = X11_GetPixelFormatFromVisualInfo(display, vinfo_temp);
if (SDL_ISPIXELFORMAT_ALPHA(format)) {
// found!
context = (SDL_GLContext)_this->gl_data->glXCreateContextAttribsARB(display,
framebuffer_config[i],
share_context, True, attribs);
X11_XFree(framebuffer_config);
framebuffer_config = NULL;
X11_XFree(vinfo_temp);
break;
}
X11_XFree(vinfo_temp);
}
}
}
if (framebuffer_config) {
context = (SDL_GLContext)_this->gl_data->glXCreateContextAttribsARB(display,
framebuffer_config[0],