mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-24 16:18:16 +00:00
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
This commit is contained in:
parent
3a9fde7b24
commit
7f59cefafb
1 changed files with 34 additions and 3 deletions
|
@ -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 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_close (GstGLWindow *window);
|
||||||
|
static void gst_gl_window_cocoa_quit (GstGLWindow *window);
|
||||||
static guintptr gst_gl_window_cocoa_get_window_handle (GstGLWindow * window);
|
static guintptr gst_gl_window_cocoa_get_window_handle (GstGLWindow * window);
|
||||||
static void gst_gl_window_cocoa_set_window_handle (GstGLWindow * window,
|
static void gst_gl_window_cocoa_set_window_handle (GstGLWindow * window,
|
||||||
guintptr handle);
|
guintptr handle);
|
||||||
|
@ -96,6 +97,9 @@ struct _GstGLWindowCocoaPrivate
|
||||||
int view_ready;
|
int view_ready;
|
||||||
|
|
||||||
gpointer gl_queue;
|
gpointer gl_queue;
|
||||||
|
|
||||||
|
gboolean shutting_down;
|
||||||
|
GstGLContext *last_context;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEBUG_INIT \
|
#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->open = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_open);
|
||||||
window_class->close = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_close);
|
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 =
|
window_class->get_window_handle =
|
||||||
GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_get_window_handle);
|
GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_get_window_handle);
|
||||||
window_class->set_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;
|
GstGLWindowCocoa *window_cocoa = (GstGLWindowCocoa *) window;
|
||||||
GstGLContext *context = gst_gl_window_get_context (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;
|
GstGLWindowCocoaPrivate *priv = window_cocoa->priv;
|
||||||
#if OS_OBJECT_USE_OBJC
|
#if OS_OBJECT_USE_OBJC
|
||||||
dispatch_queue_t gl_queue = (__bridge dispatch_queue_t)priv->gl_queue;
|
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;
|
dispatch_queue_t gl_queue = (dispatch_queue_t)priv->gl_queue;
|
||||||
#endif
|
#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()) {
|
if (thread == g_thread_self()) {
|
||||||
/* this case happens for nested calls happening from inside the GCD queue */
|
/* this case happens for nested calls happening from inside the GCD queue */
|
||||||
callback (data);
|
callback (data);
|
||||||
if (destroy)
|
if (destroy)
|
||||||
destroy (data);
|
destroy (data);
|
||||||
gst_object_unref (context);
|
if (unref_context)
|
||||||
|
gst_object_unref (unref_context);
|
||||||
} else {
|
} else {
|
||||||
dispatch_async (gl_queue, ^{
|
dispatch_async (gl_queue, ^{
|
||||||
gst_gl_context_activate (context, TRUE);
|
gst_gl_context_activate (context, TRUE);
|
||||||
gst_object_unref (context);
|
if (unref_context)
|
||||||
|
gst_object_unref (unref_context);
|
||||||
callback (data);
|
callback (data);
|
||||||
if (destroy)
|
if (destroy)
|
||||||
destroy (data);
|
destroy (data);
|
||||||
|
@ -495,6 +516,16 @@ gst_gl_window_cocoa_send_message_async (GstGLWindow * window,
|
||||||
g_thread_unref (thread);
|
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
|
struct SetRenderRectangle
|
||||||
{
|
{
|
||||||
GstGLWindowCocoa *window_cocoa;
|
GstGLWindowCocoa *window_cocoa;
|
||||||
|
|
Loading…
Reference in a new issue