mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 06:46:38 +00:00
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.
This commit is contained in:
parent
96398e5bac
commit
0fd6872f7d
3 changed files with 70 additions and 51 deletions
|
@ -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__ */
|
||||
|
|
|
@ -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;
|
||||
if (priv->external_gl_context) {
|
||||
fmt = CGLGetPixelFormat (priv->external_gl_context);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
context_cocoa->priv->pixel_format = fmt;
|
||||
context_cocoa->priv->gl_context = glContext;
|
||||
gst_gl_context_cocoa_dump_pixel_format (fmt);
|
||||
|
||||
gst_gl_window_cocoa_create_window (window_cocoa);
|
||||
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;
|
||||
}
|
||||
|
||||
[pool release];
|
||||
});
|
||||
context_cocoa->priv->pixel_format = fmt;
|
||||
context_cocoa->priv->gl_context = glContext;
|
||||
|
||||
_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
|
||||
|
|
|
@ -237,6 +237,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)
|
||||
{
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue