summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Waters <matthew@centricular.com>2015-02-17 18:17:59 +1100
committerMatthew Waters <matthew@centricular.com>2015-02-17 19:45:35 +1100
commit0fd6872f7d831c11e59d203695ff8d3c0d355b83 (patch)
treeea2e79713ced98ae7287183121d05498fcdcaae6
parent96398e5bac3032d218dcd014b3ad657279efb9bb (diff)
downloadgstreamer-plugins-bad-0fd6872f7d831c11e59d203695ff8d3c0d355b83.tar.gz
gl/cocoa: don't deadlock if the dispatch_sync is called from the main thread
Provide a helper function to check whether we are being called from the main thread and act appropriately.
-rw-r--r--gst-libs/gst/gl/cocoa/gstgl_cocoa_private.h2
-rw-r--r--gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m80
-rw-r--r--gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m39
3 files changed, 70 insertions, 51 deletions
diff --git a/gst-libs/gst/gl/cocoa/gstgl_cocoa_private.h b/gst-libs/gst/gl/cocoa/gstgl_cocoa_private.h
index df00a3882..ae7abc8a6 100644
--- a/gst-libs/gst/gl/cocoa/gstgl_cocoa_private.h
+++ b/gst-libs/gst/gl/cocoa/gstgl_cocoa_private.h
@@ -59,6 +59,8 @@ struct _GstGLContextCocoaPrivate
gboolean gst_gl_window_cocoa_create_window (GstGLWindowCocoa *window_cocoa);
+void _invoke_on_main (GstGLWindowCB func, gpointer data);
+
G_END_DECLS
#endif /* __GST_GL_COCOA_PRIVATE_H__ */
diff --git a/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m b/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m
index 8298b3d50..e7c57229c 100644
--- a/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m
+++ b/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m
@@ -290,6 +290,18 @@ gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
GstGLWindow *window = gst_gl_context_get_window (context);
GstGLWindowCocoa *window_cocoa = GST_GL_WINDOW_COCOA (window);
const GLint swapInterval = 1;
+ NSAutoreleasePool *pool;
+ CGLPixelFormatObj fmt = NULL;
+ CGLContextObj glContext;
+ CGLPixelFormatAttribute attribs[] = {
+ kCGLPFADoubleBuffer,
+ kCGLPFAAccumSize, 32,
+ 0
+ };
+ CGLError ret;
+ gint npix;
+
+ pool = [[NSAutoreleasePool alloc] init];
#ifndef GSTREAMER_GLIB_COCOA_NSAPPLICATION
priv->source_id = g_timeout_add (200, gst_gl_window_cocoa_nsapp_iteration, NULL);
@@ -301,58 +313,40 @@ gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
else
priv->external_gl_context = NULL;
- dispatch_sync (dispatch_get_main_queue (), ^{
- NSAutoreleasePool *pool;
- CGLPixelFormatObj fmt = NULL;
- CGLContextObj glContext;
- CGLPixelFormatAttribute attribs[] = {
- kCGLPFADoubleBuffer,
- kCGLPFAAccumSize, 32,
- 0
- };
- CGLError ret;
- gint npix;
-
- pool = [[NSAutoreleasePool alloc] init];
-
- if (priv->external_gl_context) {
- fmt = CGLGetPixelFormat (priv->external_gl_context);
- }
-
- if (!fmt) {
- ret = CGLChoosePixelFormat (attribs, &fmt, &npix);
- if (ret != kCGLNoError) {
- gst_object_unref (window);
- g_set_error (error, GST_GL_CONTEXT_ERROR,
- GST_GL_CONTEXT_ERROR_WRONG_CONFIG, "cannot choose a pixel format: %s", CGLErrorString (ret));
- return;
- }
- }
-
- gst_gl_context_cocoa_dump_pixel_format (fmt);
+ if (priv->external_gl_context) {
+ fmt = CGLGetPixelFormat (priv->external_gl_context);
+ }
- ret = CGLCreateContext (fmt, priv->external_gl_context, &glContext);
+ if (!fmt) {
+ ret = CGLChoosePixelFormat (attribs, &fmt, &npix);
if (ret != kCGLNoError) {
- g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_CREATE_CONTEXT,
- "failed to create context: %s", CGLErrorString (ret));
- gst_object_unref (window);
- return;
+ g_set_error (error, GST_GL_CONTEXT_ERROR,
+ GST_GL_CONTEXT_ERROR_WRONG_CONFIG, "cannot choose a pixel format: %s", CGLErrorString (ret));
+ goto error;
}
+ }
+
+ gst_gl_context_cocoa_dump_pixel_format (fmt);
- context_cocoa->priv->pixel_format = fmt;
- context_cocoa->priv->gl_context = glContext;
+ ret = CGLCreateContext (fmt, priv->external_gl_context, &glContext);
+ if (ret != kCGLNoError) {
+ g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_CREATE_CONTEXT,
+ "failed to create context: %s", CGLErrorString (ret));
+ goto error;
+ }
- gst_gl_window_cocoa_create_window (window_cocoa);
+ context_cocoa->priv->pixel_format = fmt;
+ context_cocoa->priv->gl_context = glContext;
- [pool release];
- });
+ _invoke_on_main ((GstGLWindowCB) gst_gl_window_cocoa_create_window,
+ window_cocoa);
if (!context_cocoa->priv->gl_context) {
#ifndef GSTREAMER_GLIB_COCOA_NSAPPLICATION
g_source_remove (priv->source_id);
priv->source_id = 0;
#endif
- return FALSE;
+ goto error;
}
GST_INFO_OBJECT (context, "GL context created: %p", context_cocoa->priv->gl_context);
@@ -365,8 +359,14 @@ gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
CGLSetParameter (context_cocoa->priv->gl_context, kCGLCPSwapInterval, &swapInterval);
gst_object_unref (window);
+ [pool release];
return TRUE;
+
+error:
+ gst_object_unref (window);
+ [pool release];
+ return FALSE;
}
static void
diff --git a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m
index 229948a9c..17ded0467 100644
--- a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m
+++ b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m
@@ -238,6 +238,20 @@ gst_gl_window_cocoa_set_window_handle (GstGLWindow * window, guintptr handle)
}
static void
+_show_window (gpointer data)
+{
+ GstGLWindowCocoa *window_cocoa = GST_GL_WINDOW_COCOA (data);
+ GstGLWindowCocoaPrivate *priv = window_cocoa->priv;
+
+ GST_DEBUG_OBJECT (window_cocoa, "make the window available\n");
+ [priv->internal_win_id makeMainWindow];
+ [priv->internal_win_id orderFrontRegardless];
+ [priv->internal_win_id setViewsNeedDisplay:YES];
+
+ priv->visible = TRUE;
+}
+
+static void
gst_gl_window_cocoa_show (GstGLWindow * window)
{
GstGLWindowCocoa *window_cocoa = GST_GL_WINDOW_COCOA (window);
@@ -252,17 +266,8 @@ gst_gl_window_cocoa_show (GstGLWindow * window)
return;
}
- dispatch_sync (dispatch_get_main_queue(), ^{
- if (!priv->external_view && !priv->visible) {
-
- GST_DEBUG_OBJECT (window_cocoa, "make the window available\n");
- [priv->internal_win_id makeMainWindow];
- [priv->internal_win_id orderFrontRegardless];
- [priv->internal_win_id setViewsNeedDisplay:YES];
-
- priv->visible = TRUE;
- }
- });
+ if (!priv->external_view && !priv->visible)
+ _invoke_on_main ((GstGLWindowCB) _show_window, window);
}
}
@@ -561,3 +566,15 @@ close_window_cb (gpointer data)
@end
+void
+_invoke_on_main (GstGLWindowCB func, gpointer data)
+{
+ if ([NSThread isMainThread]) {
+ func (data);
+ } else {
+ dispatch_sync (dispatch_get_main_queue (), ^{
+ func (data);
+ });
+ }
+}
+