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:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user