From 35476a4cb443f7d45557a6cfcbbccf909ca6f026 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Tue, 3 Mar 2015 18:05:04 +1100 Subject: [PATCH] gl/cocoa: avoid deadlock when creating context on the main thread. Make window/view creation async so that it is possible to gst_gl_context_create from the main thread. --- ext/gl/caopengllayersink.m | 3 +-- gst-libs/gst/gl/cocoa/gstglwindow_cocoa.h | 1 - gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m | 19 +++++++++++++++---- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/ext/gl/caopengllayersink.m b/ext/gl/caopengllayersink.m index fdbcf7b..3a11b8e 100644 --- a/ext/gl/caopengllayersink.m +++ b/ext/gl/caopengllayersink.m @@ -272,8 +272,6 @@ _ensure_gl_setup (GstCAOpenGLLayerSink * ca_sink) { GError *error = NULL; - g_assert (![NSThread isMainThread]); - if (!gst_gl_ensure_element_data (ca_sink, &ca_sink->display, &ca_sink->other_context)) return FALSE; @@ -400,6 +398,7 @@ gst_ca_opengl_layer_sink_change_state (GstElement * element, GstStateChange tran switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: + _ensure_gl_setup (ca_sink); break; case GST_STATE_CHANGE_READY_TO_PAUSED: g_atomic_int_set (&ca_sink->to_quit, 0); diff --git a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.h b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.h index 3a794fc..775c291 100644 --- a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.h +++ b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.h @@ -62,7 +62,6 @@ GstGLWindowCocoa * gst_gl_window_cocoa_new (void); void gst_gl_window_cocoa_draw_thread (GstGLWindowCocoa *window_cocoa); - G_END_DECLS #endif /* __GST_GL_WINDOW_COCOA_H__ */ diff --git a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m index 1da6d63..adc63d2 100644 --- a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m +++ b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m @@ -92,6 +92,9 @@ struct _GstGLWindowCocoaPrivate gint preferred_height; GLint viewport_dim[4]; + + /* atomic set when the internal NSView has been created */ + int view_ready; }; static void @@ -178,7 +181,9 @@ gst_gl_window_cocoa_create_window (GstGLWindowCocoa *window_cocoa) GST_DEBUG ("NSWindow id: %"G_GUINTPTR_FORMAT, (guintptr) priv->internal_win_id); - [priv->internal_win_id setContentView:glView]; + [priv->internal_win_id setContentView:glView]; + + g_atomic_int_set (&window_cocoa->priv->view_ready, 1); return TRUE; } @@ -287,7 +292,14 @@ static void gst_gl_window_cocoa_draw (GstGLWindow * window) { GstGLWindowCocoa *window_cocoa = GST_GL_WINDOW_COCOA (window); - GstGLNSView *view = (GstGLNSView *)[window_cocoa->priv->internal_win_id contentView]; + GstGLNSView *view; + + /* As the view is created asynchronously in the main thread we cannot know + * exactly when it will be ready to draw to */ + if (!g_atomic_int_get (&window_cocoa->priv->view_ready)) + return; + + view = (GstGLNSView *)[window_cocoa->priv->internal_win_id contentView]; /* this redraws the GstGLCAOpenGLLayer which calls * gst_gl_window_cocoa_draw_thread(). Use an explicit CATransaction since we @@ -584,9 +596,8 @@ _invoke_on_main (GstGLWindowCB func, gpointer data) if ([NSThread isMainThread]) { func (data); } else { - dispatch_sync (dispatch_get_main_queue (), ^{ + dispatch_async (dispatch_get_main_queue (), ^{ func (data); }); } } - -- 2.7.4