From: Benjamin Otte Date: Fri, 2 Jul 2021 01:21:14 +0000 (+0200) Subject: x11: Properly record the error when initializing GL X-Git-Tag: archive/raspbian/4.4.1+ds1-2+rpi1^2~18^2~3^2~9^2~26 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=74288eceaf3cdbd7dc4735c1b383f9da7dc5c68c;p=gtk4.git x11: Properly record the error when initializing GL That way, we can give a useful error message when things break down for users. These error messages could still be improved in places (like looking at the actual EGL error codes), but that seemed overkill. --- diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c index df893c0bbc..4500513057 100644 --- a/gdk/x11/gdkdisplay-x11.c +++ b/gdk/x11/gdkdisplay-x11.c @@ -1440,7 +1440,7 @@ gdk_x11_display_open (const char *display_name) * as we care about GLX details such as alpha/depth/stencil depth, * stereo and double buffering */ - if (!gdk_x11_display_init_gl (display_x11, &display_x11->window_visual, &display_x11->window_depth)) + if (!gdk_x11_display_init_gl (display_x11, &display_x11->window_visual, &display_x11->window_depth, &display_x11->gl_error)) gdk_x11_display_query_default_visual (display_x11, &display_x11->window_visual, &display_x11->window_depth); display_x11->window_colormap = XCreateColormap (xdisplay, @@ -1948,6 +1948,8 @@ gdk_x11_display_finalize (GObject *object) XCloseDisplay (display_x11->xdisplay); + g_clear_error (&display_x11->gl_error); + /* error traps */ while (display_x11->error_traps != NULL) { diff --git a/gdk/x11/gdkdisplay-x11.h b/gdk/x11/gdkdisplay-x11.h index 067f34cca8..0bdc4488f0 100644 --- a/gdk/x11/gdkdisplay-x11.h +++ b/gdk/x11/gdkdisplay-x11.h @@ -129,6 +129,9 @@ struct _GdkX11Display guint have_damage; #endif + /* If GL is not supported, store the error here */ + GError *gl_error; + /* GLX information */ /* GLXFBConfig */ gpointer glx_config; int glx_version; diff --git a/gdk/x11/gdkglcontext-egl.c b/gdk/x11/gdkglcontext-egl.c index fa795cec2e..3df0919738 100644 --- a/gdk/x11/gdkglcontext-egl.c +++ b/gdk/x11/gdkglcontext-egl.c @@ -132,10 +132,11 @@ visual_is_rgba (XVisualInfo *visinfo) #define MAX_EGL_ATTRS 30 -static void +static gboolean gdk_x11_display_create_egl_config (GdkX11Display *display, Visual **out_visual, - int *out_depth) + int *out_depth, + GError **error) { GdkX11Display *self = GDK_X11_DISPLAY (display); EGLint attrs[MAX_EGL_ATTRS]; @@ -170,14 +171,19 @@ gdk_x11_display_create_egl_config (GdkX11Display *display, attrs[i++] = EGL_NONE; g_assert (i < MAX_EGL_ATTRS); - if (!eglChooseConfig (self->egl_display, attrs, NULL, -1, &alloced)) - return; + if (!eglChooseConfig (self->egl_display, attrs, NULL, -1, &alloced) || alloced == 0) + { + g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE, + _("No EGL configuration available")); + return FALSE; + } configs = g_new (EGLConfig, alloced); if (!eglChooseConfig (self->egl_display, attrs, configs, alloced, &count)) { - g_free (configs); - return; + g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE, + _("Failed to get EGL configurations")); + return FALSE; } g_warn_if_fail (alloced == count); @@ -249,6 +255,16 @@ gdk_x11_display_create_egl_config (GdkX11Display *display, } g_free (configs); + + if (best_features == NO_VISUAL_FOUND) + { + g_set_error_literal (error, GDK_GL_ERROR, + GDK_GL_ERROR_NOT_AVAILABLE, + _("No EGL configuration with required features found")); + return FALSE; + } + + return TRUE; } #undef MAX_EGL_ATTRS @@ -574,7 +590,8 @@ gdk_x11_gl_context_egl_init (GdkX11GLContextEGL *self) gboolean gdk_x11_display_init_egl (GdkX11Display *self, Visual **out_visual, - int *out_depth) + int *out_depth, + GError **error) { GdkDisplay *display = GDK_DISPLAY (self); Display *dpy; @@ -583,20 +600,32 @@ gdk_x11_display_init_egl (GdkX11Display *self, dpy = gdk_x11_display_get_xdisplay (display); if (!epoxy_has_egl ()) - return FALSE; + { + g_set_error_literal (error, GDK_GL_ERROR, + GDK_GL_ERROR_NOT_AVAILABLE, + _("EGL is not supported")); + return FALSE; + } gdk_x11_display_create_egl_display (self); if (self->egl_display == NULL) - return FALSE; + { + g_set_error_literal (error, GDK_GL_ERROR, + GDK_GL_ERROR_NOT_AVAILABLE, + _("Failed to create EGL display")); + return FALSE; + } if (!eglInitialize (self->egl_display, &major, &minor)) { self->egl_display = NULL; + g_set_error_literal (error, GDK_GL_ERROR, + GDK_GL_ERROR_NOT_AVAILABLE, + _("Could not initialize EGL display")); return FALSE; } - gdk_x11_display_create_egl_config (self, out_visual, out_depth); - if (self->egl_config == NULL) + if (!gdk_x11_display_create_egl_config (self, out_visual, out_depth, error)) { eglTerminate (self->egl_display); self->egl_display = NULL; diff --git a/gdk/x11/gdkglcontext-glx.c b/gdk/x11/gdkglcontext-glx.c index 9b112053f7..a1ecb68313 100644 --- a/gdk/x11/gdkglcontext-glx.c +++ b/gdk/x11/gdkglcontext-glx.c @@ -715,10 +715,11 @@ visual_is_rgba (XVisualInfo *visinfo) #define MAX_GLX_ATTRS 30 -static void +static gboolean gdk_x11_display_create_glx_config (GdkX11Display *self, Visual **out_visual, - int *out_depth) + int *out_depth, + GError **error) { GdkDisplay *display = GDK_DISPLAY (self); Display *dpy = gdk_x11_display_get_xdisplay (display); @@ -758,7 +759,12 @@ gdk_x11_display_create_glx_config (GdkX11Display *self, configs = glXChooseFBConfig (dpy, DefaultScreen (dpy), attrs, &count); if (configs == NULL || count == 0) - return; + { + g_set_error_literal (error, GDK_GL_ERROR, + GDK_GL_ERROR_NOT_AVAILABLE, + _("No GLX configurations available")); + return FALSE; + } best_features = NO_VISUAL_FOUND; @@ -824,6 +830,16 @@ gdk_x11_display_create_glx_config (GdkX11Display *self, } XFree (configs); + + if (best_features == NO_VISUAL_FOUND) + { + g_set_error_literal (error, GDK_GL_ERROR, + GDK_GL_ERROR_NOT_AVAILABLE, + _("No GLX configuration with required features found")); + return FALSE; + } + + return TRUE; } #undef MAX_GLX_ATTRS @@ -942,6 +958,7 @@ gdk_x11_display_get_glx_version (GdkDisplay *display, * @display_x11: an X11 display that has not been inited yet. * @out_visual: set to the Visual to be used with the returned config * @out_depth: set to the depth to be used with the returned config + * @error: Return location for error * * Initializes the cached GLX state for the given @screen. * @@ -952,7 +969,8 @@ gdk_x11_display_get_glx_version (GdkDisplay *display, gboolean gdk_x11_display_init_glx (GdkX11Display *display_x11, Visual **out_visual, - int *out_depth) + int *out_depth, + GError **error) { GdkDisplay *display = GDK_DISPLAY (display_x11); Display *dpy; @@ -961,7 +979,12 @@ gdk_x11_display_init_glx (GdkX11Display *display_x11, dpy = gdk_x11_display_get_xdisplay (display); if (!epoxy_has_glx (dpy)) - return FALSE; + { + g_set_error_literal (error, GDK_GL_ERROR, + GDK_GL_ERROR_NOT_AVAILABLE, + _("GLX is not supported")); + return FALSE; + } screen_num = display_x11->screen->screen_num; @@ -1023,8 +1046,7 @@ gdk_x11_display_init_glx (GdkX11Display *display_x11, XFree (data); } - gdk_x11_display_create_glx_config (display_x11, out_visual, out_depth); - if (display_x11->glx_config == NULL) + if (!gdk_x11_display_create_glx_config (display_x11, out_visual, out_depth, error)) return FALSE; GDK_DISPLAY_NOTE (display, OPENGL, diff --git a/gdk/x11/gdkglcontext-x11.c b/gdk/x11/gdkglcontext-x11.c index e4e24c88ab..389faf6292 100644 --- a/gdk/x11/gdkglcontext-x11.c +++ b/gdk/x11/gdkglcontext-x11.c @@ -72,9 +72,9 @@ gdk_x11_surface_create_gl_context (GdkSurface *surface, context = gdk_x11_gl_context_glx_new (surface, attached, share, error); else { - g_set_error_literal (error, GDK_GL_ERROR, - GDK_GL_ERROR_NOT_AVAILABLE, - _("No GL implementation is available")); + g_assert (display_x11->gl_error); + if (error) + *error = g_error_copy (display_x11->gl_error); return NULL; } @@ -105,22 +105,41 @@ gdk_x11_display_make_gl_context_current (GdkDisplay *display, gboolean gdk_x11_display_init_gl (GdkX11Display *self, Visual **out_visual, - int *out_depth) + int *out_depth, + GError **error) { GdkDisplay *display G_GNUC_UNUSED = GDK_DISPLAY (self); + GError *egl_error = NULL; + GError *glx_error = NULL; if (GDK_DISPLAY_DEBUG_CHECK (display, GL_DISABLE)) - return FALSE; + { + g_set_error_literal (error, GDK_GL_ERROR, + GDK_GL_ERROR_NOT_AVAILABLE, + _("GL support disabled via GDK_DEBUG=gl-disable")); + return FALSE; + } if (!GDK_DISPLAY_DEBUG_CHECK (display, GL_GLX)) { /* We favour EGL */ - if (gdk_x11_display_init_egl (self, out_visual, out_depth)) + if (gdk_x11_display_init_egl (self, out_visual, out_depth, &egl_error)) return TRUE; } - if (gdk_x11_display_init_glx (self, out_visual, out_depth)) - return TRUE; + if (gdk_x11_display_init_glx (self, out_visual, out_depth, &glx_error)) + { + g_clear_error (&egl_error); + return TRUE; + } + + if (egl_error) + { + *error = egl_error; + g_clear_error (&glx_error); + } + else + *error = glx_error; return FALSE; } diff --git a/gdk/x11/gdkglcontext-x11.h b/gdk/x11/gdkglcontext-x11.h index acbc58a260..1aa7fbe545 100644 --- a/gdk/x11/gdkglcontext-x11.h +++ b/gdk/x11/gdkglcontext-x11.h @@ -61,7 +61,8 @@ struct _GdkX11GLContextClass gboolean gdk_x11_display_init_gl (GdkX11Display *self, Visual **out_visual, - int *out_depth); + int *out_depth, + GError **error); GdkGLContext * gdk_x11_surface_create_gl_context (GdkSurface *window, gboolean attached, @@ -79,7 +80,8 @@ typedef struct _GdkX11GLContextGLX GdkX11GLContextGLX; gboolean gdk_x11_display_init_glx (GdkX11Display *display_x11, Visual **out_visual, - int *out_depth); + int *out_depth, + GError **error); void gdk_x11_surface_destroy_glx_drawable (GdkX11Surface *self); GType gdk_x11_gl_context_glx_get_type (void) G_GNUC_CONST; @@ -100,7 +102,8 @@ typedef struct _GdkX11GLContextEGL GdkX11GLContextEGL; gboolean gdk_x11_display_init_egl (GdkX11Display *display_x11, Visual **out_visual, - int *out_depth); + int *out_depth, + GError **error); void gdk_x11_surface_destroy_egl_surface (GdkX11Surface *self); GType gdk_x11_gl_context_egl_get_type (void) G_GNUC_CONST;