diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c index acbf66fdee..d48491b611 100644 --- a/gdk/gdkdisplay.c +++ b/gdk/gdkdisplay.c @@ -2244,28 +2244,6 @@ gdk_error_trap_pop (void) return gdk_error_trap_pop_internal (TRUE); } -/*< private > - * gdk_display_destroy_gl_context: - * @display: a #GdkDisplay - * @context: a #GdkGLContext - * - * Destroys the platform-specific parts of the @context. - * - * The @context instance is still valid, though inert, after - * this functionr returns. - */ -void -gdk_display_destroy_gl_context (GdkDisplay *display, - GdkGLContext *context) -{ - GdkGLContext *current = gdk_display_get_current_gl_context (display); - - if (current == context) - g_object_set_data (G_OBJECT (display), "-gdk-gl-current-context", NULL); - - GDK_DISPLAY_GET_CLASS (display)->destroy_gl_context (display, context); -} - /*< private > * gdk_display_make_gl_context_current: * @display: a #GdkDisplay @@ -2274,35 +2252,9 @@ gdk_display_destroy_gl_context (GdkDisplay *display, * Makes the given @context the current GL context, or unsets * the current GL context if @context is %NULL. */ -void +gboolean gdk_display_make_gl_context_current (GdkDisplay *display, GdkGLContext *context) { - GdkGLContext *current = gdk_display_get_current_gl_context (display); - - if (current == context) - return; - - if (context == NULL) - g_object_set_data (G_OBJECT (display), "-gdk-gl-current-context", NULL); - else - g_object_set_data_full (G_OBJECT (display), "-gdk-gl-current-context", - g_object_ref (context), - (GDestroyNotify) g_object_unref); - - GDK_DISPLAY_GET_CLASS (display)->make_gl_context_current (display, context); -} - -/*< private > - * gdk_display_get_current_gl_context: - * @display: a #GdkDisplay - * - * Retrieves the current #GdkGLContext associated with @display. - * - * Returns: (transfer none): the current #GdkGLContext or %NULL - */ -GdkGLContext * -gdk_display_get_current_gl_context (GdkDisplay *display) -{ - return g_object_get_data (G_OBJECT (display), "-gdk-gl-current-context"); + return GDK_DISPLAY_GET_CLASS (display)->make_gl_context_current (display, context); } diff --git a/gdk/gdkdisplayprivate.h b/gdk/gdkdisplayprivate.h index 6bd87d149c..4c6f4a015b 100644 --- a/gdk/gdkdisplayprivate.h +++ b/gdk/gdkdisplayprivate.h @@ -228,10 +228,8 @@ struct _GdkDisplayClass gchar * (*utf8_to_string_target) (GdkDisplay *display, const gchar *text); - void (*make_gl_context_current) (GdkDisplay *display, - GdkGLContext *context); - void (*destroy_gl_context) (GdkDisplay *display, - GdkGLContext *context); + gboolean (*make_gl_context_current) (GdkDisplay *display, + GdkGLContext *context); /* Signals */ void (*opened) (GdkDisplay *display); @@ -311,11 +309,8 @@ void _gdk_display_create_window_impl (GdkDisplay *display gint attributes_mask); GdkWindow * _gdk_display_create_window (GdkDisplay *display); -void gdk_display_destroy_gl_context (GdkDisplay *display, +gboolean gdk_display_make_gl_context_current (GdkDisplay *display, GdkGLContext *context); -void gdk_display_make_gl_context_current (GdkDisplay *display, - GdkGLContext *context); -GdkGLContext * gdk_display_get_current_gl_context (GdkDisplay *display); G_END_DECLS diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c index f1e87406e3..748d9322dd 100644 --- a/gdk/gdkglcontext.c +++ b/gdk/gdkglcontext.c @@ -103,13 +103,18 @@ G_DEFINE_QUARK (gdk-gl-error-quark, gdk_gl_error) G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdkGLContext, gdk_gl_context, G_TYPE_OBJECT) +static GPrivate thread_current_context = G_PRIVATE_INIT (g_object_unref); + static void gdk_gl_context_dispose (GObject *gobject) { GdkGLContext *context = GDK_GL_CONTEXT (gobject); GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context); + GdkGLContext *current; - gdk_display_destroy_gl_context (gdk_window_get_display (priv->window), context); + current = g_private_get (&thread_current_context); + if (current == context) + g_private_replace (&thread_current_context, NULL); g_clear_object (&priv->window); g_clear_object (&priv->visual); @@ -310,13 +315,20 @@ void gdk_gl_context_make_current (GdkGLContext *context) { GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context); + GdkGLContext *current; g_return_if_fail (GDK_IS_GL_CONTEXT (context)); - gdk_display_make_gl_context_current (gdk_window_get_display (priv->window), context); + current = g_private_get (&thread_current_context); + if (current == context) + return; - if (!priv->realized) - gdk_gl_context_realize (context); + if (gdk_display_make_gl_context_current (gdk_window_get_display (priv->window), context)) + { + g_private_replace (&thread_current_context, g_object_ref (context)); + if (!priv->realized) + gdk_gl_context_realize (context); + } } /** @@ -352,9 +364,16 @@ gdk_gl_context_get_window (GdkGLContext *context) void gdk_gl_context_clear_current (void) { - GdkDisplay *display = gdk_display_get_default (); + GdkGLContext *current; - gdk_display_make_gl_context_current (display, NULL); + current = g_private_get (&thread_current_context); + if (current != NULL) + { + GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (current); + + if (gdk_display_make_gl_context_current (gdk_window_get_display (priv->window), NULL)) + g_private_replace (&thread_current_context, NULL); + } } /** @@ -369,7 +388,9 @@ gdk_gl_context_clear_current (void) GdkGLContext * gdk_gl_context_get_current (void) { - GdkDisplay *display = gdk_display_get_default (); + GdkGLContext *current; - return gdk_display_get_current_gl_context (display); + current = g_private_get (&thread_current_context); + + return current; } diff --git a/gdk/gdkglcontextprivate.h b/gdk/gdkglcontextprivate.h index c7b6937ba6..fcb82a8345 100644 --- a/gdk/gdkglcontextprivate.h +++ b/gdk/gdkglcontextprivate.h @@ -40,7 +40,7 @@ struct _GdkGLContextClass { GObjectClass parent_class; - void (* update) (GdkGLContext *context); + void (* update) (GdkGLContext *context); void (* end_frame) (GdkGLContext *context, cairo_region_t *painted, cairo_region_t *damage); diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 0f367ec0d8..56e7278ee2 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -534,7 +534,6 @@ gdk_wayland_display_class_init (GdkWaylandDisplayClass * class) display_class->text_property_to_utf8_list = _gdk_wayland_display_text_property_to_utf8_list; display_class->utf8_to_string_target = _gdk_wayland_display_utf8_to_string_target; - display_class->destroy_gl_context = gdk_wayland_display_destroy_gl_context; display_class->make_gl_context_current = gdk_wayland_display_make_gl_context_current; } diff --git a/gdk/wayland/gdkglcontext-wayland.c b/gdk/wayland/gdkglcontext-wayland.c index 5fc320d932..5a75c54748 100644 --- a/gdk/wayland/gdkglcontext-wayland.c +++ b/gdk/wayland/gdkglcontext-wayland.c @@ -35,6 +35,8 @@ G_DEFINE_TYPE (GdkWaylandGLContext, gdk_wayland_gl_context, GDK_TYPE_GL_CONTEXT) +static void gdk_x11_gl_context_dispose (GObject *gobject); + static void gdk_wayland_gl_context_update (GdkGLContext *context) { @@ -159,9 +161,11 @@ static void gdk_wayland_gl_context_class_init (GdkWaylandGLContextClass *klass) { GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); context_class->update = gdk_wayland_gl_context_update; context_class->end_frame = gdk_wayland_gl_context_end_frame; + gobject_class->dispose = gdk_x11_gl_context_dispose; } static void @@ -369,16 +373,18 @@ gdk_wayland_window_create_gl_context (GdkWindow *window, return GDK_GL_CONTEXT (context); } -void -gdk_wayland_display_destroy_gl_context (GdkDisplay *display, - GdkGLContext *context) +static void +gdk_x11_gl_context_dispose (GObject *gobject) { - GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display); - GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (context); + GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (gobject); - /* TODO: Unset as current if current? */ if (context_wayland->egl_context != NULL) { + GdkGLContext *context = GDK_GL_CONTEXT (gobject); + GdkWindow *window = gdk_gl_context_get_window (context); + GdkDisplay *display = gdk_window_get_display (window); + GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display); + if (eglGetCurrentContext () == context_wayland->egl_context) eglMakeCurrent(display_wayland->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); @@ -389,9 +395,11 @@ gdk_wayland_display_destroy_gl_context (GdkDisplay *display, context_wayland->egl_context); context_wayland->egl_context = NULL; } + + G_OBJECT_CLASS (gdk_wayland_gl_context_parent_class)->dispose (gobject); } -void +gboolean gdk_wayland_display_make_gl_context_current (GdkDisplay *display, GdkGLContext *context) { @@ -404,7 +412,7 @@ gdk_wayland_display_make_gl_context_current (GdkDisplay *display, { eglMakeCurrent(display_wayland->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - return; + return TRUE; } context_wayland = GDK_WAYLAND_GL_CONTEXT (context); @@ -422,6 +430,11 @@ gdk_wayland_display_make_gl_context_current (GdkDisplay *display, } if (!eglMakeCurrent (display_wayland->egl_display, egl_surface, - egl_surface, context_wayland->egl_context)) - g_critical ("eglMakeCurrent failed"); + egl_surface, context_wayland->egl_context)) + { + g_warning ("eglMakeCurrent failed"); + return FALSE; + } + + return TRUE; } diff --git a/gdk/wayland/gdkglcontext-wayland.h b/gdk/wayland/gdkglcontext-wayland.h index 6a7d8797d8..a140f5ca15 100644 --- a/gdk/wayland/gdkglcontext-wayland.h +++ b/gdk/wayland/gdkglcontext-wayland.h @@ -55,9 +55,7 @@ GdkGLContext * gdk_wayland_window_create_gl_context (GdkWindow GError **error); void gdk_wayland_window_invalidate_for_new_frame (GdkWindow *window, cairo_region_t *update_area); -void gdk_wayland_display_destroy_gl_context (GdkDisplay *display, - GdkGLContext *context); -void gdk_wayland_display_make_gl_context_current (GdkDisplay *display, +gboolean gdk_wayland_display_make_gl_context_current (GdkDisplay *display, GdkGLContext *context); G_END_DECLS diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c index 358ae84df0..220a85b009 100644 --- a/gdk/x11/gdkdisplay-x11.c +++ b/gdk/x11/gdkdisplay-x11.c @@ -2894,7 +2894,6 @@ gdk_x11_display_class_init (GdkX11DisplayClass * class) display_class->text_property_to_utf8_list = _gdk_x11_display_text_property_to_utf8_list; display_class->utf8_to_string_target = _gdk_x11_display_utf8_to_string_target; - display_class->destroy_gl_context = gdk_x11_display_destroy_gl_context; display_class->make_gl_context_current = gdk_x11_display_make_gl_context_current; _gdk_x11_windowing_init (); diff --git a/gdk/x11/gdkglcontext-x11.c b/gdk/x11/gdkglcontext-x11.c index 8d1e6cfe61..b7a90eb177 100644 --- a/gdk/x11/gdkglcontext-x11.c +++ b/gdk/x11/gdkglcontext-x11.c @@ -495,14 +495,40 @@ gdk_x11_gl_context_texture_from_surface (GdkGLContext *context, return TRUE; } +static void +gdk_x11_gl_context_dispose (GObject *gobject) +{ + GdkX11GLContext *context_x11 = GDK_X11_GL_CONTEXT (gobject); + + if (context_x11->glx_context != NULL) + { + GdkGLContext *context = GDK_GL_CONTEXT (gobject); + GdkWindow *window = gdk_gl_context_get_window (context); + GdkDisplay *display = gdk_window_get_display (window); + Display *dpy = gdk_x11_display_get_xdisplay (display); + + if (glXGetCurrentContext () == context_x11->glx_context) + glXMakeContextCurrent (dpy, None, None, NULL); + + GDK_NOTE (OPENGL, g_print ("Destroying GLX context\n")); + glXDestroyContext (dpy, context_x11->glx_context); + context_x11->glx_context = NULL; + } + + G_OBJECT_CLASS (gdk_x11_gl_context_parent_class)->dispose (gobject); +} + static void gdk_x11_gl_context_class_init (GdkX11GLContextClass *klass) { GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); context_class->update = gdk_x11_gl_context_update; context_class->end_frame = gdk_x11_gl_context_end_frame; context_class->texture_from_surface = gdk_x11_gl_context_texture_from_surface; + + gobject_class->dispose = gdk_x11_gl_context_dispose; } static void @@ -1110,25 +1136,7 @@ gdk_x11_window_create_gl_context (GdkWindow *window, return GDK_GL_CONTEXT (context); } -void -gdk_x11_display_destroy_gl_context (GdkDisplay *display, - GdkGLContext *context) -{ - GdkX11GLContext *context_x11 = GDK_X11_GL_CONTEXT (context); - Display *dpy = gdk_x11_display_get_xdisplay (display); - - if (context_x11->glx_context != NULL) - { - if (glXGetCurrentContext () == context_x11->glx_context) - glXMakeContextCurrent (dpy, None, None, NULL); - - GDK_NOTE (OPENGL, g_print ("Destroying GLX context\n")); - glXDestroyContext (dpy, context_x11->glx_context); - context_x11->glx_context = NULL; - } -} - -void +gboolean gdk_x11_display_make_gl_context_current (GdkDisplay *display, GdkGLContext *context) { @@ -1141,7 +1149,7 @@ gdk_x11_display_make_gl_context_current (GdkDisplay *display, if (context == NULL) { glXMakeContextCurrent (dpy, None, None, NULL); - return; + return TRUE; } context_x11 = GDK_X11_GL_CONTEXT (context); @@ -1161,8 +1169,13 @@ gdk_x11_display_make_gl_context_current (GdkDisplay *display, g_print ("Making GLX context current to drawable %lu\n", (unsigned long) context_x11->drawable)); - glXMakeContextCurrent (dpy, context_x11->drawable, context_x11->drawable, - context_x11->glx_context); + if (!glXMakeContextCurrent (dpy, context_x11->drawable, context_x11->drawable, + context_x11->glx_context)) + { + GDK_NOTE (OPENGL, + g_print ("Making GLX context current failed\n")); + return FALSE; + } if (context_x11->is_attached && GDK_X11_DISPLAY (display)->has_glx_swap_interval) { @@ -1171,6 +1184,8 @@ gdk_x11_display_make_gl_context_current (GdkDisplay *display, else glXSwapIntervalSGI (0); } + + return TRUE; } /** diff --git a/gdk/x11/gdkglcontext-x11.h b/gdk/x11/gdkglcontext-x11.h index 683ca41d00..865a7654a7 100644 --- a/gdk/x11/gdkglcontext-x11.h +++ b/gdk/x11/gdkglcontext-x11.h @@ -64,9 +64,7 @@ GdkGLContext * gdk_x11_window_create_gl_context (GdkWindow GError **error); void gdk_x11_window_invalidate_for_new_frame (GdkWindow *window, cairo_region_t *update_area); -void gdk_x11_display_destroy_gl_context (GdkDisplay *display, - GdkGLContext *context); -void gdk_x11_display_make_gl_context_current (GdkDisplay *display, +gboolean gdk_x11_display_make_gl_context_current (GdkDisplay *display, GdkGLContext *context); G_END_DECLS