[gtk/wip/otte/gleanup: 37/60] x11: Properly record the error when initializing GL




commit 256e09017f50ebae8730a6beb435328862e08966
Author: Benjamin Otte <otte redhat com>
Date:   Fri Jul 2 03:21:14 2021 +0200

    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.

 gdk/x11/gdkdisplay-x11.c   |  4 +++-
 gdk/x11/gdkdisplay-x11.h   |  3 +++
 gdk/x11/gdkglcontext-egl.c | 51 ++++++++++++++++++++++++++++++++++++----------
 gdk/x11/gdkglcontext-glx.c | 36 +++++++++++++++++++++++++-------
 gdk/x11/gdkglcontext-x11.c | 35 +++++++++++++++++++++++--------
 gdk/x11/gdkglcontext-x11.h |  9 +++++---
 6 files changed, 108 insertions(+), 30 deletions(-)
---
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index 6e9a46ec12..9441ed1417 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -1444,7 +1444,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,
@@ -1970,6 +1970,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 3e76962f3a..bf84950654 100644
--- a/gdk/x11/gdkdisplay-x11.h
+++ b/gdk/x11/gdkdisplay-x11.h
@@ -131,6 +131,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 9bb4705f3d..c6bd867361 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);
@@ -757,7 +758,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;
 
@@ -823,6 +829,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
@@ -941,6 +957,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.
  *
@@ -951,7 +968,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;
@@ -960,7 +978,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;
 
@@ -1022,8 +1045,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;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]