gldisplay: synchronize the searching and creation of GstGLContext's

Ootherwise we could end up with multiple elements in different chains
each creating a context.  Fixes context creation with glvideomixer.
This commit is contained in:
Matthew Waters 2015-04-21 12:19:46 +10:00 committed by Tim-Philipp Müller
parent e6c5410a2a
commit 03908c679e
7 changed files with 25 additions and 6 deletions

View file

@ -484,6 +484,7 @@ gst_gl_base_mixer_decide_allocation (GstGLBaseMixer * mix, GstQuery * query)
_find_local_gl_context (mix); _find_local_gl_context (mix);
if (!mix->context) { if (!mix->context) {
GST_OBJECT_LOCK (mix->display);
do { do {
if (mix->context) if (mix->context)
gst_object_unref (mix->context); gst_object_unref (mix->context);
@ -497,6 +498,7 @@ gst_gl_base_mixer_decide_allocation (GstGLBaseMixer * mix, GstQuery * query)
goto context_error; goto context_error;
} }
} while (!gst_gl_display_add_context (mix->display, mix->context)); } while (!gst_gl_display_add_context (mix->display, mix->context));
GST_OBJECT_UNLOCK (mix->display);
} }
if (mix_class->decide_allocation) if (mix_class->decide_allocation)

View file

@ -698,6 +698,7 @@ _ensure_gl_setup (GstGLImageSink * gl_sink)
GST_DEBUG_OBJECT (gl_sink, "Ensuring setup"); GST_DEBUG_OBJECT (gl_sink, "Ensuring setup");
if (!gl_sink->context) { if (!gl_sink->context) {
GST_OBJECT_LOCK (gl_sink->display);
do { do {
GstGLContext *other_context; GstGLContext *other_context;
GstGLWindow *window; GstGLWindow *window;
@ -770,6 +771,7 @@ _ensure_gl_setup (GstGLImageSink * gl_sink)
gst_object_unref (other_context); gst_object_unref (other_context);
gst_object_unref (window); gst_object_unref (window);
} while (!gst_gl_display_add_context (gl_sink->display, gl_sink->context)); } while (!gst_gl_display_add_context (gl_sink->display, gl_sink->context));
GST_OBJECT_UNLOCK (gl_sink->display);
} else } else
GST_DEBUG_OBJECT (gl_sink, "Already have a context"); GST_DEBUG_OBJECT (gl_sink, "Already have a context");
@ -908,6 +910,9 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
gst_gl_display_filter_gl_api (glimage_sink->display, SUPPORTED_GL_APIS); gst_gl_display_filter_gl_api (glimage_sink->display, SUPPORTED_GL_APIS);
break; break;
case GST_STATE_CHANGE_READY_TO_PAUSED: case GST_STATE_CHANGE_READY_TO_PAUSED:
if (!_ensure_gl_setup (glimage_sink))
return GST_STATE_CHANGE_FAILURE;
g_atomic_int_set (&glimage_sink->to_quit, 0); g_atomic_int_set (&glimage_sink->to_quit, 0);
break; break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING: case GST_STATE_CHANGE_PAUSED_TO_PLAYING:

View file

@ -816,6 +816,7 @@ gst_gl_test_src_decide_allocation (GstBaseSrc * basesrc, GstQuery * query)
_find_local_gl_context (src); _find_local_gl_context (src);
if (!src->context) { if (!src->context) {
GST_OBJECT_LOCK (src->display);
do { do {
if (src->context) if (src->context)
gst_object_unref (src->context); gst_object_unref (src->context);
@ -828,6 +829,7 @@ gst_gl_test_src_decide_allocation (GstBaseSrc * basesrc, GstQuery * query)
goto context_error; goto context_error;
} }
} while (!gst_gl_display_add_context (src->display, src->context)); } while (!gst_gl_display_add_context (src->display, src->context));
GST_OBJECT_UNLOCK (src->display);
} }
out_width = GST_VIDEO_INFO_WIDTH (&src->out_info); out_width = GST_VIDEO_INFO_WIDTH (&src->out_info);

View file

@ -334,6 +334,7 @@ gst_gl_base_filter_decide_allocation (GstBaseTransform * trans,
_find_local_gl_context (filter); _find_local_gl_context (filter);
if (!filter->context) { if (!filter->context) {
GST_OBJECT_LOCK (filter->display);
do { do {
if (filter->context) if (filter->context)
gst_object_unref (filter->context); gst_object_unref (filter->context);
@ -350,6 +351,7 @@ gst_gl_base_filter_decide_allocation (GstBaseTransform * trans,
goto context_error; goto context_error;
} }
} while (!gst_gl_display_add_context (filter->display, filter->context)); } while (!gst_gl_display_add_context (filter->display, filter->context));
GST_OBJECT_UNLOCK (filter->display);
} }
gst_gl_context_thread_add (filter->context, gst_gl_base_filter_gl_start, gst_gl_context_thread_add (filter->context, gst_gl_base_filter_gl_start,

View file

@ -1216,7 +1216,7 @@ gst_gl_context_create_thread (GstGLContext * context)
context_class = GST_GL_CONTEXT_GET_CLASS (context); context_class = GST_GL_CONTEXT_GET_CLASS (context);
window_class = GST_GL_WINDOW_GET_CLASS (context->window); window_class = GST_GL_WINDOW_GET_CLASS (context->window);
display_api = gst_gl_display_get_gl_api (context->priv->display); display_api = gst_gl_display_get_gl_api_unlocked (context->priv->display);
if (display_api == GST_GL_API_NONE) { if (display_api == GST_GL_API_NONE) {
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_API, g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_API,
"Cannot create context with satisfying requested apis " "Cannot create context with satisfying requested apis "

View file

@ -237,6 +237,14 @@ gst_gl_display_filter_gl_api (GstGLDisplay * display, GstGLAPI gl_api)
GST_OBJECT_UNLOCK (display); GST_OBJECT_UNLOCK (display);
} }
GstGLAPI
gst_gl_display_get_gl_api_unlocked (GstGLDisplay * display)
{
g_return_val_if_fail (GST_IS_GL_DISPLAY (display), GST_GL_API_NONE);
return display->priv->gl_api;
}
/** /**
* gst_gl_display_get_gl_api: * gst_gl_display_get_gl_api:
* @display: a #GstGLDisplay * @display: a #GstGLDisplay
@ -372,6 +380,8 @@ _get_gl_context_for_thread_unlocked (GstGLDisplay * display, GThread * thread)
* *
* Returns: (transfer full): the #GstGLContext current on @thread or %NULL * Returns: (transfer full): the #GstGLContext current on @thread or %NULL
* *
* Must be called with the object lock held.
*
* Since: 1.6 * Since: 1.6
*/ */
GstGLContext * GstGLContext *
@ -382,11 +392,9 @@ gst_gl_display_get_gl_context_for_thread (GstGLDisplay * display,
g_return_val_if_fail (GST_IS_GL_DISPLAY (display), NULL); g_return_val_if_fail (GST_IS_GL_DISPLAY (display), NULL);
GST_OBJECT_LOCK (display);
context = _get_gl_context_for_thread_unlocked (display, thread); context = _get_gl_context_for_thread_unlocked (display, thread);
GST_DEBUG_OBJECT (display, "returning context %" GST_PTR_FORMAT " for thread " GST_DEBUG_OBJECT (display, "returning context %" GST_PTR_FORMAT " for thread "
"%p", context, thread); "%p", context, thread);
GST_OBJECT_UNLOCK (display);
return context; return context;
} }
@ -430,6 +438,8 @@ out:
* Returns: whether @context was successfully added. %FALSE may be returned * Returns: whether @context was successfully added. %FALSE may be returned
* if there already exists another context for @context's active thread. * if there already exists another context for @context's active thread.
* *
* Must be called with the object lock held.
*
* Since: 1.6 * Since: 1.6
*/ */
gboolean gboolean
@ -448,8 +458,6 @@ gst_gl_display_add_context (GstGLDisplay * display, GstGLContext * context)
g_assert (context_display == display); g_assert (context_display == display);
gst_object_unref (context_display); gst_object_unref (context_display);
GST_OBJECT_LOCK (display);
thread = gst_gl_context_get_thread (context); thread = gst_gl_context_get_thread (context);
if (thread) { if (thread) {
collision = _get_gl_context_for_thread_unlocked (display, thread); collision = _get_gl_context_for_thread_unlocked (display, thread);
@ -471,7 +479,6 @@ out:
GST_DEBUG_OBJECT (display, "%ssuccessfully inserted context %" GST_PTR_FORMAT, GST_DEBUG_OBJECT (display, "%ssuccessfully inserted context %" GST_PTR_FORMAT,
ret ? "" : "un", context); ret ? "" : "un", context);
GST_OBJECT_UNLOCK (display);
return ret; return ret;
} }

View file

@ -86,6 +86,7 @@ GstGLDisplayType gst_gl_display_get_handle_type (GstGLDisplay * display);
void gst_gl_display_filter_gl_api (GstGLDisplay * display, void gst_gl_display_filter_gl_api (GstGLDisplay * display,
GstGLAPI api); GstGLAPI api);
GstGLAPI gst_gl_display_get_gl_api (GstGLDisplay * display); GstGLAPI gst_gl_display_get_gl_api (GstGLDisplay * display);
GstGLAPI gst_gl_display_get_gl_api_unlocked (GstGLDisplay * display);
#define GST_GL_DISPLAY_CONTEXT_TYPE "gst.gl.GLDisplay" #define GST_GL_DISPLAY_CONTEXT_TYPE "gst.gl.GLDisplay"
void gst_context_set_gl_display (GstContext * context, GstGLDisplay * display); void gst_context_set_gl_display (GstContext * context, GstGLDisplay * display);