x11: Redo choice between EGL and GLX
authorBenjamin Otte <otte@redhat.com>
Fri, 2 Jul 2021 01:37:32 +0000 (03:37 +0200)
committerBenjamin Otte <otte@redhat.com>
Thu, 22 Jul 2021 14:23:56 +0000 (16:23 +0200)
We try EGL first, but are very picky about what we accept.
If that fails, we try to go with GLX instead.
And if that also fails, we try EGL again, but this time accept anything.

The idea here is that EGL is the preferred method going forward, but GLX is
the tried and tested method that we know works. So if we detect issues with
EGL, we want to avoid using it in favor of GLX.

Also add a GDK_DEBUG=gl-egl option to force EGL at all costs and not try
GLX.

gdk/gdk.c
gdk/gdkdebug.h
gdk/x11/gdkglcontext-egl.c
gdk/x11/gdkglcontext-x11.c
gdk/x11/gdkglcontext-x11.h

index b3a569d34da226cf91a4ccc2d4fc21c867f9fc8b..c6b5b7b8ce1f23e20dfcc8a1634242a4a1d0cef5 100644 (file)
--- a/gdk/gdk.c
+++ b/gdk/gdk.c
@@ -127,6 +127,7 @@ static const GdkDebugKey gdk_debug_keys[] = {
   { "gl-legacy",       GDK_DEBUG_GL_LEGACY, "Use a legacy OpenGL context" },
   { "gl-gles",         GDK_DEBUG_GL_GLES, "Use a GLES OpenGL context" },
   { "gl-debug",        GDK_DEBUG_GL_DEBUG, "Insert debugging information in OpenGL" },
+  { "gl-egl",          GDK_DEBUG_GL_EGL, "Use EGL on X11" },
   { "gl-glx",          GDK_DEBUG_GL_GLX, "Use GLX on X11" },
   { "vulkan-disable",  GDK_DEBUG_VULKAN_DISABLE, "Disable Vulkan support" },
   { "vulkan-validate", GDK_DEBUG_VULKAN_VALIDATE, "Load the Vulkan validation layer" },
index e03b904ce4018325ef63b5e3013a2cc8d2ec8bfe..111cc2f28a4b064371363ecfb8dc651324f59d5e 100644 (file)
@@ -41,10 +41,11 @@ typedef enum {
   GDK_DEBUG_GL_LEGACY       = 1 << 15,
   GDK_DEBUG_GL_GLES         = 1 << 16,
   GDK_DEBUG_GL_DEBUG        = 1 << 17,
-  GDK_DEBUG_GL_GLX          = 1 << 18,
-  GDK_DEBUG_VULKAN_DISABLE  = 1 << 19,
-  GDK_DEBUG_VULKAN_VALIDATE = 1 << 20,
-  GDK_DEBUG_DEFAULT_SETTINGS= 1 << 21
+  GDK_DEBUG_GL_EGL          = 1 << 18,
+  GDK_DEBUG_GL_GLX          = 1 << 19,
+  GDK_DEBUG_VULKAN_DISABLE  = 1 << 20,
+  GDK_DEBUG_VULKAN_VALIDATE = 1 << 21,
+  GDK_DEBUG_DEFAULT_SETTINGS= 1 << 22
 } GdkDebugFlags;
 
 extern guint _gdk_debug_flags;
index 3df0919738a6aee4ba1ffdd48fdd195ce57e2de6..56a17168b1c1c132c938f8656e91425547d2dc56 100644 (file)
@@ -134,6 +134,7 @@ visual_is_rgba (XVisualInfo *visinfo)
 
 static gboolean
 gdk_x11_display_create_egl_config (GdkX11Display  *display,
+                                   gboolean        force,
                                    Visual        **out_visual,
                                    int            *out_depth,
                                    GError        **error)
@@ -263,6 +264,13 @@ gdk_x11_display_create_egl_config (GdkX11Display  *display,
                            _("No EGL configuration with required features found"));
       return FALSE;
     }
+  else if (!force && best_features != PERFECT)
+    {
+      g_set_error_literal (error, GDK_GL_ERROR,
+                           GDK_GL_ERROR_NOT_AVAILABLE,
+                           _("No perfect EGL configuration found"));
+      return FALSE;
+    }
 
   return TRUE;
 }
@@ -589,6 +597,7 @@ gdk_x11_gl_context_egl_init (GdkX11GLContextEGL *self)
 
 gboolean
 gdk_x11_display_init_egl (GdkX11Display  *self,
+                          gboolean        force,
                           Visual        **out_visual,
                           int            *out_depth,
                           GError        **error)
@@ -625,7 +634,7 @@ gdk_x11_display_init_egl (GdkX11Display  *self,
       return FALSE;
     }
 
-  if (!gdk_x11_display_create_egl_config (self, out_visual, out_depth, error))
+  if (!gdk_x11_display_create_egl_config (self, force, out_visual, out_depth, error))
     {
       eglTerminate (self->egl_display);
       self->egl_display = NULL;
index 389faf629268ab1e7ae703caa1eef97c5ac0242d..c74a994c7015b46ff5c645f30350dbe559d83557 100644 (file)
@@ -109,8 +109,6 @@ gdk_x11_display_init_gl (GdkX11Display  *self,
                          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))
     {
@@ -120,27 +118,30 @@ gdk_x11_display_init_gl (GdkX11Display  *self,
       return FALSE;
     }
 
-  if (!GDK_DISPLAY_DEBUG_CHECK (display, GL_GLX))
-    {
-      /* We favour EGL */
-      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, &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;
+  if (GDK_DISPLAY_DEBUG_CHECK (display, GL_EGL))
+    return gdk_x11_display_init_egl (self, TRUE, out_visual, out_depth, error);
+  if (GDK_DISPLAY_DEBUG_CHECK (display, GL_GLX))
+    return gdk_x11_display_init_glx (self, out_visual, out_depth, error);
+
+  /* No env vars set, do the regular GL initialization.
+   * 
+   * We try EGL first, but are very picky about what we accept.
+   * If that fails, we try to go with GLX instead.
+   * And if that also fails, we try EGL again, but this time accept anything.
+   *
+   * The idea here is that EGL is the preferred method going forward, but GLX is
+   * the tried and tested method that we know works. So if we detect issues with
+   * EGL, we want to avoid using it in favor of GLX.
+   */
+
+  if (gdk_x11_display_init_egl (self, FALSE, out_visual, out_depth, error))
+    return TRUE;
+  g_clear_error (error);
+
+  if (gdk_x11_display_init_glx (self, out_visual, out_depth, error))
+    return TRUE;
+  g_clear_error (error);
+
+  return gdk_x11_display_init_egl (self, TRUE, out_visual, out_depth, error);
 }
 
index 1aa7fbe5451fd95706d6dcdd449dfc67cf8bb2a5..5cc2ebf5d625ec004a400600222ce99b85a026ff 100644 (file)
@@ -101,6 +101,7 @@ gboolean                gdk_x11_gl_context_glx_make_current     (GdkDisplay    *
 typedef struct _GdkX11GLContextEGL      GdkX11GLContextEGL;
 
 gboolean                gdk_x11_display_init_egl                (GdkX11Display *display_x11,
+                                                                 gboolean       force,
                                                                  Visual       **out_visual,
                                                                  int           *out_depth,
                                                                  GError       **error);