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.
This commit is contained in:
Benjamin Otte
2021-07-02 03:21:14 +02:00
parent 37ba057128
commit 74288eceaf
6 changed files with 108 additions and 30 deletions

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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;

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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;