gl/cocoa: keep refs over async operations

Avoids dereferencing dead objects

What happens in the autovideosink case is that context 1 is created and
destroyed before all the async operations hae executed on the associated
window.  When the delayed operations execute, they then reference dead
objects and crash.

We fix this by keeping refs over all async operations so the object
cannot be deleted while async operations are in flight.

https://bugzilla.gnome.org/show_bug.cgi?id=782379
This commit is contained in:
Matthew Waters 2017-07-16 01:17:04 +10:00
parent 1656d8000d
commit 24e3cbf13b
3 changed files with 19 additions and 7 deletions

View file

@ -59,7 +59,7 @@ struct _GstGLContextCocoaPrivate
gboolean gst_gl_window_cocoa_create_window (GstGLWindowCocoa *window_cocoa);
void _invoke_on_main (GstGLWindowCB func, gpointer data);
void _invoke_on_main (GstGLWindowCB func, gpointer data, GDestroyNotify notify);
G_END_DECLS

View file

@ -259,7 +259,7 @@ gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
context_cocoa->priv->gl_context = glContext;
_invoke_on_main ((GstGLWindowCB) gst_gl_window_cocoa_create_window,
window_cocoa);
gst_object_ref (window_cocoa), (GDestroyNotify) gst_object_unref);
if (!context_cocoa->priv->gl_context) {
goto error;

View file

@ -175,9 +175,16 @@ gst_gl_window_cocoa_create_window (GstGLWindowCocoa *window_cocoa)
NSRect rect = NSMakeRect (0, y, priv->preferred_width, priv->preferred_height);
NSRect windowRect = NSMakeRect (0, y, priv->preferred_width, priv->preferred_height);
GstGLContext *context = gst_gl_window_get_context (window);
GstGLContextCocoa *context_cocoa = GST_GL_CONTEXT_COCOA (context);
GstGLCAOpenGLLayer *layer = [[GstGLCAOpenGLLayer alloc] initWithGstGLContext:context_cocoa];
GstGLNSView *glView = [[GstGLNSView alloc] initWithFrameLayer:window_cocoa rect:windowRect layer:layer];
GstGLContextCocoa *context_cocoa;
GstGLCAOpenGLLayer *layer;
GstGLNSView *glView;
if (!context)
return FALSE;
context_cocoa = GST_GL_CONTEXT_COCOA (context);
layer = [[GstGLCAOpenGLLayer alloc] initWithGstGLContext:context_cocoa];
glView = [[GstGLNSView alloc] initWithFrameLayer:window_cocoa rect:windowRect layer:layer];
gst_object_unref (context);
@ -296,7 +303,8 @@ gst_gl_window_cocoa_show (GstGLWindow * window)
}
if (!priv->external_view && !priv->visible)
_invoke_on_main ((GstGLWindowCB) _show_window, window);
_invoke_on_main ((GstGLWindowCB) _show_window, gst_object_ref (window),
(GDestroyNotify) gst_object_unref);
}
}
@ -575,13 +583,17 @@ close_window_cb (gpointer data)
@end
void
_invoke_on_main (GstGLWindowCB func, gpointer data)
_invoke_on_main (GstGLWindowCB func, gpointer data, GDestroyNotify notify)
{
if ([NSThread isMainThread]) {
func (data);
if (notify)
notify (data);
} else {
dispatch_async (dispatch_get_main_queue (), ^{
func (data);
if (notify)
notify (data);
});
}
}