[gtk+] GdkGLContext: Change the way we track the current context
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] GdkGLContext: Change the way we track the current context
- Date: Thu, 30 Oct 2014 11:43:20 +0000 (UTC)
commit fb50015519bee516f7a83c64034d11cd9a606246
Author: Alexander Larsson <alexl redhat com>
Date: Thu Oct 30 11:46:09 2014 +0100
GdkGLContext: Change the way we track the current context
To properly support multithreaded use we use a global GPrivate
to track the current context. Since we also don't need to track
the current context on the display we move gdk_display_destroy_gl_context
to GdkGLContext::discard.
gdk/gdkdisplay.c | 52 +------------------------------
gdk/gdkdisplayprivate.h | 11 ++-----
gdk/gdkglcontext.c | 37 +++++++++++++++++-----
gdk/gdkglcontextprivate.h | 2 +-
gdk/wayland/gdkdisplay-wayland.c | 1 -
gdk/wayland/gdkglcontext-wayland.c | 33 ++++++++++++++------
gdk/wayland/gdkglcontext-wayland.h | 4 +--
gdk/x11/gdkdisplay-x11.c | 1 -
gdk/x11/gdkglcontext-x11.c | 59 ++++++++++++++++++++++-------------
gdk/x11/gdkglcontext-x11.h | 4 +--
10 files changed, 97 insertions(+), 107 deletions(-)
---
diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c
index acbf66f..d48491b 100644
--- a/gdk/gdkdisplay.c
+++ b/gdk/gdkdisplay.c
@@ -2245,28 +2245,6 @@ gdk_error_trap_pop (void)
}
/*< 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
* @context: (optional): a #GdkGLContext, or %NULL
@@ -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 6bd87d1..4c6f4a0 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 f1e8740..748d932 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;
+
+ current = g_private_get (&thread_current_context);
- return gdk_display_get_current_gl_context (display);
+ return current;
}
diff --git a/gdk/gdkglcontextprivate.h b/gdk/gdkglcontextprivate.h
index c7b6937..fcb82a8 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 0f367ec..56e7278 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 5fc320d..5a75c54 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 6a7d879..a140f5c 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 358ae84..220a85b 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 8d1e6cf..b7a90eb 100644
--- a/gdk/x11/gdkglcontext-x11.c
+++ b/gdk/x11/gdkglcontext-x11.c
@@ -496,13 +496,39 @@ gdk_x11_gl_context_texture_from_surface (GdkGLContext *context,
}
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 683ca41..865a765 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
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]