* 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,
XCloseDisplay (display_x11->xdisplay);
+ g_clear_error (&display_x11->gl_error);
+
/* error traps */
while (display_x11->error_traps != NULL)
{
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;
#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];
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);
}
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
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;
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;
#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);
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;
}
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
* @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.
*
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;
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;
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,
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;
}
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;
}
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,
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;
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;