mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-30 12:10:37 +00:00
glcontext: implement checking whether a context has been shared
Some operations are unnecessary when running with only a single GL context. e.g. glFlush when setting a fence object as the flush happens on wait. API: gst_gl_context_is_shared
This commit is contained in:
parent
a0a0e51249
commit
472970324c
3 changed files with 93 additions and 24 deletions
|
@ -138,35 +138,52 @@ load_self_module (gpointer user_data)
|
|||
#error "Add module loading support for GLES3"
|
||||
#endif
|
||||
|
||||
/* Context sharedness es tracked by a unique id stored in each context object
|
||||
* in order track complex creation/deletion scenarios. As a result, sharedness
|
||||
* can only be successfully validated between two GstGLContext's where one is
|
||||
* not a wrapped context.
|
||||
/* Context sharedness is tracked by a refcounted pointer stored in each context
|
||||
* object to track complex creation/deletion scenarios. As a result,
|
||||
* sharedness can only be successfully validated between two GstGLContext's
|
||||
* where one is not a wrapped context.
|
||||
*
|
||||
* As there is no API at the winsys level to tell whether two OpenGL contexts
|
||||
* can share GL resources, this is the next best thing.
|
||||
*
|
||||
* XXX: we may need a way to associate two wrapped GstGLContext's as being
|
||||
* shared however I have not come across a use case that requries this yet.
|
||||
*/
|
||||
static volatile guint sharegroup_idx;
|
||||
|
||||
static guint
|
||||
_new_sharegroup_id (void)
|
||||
struct ContextShareGroup
|
||||
{
|
||||
guint current, ret;
|
||||
volatile int refcount;
|
||||
};
|
||||
|
||||
do {
|
||||
current = g_atomic_int_get (&sharegroup_idx);
|
||||
ret = current + 1;
|
||||
static struct ContextShareGroup *
|
||||
_context_share_group_new (void)
|
||||
{
|
||||
struct ContextShareGroup *ret = g_new0 (struct ContextShareGroup, 1);
|
||||
|
||||
/* 0 is special */
|
||||
if (ret == 0)
|
||||
ret++;
|
||||
} while (!g_atomic_int_compare_and_exchange (&sharegroup_idx, current, ret));
|
||||
|
||||
GST_TRACE ("generated new share group id %u", ret);
|
||||
ret->refcount = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct ContextShareGroup *
|
||||
_context_share_group_ref (struct ContextShareGroup *share)
|
||||
{
|
||||
g_atomic_int_inc (&share->refcount);
|
||||
return share;
|
||||
}
|
||||
|
||||
static void
|
||||
_context_share_group_unref (struct ContextShareGroup *share)
|
||||
{
|
||||
if (g_atomic_int_dec_and_test (&share->refcount))
|
||||
g_free (share);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_context_share_group_is_shared (struct ContextShareGroup *share)
|
||||
{
|
||||
return g_atomic_int_get (&share->refcount) > 1;
|
||||
}
|
||||
|
||||
#define GST_CAT_DEFAULT gst_gl_context_debug
|
||||
GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
|
||||
|
||||
|
@ -194,7 +211,7 @@ struct _GstGLContextPrivate
|
|||
gboolean alive;
|
||||
|
||||
GWeakRef other_context_ref;
|
||||
guint sharegroup_id;
|
||||
struct ContextShareGroup *sharegroup;
|
||||
GError **error;
|
||||
|
||||
gint gl_major;
|
||||
|
@ -389,7 +406,7 @@ gst_gl_context_new_wrapped (GstGLDisplay * display, guintptr handle,
|
|||
context = (GstGLContext *) context_wrap;
|
||||
|
||||
context->display = gst_object_ref (display);
|
||||
context->priv->sharegroup_id = _new_sharegroup_id ();
|
||||
context->priv->sharegroup = _context_share_group_new ();
|
||||
context_wrap->handle = handle;
|
||||
context_wrap->platform = context_type;
|
||||
context_wrap->available_apis = available_apis;
|
||||
|
@ -638,6 +655,9 @@ gst_gl_context_finalize (GObject * object)
|
|||
gst_object_unref (context->window);
|
||||
}
|
||||
|
||||
if (context->priv->sharegroup)
|
||||
_context_share_group_unref (context->priv->sharegroup);
|
||||
|
||||
gst_object_unref (context->display);
|
||||
|
||||
if (context->gl_vtable) {
|
||||
|
@ -887,8 +907,8 @@ gst_gl_context_can_share (GstGLContext * context, GstGLContext * other_context)
|
|||
g_return_val_if_fail (GST_IS_GL_CONTEXT (other_context), FALSE);
|
||||
|
||||
/* check if the contexts are descendants or the root nodes are the same */
|
||||
return context->priv->sharegroup_id != 0
|
||||
&& context->priv->sharegroup_id == other_context->priv->sharegroup_id;
|
||||
return context->priv->sharegroup != NULL
|
||||
&& context->priv->sharegroup == other_context->priv->sharegroup;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -929,9 +949,10 @@ gst_gl_context_create (GstGLContext * context,
|
|||
g_weak_ref_set (&context->priv->other_context_ref, other_context);
|
||||
context->priv->error = error;
|
||||
if (other_context == NULL)
|
||||
context->priv->sharegroup_id = _new_sharegroup_id ();
|
||||
context->priv->sharegroup = _context_share_group_new ();
|
||||
else
|
||||
context->priv->sharegroup_id = other_context->priv->sharegroup_id;
|
||||
context->priv->sharegroup =
|
||||
_context_share_group_ref (other_context->priv->sharegroup);
|
||||
|
||||
context->priv->gl_thread = g_thread_new ("gstglcontext",
|
||||
(GThreadFunc) gst_gl_context_create_thread, context);
|
||||
|
@ -1590,6 +1611,23 @@ gst_gl_context_get_current (void)
|
|||
return g_private_get (¤t_context_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_gl_context_is_shared:
|
||||
* @context: a #GstGLContext
|
||||
*
|
||||
* Returns: Whether the #GstGLContext has been shared with another #GstGLContext
|
||||
*
|
||||
* Since: 1.8
|
||||
*/
|
||||
gboolean
|
||||
gst_gl_context_is_shared (GstGLContext * context)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_GL_CONTEXT (context), FALSE);
|
||||
g_return_val_if_fail (context->priv->alive, FALSE);
|
||||
|
||||
return _context_share_group_is_shared (context->priv->sharegroup);
|
||||
}
|
||||
|
||||
static GstGLAPI
|
||||
gst_gl_wrapped_context_get_gl_api (GstGLContext * context)
|
||||
{
|
||||
|
|
|
@ -148,6 +148,8 @@ gboolean gst_gl_context_check_feature (GstGLContext *context, const gchar *
|
|||
guintptr gst_gl_context_get_current_gl_context (GstGLPlatform platform);
|
||||
GstGLAPI gst_gl_context_get_current_gl_api (GstGLPlatform platform, guint *major, guint *minor);
|
||||
|
||||
gboolean gst_gl_context_is_shared (GstGLContext * context);
|
||||
|
||||
gboolean gst_gl_context_fill_info (GstGLContext * context, GError ** error);
|
||||
|
||||
/* FIXME: remove */
|
||||
|
|
|
@ -489,6 +489,34 @@ GST_START_TEST (test_context_can_share)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_is_shared)
|
||||
{
|
||||
GstGLContext *c1, *c2;
|
||||
GError *error = NULL;
|
||||
|
||||
c1 = gst_gl_context_new (display);
|
||||
gst_gl_context_create (c1, NULL, &error);
|
||||
fail_if (error != NULL, "Error creating context %s\n",
|
||||
error ? error->message : "Unknown Error");
|
||||
|
||||
c2 = gst_gl_context_new (display);
|
||||
gst_gl_context_create (c2, c1, &error);
|
||||
fail_if (error != NULL, "Error creating context %s\n",
|
||||
error ? error->message : "Unknown Error");
|
||||
|
||||
fail_unless (gst_gl_context_is_shared (c1));
|
||||
fail_unless (gst_gl_context_is_shared (c2));
|
||||
|
||||
gst_object_unref (c2);
|
||||
c2 = NULL;
|
||||
|
||||
fail_unless (!gst_gl_context_is_shared (c1));
|
||||
|
||||
gst_object_unref (c1);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
static Suite *
|
||||
gst_gl_context_suite (void)
|
||||
{
|
||||
|
@ -501,6 +529,7 @@ gst_gl_context_suite (void)
|
|||
tcase_add_test (tc_chain, test_wrapped_context);
|
||||
tcase_add_test (tc_chain, test_current_context);
|
||||
tcase_add_test (tc_chain, test_context_can_share);
|
||||
tcase_add_test (tc_chain, test_is_shared);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue