From d99b517b5390b880f15d3aba2da83293d0493452 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Tue, 23 Sep 2014 12:01:04 +1000 Subject: [PATCH] glcontext: add gst_gl_context_can_share Which determines whether two GstGLContext's can share sharable OpenGL resources. --- docs/libs/gst-plugins-bad-libs-sections.txt | 1 + gst-libs/gst/gl/gstglcontext.c | 56 +++++++++++++++++++-- gst-libs/gst/gl/gstglcontext.h | 1 + 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/docs/libs/gst-plugins-bad-libs-sections.txt b/docs/libs/gst-plugins-bad-libs-sections.txt index 0d8398694f..f9051fa574 100644 --- a/docs/libs/gst-plugins-bad-libs-sections.txt +++ b/docs/libs/gst-plugins-bad-libs-sections.txt @@ -805,6 +805,7 @@ gst_gl_context_get_gl_api gst_gl_context_get_gl_context gst_gl_context_get_gl_platform gst_gl_context_get_thread +gst_gl_context_can_share gst_gl_context_check_feature gst_gl_context_check_gl_version gst_gl_context_get_gl_version diff --git a/gst-libs/gst/gl/gstglcontext.c b/gst-libs/gst/gl/gstglcontext.c index 9a72f56f8b..02a9273933 100644 --- a/gst-libs/gst/gl/gstglcontext.c +++ b/gst-libs/gst/gl/gstglcontext.c @@ -149,7 +149,7 @@ struct _GstGLContextPrivate gboolean created; gboolean alive; - GstGLContext *other_context; + GWeakRef other_context_ref; GError **error; gint gl_major; @@ -217,6 +217,8 @@ gst_gl_context_init (GstGLContext * context) g_cond_init (&context->priv->create_cond); g_cond_init (&context->priv->destroy_cond); context->priv->created = FALSE; + + g_weak_ref_init (&context->priv->other_context_ref, NULL); } static void @@ -382,6 +384,7 @@ gst_gl_context_finalize (GObject * object) g_cond_clear (&context->priv->create_cond); g_free (context->priv->gl_exts); + g_weak_ref_clear (&context->priv->other_context_ref); G_OBJECT_CLASS (gst_gl_context_parent_class)->finalize (object); } @@ -577,6 +580,47 @@ gst_gl_context_get_window (GstGLContext * context) return gst_object_ref (context->window); } +static gboolean +_share_group_descendant (GstGLContext * context, GstGLContext * other_context) +{ + GstGLContext *next = gst_object_ref (context); + while (next != NULL) { + GstGLContext *prev; + + if (next == other_context) { + gst_object_unref (next); + return TRUE; + } + + prev = next; + next = g_weak_ref_get (&next->priv->other_context_ref); + gst_object_unref (prev); + } + + return FALSE; +} + +/** + * gst_gl_context_can_share: + * @context: a #GstGLContext + * @other_context: another #GstGLContext + * + * Returns: whether @context and @other_context are able to share OpenGL + * resources. + * + * Since: 1.6 + */ +gboolean +gst_gl_context_can_share (GstGLContext * context, GstGLContext * other_context) +{ + g_return_val_if_fail (GST_GL_IS_CONTEXT (context), FALSE); + g_return_val_if_fail (GST_GL_IS_CONTEXT (other_context), FALSE); + + return context == other_context + || _share_group_descendant (context, other_context) + || _share_group_descendant (other_context, context); +} + /** * gst_gl_context_create: * @context: a #GstGLContext: @@ -607,7 +651,7 @@ gst_gl_context_create (GstGLContext * context, g_mutex_lock (&context->priv->render_lock); if (!context->priv->created) { - context->priv->other_context = other_context; + g_weak_ref_set (&context->priv->other_context_ref, other_context); context->priv->error = error; context->priv->gl_thread = g_thread_new ("gstglcontext", @@ -889,7 +933,7 @@ gst_gl_context_create_thread (GstGLContext * context) g_mutex_lock (&context->priv->render_lock); error = context->priv->error; - other_context = context->priv->other_context; + other_context = g_weak_ref_get (&context->priv->other_context_ref); context_class = GST_GL_CONTEXT_GET_CLASS (context); window_class = GST_GL_WINDOW_GET_CLASS (context->window); @@ -1024,6 +1068,9 @@ gst_gl_context_create_thread (GstGLContext * context) #endif } + if (other_context) + gst_object_unref (other_context); + g_cond_signal (&context->priv->create_cond); // g_mutex_unlock (&context->priv->render_lock); @@ -1059,6 +1106,9 @@ gst_gl_context_create_thread (GstGLContext * context) failure: { + if (other_context) + gst_object_unref (other_context); + g_cond_signal (&context->priv->create_cond); g_mutex_unlock (&context->priv->render_lock); return NULL; diff --git a/gst-libs/gst/gl/gstglcontext.h b/gst-libs/gst/gl/gstglcontext.h index 7d06981647..d2acc0deee 100644 --- a/gst-libs/gst/gl/gstglcontext.h +++ b/gst-libs/gst/gl/gstglcontext.h @@ -127,6 +127,7 @@ gpointer gst_gl_context_get_proc_address (GstGLContext *context, const gcha GstGLPlatform gst_gl_context_get_gl_platform (GstGLContext *context); GstGLAPI gst_gl_context_get_gl_api (GstGLContext *context); guintptr gst_gl_context_get_gl_context (GstGLContext *context); +gboolean gst_gl_context_can_share (GstGLContext * context, GstGLContext *other_context); gboolean gst_gl_context_create (GstGLContext *context, GstGLContext *other_context, GError ** error); void gst_gl_context_destroy (GstGLContext *context);