From 7f59cefafb1cd733cf527fb935b2cd32418fcbe2 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Thu, 26 Mar 2020 13:51:24 +1100 Subject: [PATCH] glcontext/cocoa: handle sending one message during shutdown gst_gl_window_quit() will attempt to send a message but will be called from GstGLContext's finalize handler and so the weak ref that backs gst_gl_window_get_context will return NULL as it has already been cleared. We need that context in send_message_async to decide whether to run the provided callback immediately or queue in GCD --- gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m | 37 +++++++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m index f70001ee3d..0997b8d539 100644 --- a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m +++ b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m @@ -69,6 +69,7 @@ static void gst_gl_window_cocoa_finalize (GObject * object); static gboolean gst_gl_window_cocoa_open (GstGLWindow *window, GError **err); static void gst_gl_window_cocoa_close (GstGLWindow *window); +static void gst_gl_window_cocoa_quit (GstGLWindow *window); static guintptr gst_gl_window_cocoa_get_window_handle (GstGLWindow * window); static void gst_gl_window_cocoa_set_window_handle (GstGLWindow * window, guintptr handle); @@ -96,6 +97,9 @@ struct _GstGLWindowCocoaPrivate int view_ready; gpointer gl_queue; + + gboolean shutting_down; + GstGLContext *last_context; }; #define DEBUG_INIT \ @@ -114,6 +118,7 @@ gst_gl_window_cocoa_class_init (GstGLWindowCocoaClass * klass) window_class->open = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_open); window_class->close = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_close); + window_class->quit = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_quit); window_class->get_window_handle = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_get_window_handle); window_class->set_window_handle = @@ -468,7 +473,8 @@ gst_gl_window_cocoa_send_message_async (GstGLWindow * window, { GstGLWindowCocoa *window_cocoa = (GstGLWindowCocoa *) window; GstGLContext *context = gst_gl_window_get_context (window); - GThread *thread = gst_gl_context_get_thread (context); + GstGLContext *unref_context = NULL; + GThread *thread = NULL; GstGLWindowCocoaPrivate *priv = window_cocoa->priv; #if OS_OBJECT_USE_OBJC dispatch_queue_t gl_queue = (__bridge dispatch_queue_t)priv->gl_queue; @@ -476,16 +482,31 @@ gst_gl_window_cocoa_send_message_async (GstGLWindow * window, dispatch_queue_t gl_queue = (dispatch_queue_t)priv->gl_queue; #endif + if (context) + window_cocoa->priv->last_context = unref_context = context; + + /* we may not have a context if we are shutting down */ + if (!context && window_cocoa->priv->shutting_down) { + context = window_cocoa->priv->last_context; + window_cocoa->priv->shutting_down = FALSE; + } + + g_return_if_fail (context != NULL); + + thread = gst_gl_context_get_thread (context); + if (thread == g_thread_self()) { /* this case happens for nested calls happening from inside the GCD queue */ callback (data); if (destroy) destroy (data); - gst_object_unref (context); + if (unref_context) + gst_object_unref (unref_context); } else { dispatch_async (gl_queue, ^{ gst_gl_context_activate (context, TRUE); - gst_object_unref (context); + if (unref_context) + gst_object_unref (unref_context); callback (data); if (destroy) destroy (data); @@ -495,6 +516,16 @@ gst_gl_window_cocoa_send_message_async (GstGLWindow * window, g_thread_unref (thread); } +static void +gst_gl_window_cocoa_quit (GstGLWindow * window) +{ + GstGLWindowCocoa *window_cocoa = (GstGLWindowCocoa *) window; + + window_cocoa->priv->shutting_down = TRUE; + + GST_GL_WINDOW_CLASS (parent_class)->quit (window); +} + struct SetRenderRectangle { GstGLWindowCocoa *window_cocoa;