mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-13 14:00:09 +00:00
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.
This commit is contained in:
parent
eb8f60f141
commit
fb50015519
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 ();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user