Skip to content

Commit e0321ca

Browse files
authored
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.
1 parent dcbb2f1 commit e0321ca

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

src/video/x11/SDL_x11opengl.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,32 @@ static int X11_GL_GetAttributes(SDL_VideoDevice *_this, Display *display, int sc
608608
return i;
609609
}
610610

611+
//get the first transparent Visual
612+
static XVisualInfo* X11_GL_GetTransparentVisualInfo(Display *display, int screen)
613+
{
614+
XVisualInfo* visualinfo = NULL;
615+
XVisualInfo vi_in;
616+
int out_count = 0;
617+
618+
vi_in.screen = screen;
619+
visualinfo = X11_XGetVisualInfo(display, VisualScreenMask, &vi_in, &out_count);
620+
if (visualinfo != NULL) {
621+
int i = 0;
622+
for (i = 0; i < out_count; i++) {
623+
XVisualInfo* v = &visualinfo[i];
624+
Uint32 format = X11_GetPixelFormatFromVisualInfo(display, v);
625+
if (SDL_ISPIXELFORMAT_ALPHA(format)) {
626+
vi_in.screen = screen;
627+
vi_in.visualid = v->visualid;
628+
X11_XFree(visualinfo);
629+
visualinfo = X11_XGetVisualInfo(display, VisualScreenMask | VisualIDMask, &vi_in, &out_count);
630+
break;
631+
}
632+
}
633+
}
634+
return visualinfo;
635+
}
636+
611637
XVisualInfo *X11_GL_GetVisual(SDL_VideoDevice *_this, Display *display, int screen, bool transparent)
612638
{
613639
// 64 seems nice.
@@ -666,6 +692,18 @@ XVisualInfo *X11_GL_GetVisual(SDL_VideoDevice *_this, Display *display, int scre
666692
}
667693
}
668694

695+
if (transparent && vinfo) {
696+
Uint32 format = X11_GetPixelFormatFromVisualInfo(display, vinfo);
697+
if (!SDL_ISPIXELFORMAT_ALPHA(format)) {
698+
// not transparent!
699+
XVisualInfo* visualinfo = X11_GL_GetTransparentVisualInfo(display, screen);
700+
if (visualinfo != NULL) {
701+
X11_XFree(vinfo);
702+
vinfo = visualinfo;
703+
}
704+
}
705+
}
706+
669707
if (!vinfo) {
670708
SDL_SetError("Couldn't find matching GLX visual");
671709
}
@@ -814,6 +852,26 @@ SDL_GLContext X11_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window)
814852
&fbcount);
815853
}
816854

855+
if (transparent && (framebuffer_config != NULL)) {
856+
int i;
857+
for (i = 0; i < fbcount; i++) {
858+
XVisualInfo* vinfo_temp = _this->gl_data->glXGetVisualFromFBConfig(display, framebuffer_config[i]);
859+
if ( vinfo_temp != NULL) {
860+
Uint32 format = X11_GetPixelFormatFromVisualInfo(display, vinfo_temp);
861+
if (SDL_ISPIXELFORMAT_ALPHA(format)) {
862+
// found!
863+
context = (SDL_GLContext)_this->gl_data->glXCreateContextAttribsARB(display,
864+
framebuffer_config[i],
865+
share_context, True, attribs);
866+
X11_XFree(framebuffer_config);
867+
framebuffer_config = NULL;
868+
X11_XFree(vinfo_temp);
869+
break;
870+
}
871+
X11_XFree(vinfo_temp);
872+
}
873+
}
874+
}
817875
if (framebuffer_config) {
818876
context = (SDL_GLContext)_this->gl_data->glXCreateContextAttribsARB(display,
819877
framebuffer_config[0],

0 commit comments

Comments
 (0)