diff --git a/gst-libs/gst/gl/cocoa/gstgl_cocoa_private.h b/gst-libs/gst/gl/cocoa/gstgl_cocoa_private.h index ae7abc8a6e..2459e2a284 100644 --- a/gst-libs/gst/gl/cocoa/gstgl_cocoa_private.h +++ b/gst-libs/gst/gl/cocoa/gstgl_cocoa_private.h @@ -40,6 +40,7 @@ struct _GstGLContextCocoaPrivate GstGLAPI context_api; gint source_id; + GRecMutex current_lock; }; @@ -59,8 +60,13 @@ struct _GstGLContextCocoaPrivate gboolean gst_gl_window_cocoa_create_window (GstGLWindowCocoa *window_cocoa); + void _invoke_on_main (GstGLWindowCB func, gpointer data); +typedef void (*GstGLContextCocoaInvokeFunc) (gpointer data); +void _gst_gl_context_cocoa_invoke (GstGLContext * context, + GstGLContextCocoaInvokeFunc func, gpointer data, GDestroyNotify notify); + 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 ac1e0d6928..c50d0069f1 100644 --- a/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m +++ b/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m @@ -43,14 +43,18 @@ GST_DEBUG_CATEGORY_STATIC (gst_gl_context_cocoa_debug); G_DEFINE_TYPE_WITH_CODE (GstGLContextCocoa, gst_gl_context_cocoa, GST_GL_TYPE_CONTEXT, GST_DEBUG_CATEGORY_INIT (gst_gl_context_cocoa_debug, "glcontext_cocoa", 0, "Cocoa GL Context"); ); +static void gst_gl_context_cocoa_finalize (GObject * object); static void gst_gl_context_cocoa_class_init (GstGLContextCocoaClass * klass) { + GObjectClass *gobject_class = (GObjectClass *) klass; GstGLContextClass *context_class = (GstGLContextClass *) klass; g_type_class_add_private (klass, sizeof (GstGLContextCocoaPrivate)); + gobject_class->finalize = gst_gl_context_cocoa_finalize; + context_class->destroy_context = GST_DEBUG_FUNCPTR (gst_gl_context_cocoa_destroy_context); context_class->create_context = @@ -68,6 +72,13 @@ static void gst_gl_context_cocoa_init (GstGLContextCocoa * context) { context->priv = GST_GL_CONTEXT_COCOA_GET_PRIVATE (context); + g_rec_mutex_init (&context->priv->current_lock); +} + +static void gst_gl_context_cocoa_finalize (GObject * object) +{ + g_rec_mutex_clear (&GST_GL_CONTEXT_COCOA (object)->priv->current_lock); + G_OBJECT_CLASS (gst_gl_context_cocoa_parent_class)->finalize (object); } /* Must be called in the gl thread */ @@ -327,3 +338,17 @@ gst_gl_context_cocoa_get_current_context (void) { return (guintptr) CGLGetCurrentContext (); } + +void +_gst_gl_context_cocoa_invoke (GstGLContext * context, + GstGLContextCocoaInvokeFunc func, gpointer data, GDestroyNotify destroy) +{ + GstGLContextCocoa *context_cocoa = (GstGLContextCocoa *) context; + + g_rec_mutex_lock (&context_cocoa->priv->current_lock); + gst_gl_context_activate (context, TRUE); + func (data); + if (destroy) + destroy (data); + g_rec_mutex_unlock (&context_cocoa->priv->current_lock); +} diff --git a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m index 0d027c5a1a..3d771fb6d6 100644 --- a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m +++ b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m @@ -77,6 +77,10 @@ static void gst_gl_window_cocoa_set_preferred_size (GstGLWindow * window, gint width, gint height); static void gst_gl_window_cocoa_show (GstGLWindow * window); static void gst_gl_window_cocoa_queue_resize (GstGLWindow * window); +static void gst_gl_window_cocoa_send_message_async (GstGLWindow * window, + GstGLWindowCB callback, gpointer data, GDestroyNotify destroy); +static void gst_gl_window_cocoa_send_message (GstGLWindow * window, + GstGLWindowCB callback, gpointer data); struct _GstGLWindowCocoaPrivate { @@ -111,6 +115,10 @@ gst_gl_window_cocoa_class_init (GstGLWindowCocoaClass * klass) GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_set_preferred_size); window_class->show = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_show); window_class->queue_resize = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_queue_resize); + window_class->send_message_async = + GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_send_message_async); + window_class->send_message = + GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_send_message); gobject_class->finalize = gst_gl_window_cocoa_finalize; } @@ -370,6 +378,24 @@ gst_gl_cocoa_resize_cb (GstGLNSView * view, guint width, guint height) [pool release]; } +static void +gst_gl_window_cocoa_send_message_async (GstGLWindow * window, + GstGLWindowCB callback, gpointer data, GDestroyNotify destroy) +{ + GstGLContext *context = gst_gl_window_get_context (window); + _gst_gl_context_cocoa_invoke (context, callback, data, destroy); + gst_object_unref (context); +} + +static void +gst_gl_window_cocoa_send_message (GstGLWindow * window, + GstGLWindowCB callback, gpointer data) +{ + GstGLContext *context = gst_gl_window_get_context (window); + _gst_gl_context_cocoa_invoke (context, callback, data, NULL); + gst_object_unref (context); +} + /* =============================================================*/ /* */ /* GstGLNSWindow implementation */ diff --git a/gst-libs/gst/gl/eagl/gstglcontext_eagl.h b/gst-libs/gst/gl/eagl/gstglcontext_eagl.h index 262281029c..0a36cb9e49 100644 --- a/gst-libs/gst/gl/eagl/gstglcontext_eagl.h +++ b/gst-libs/gst/gl/eagl/gstglcontext_eagl.h @@ -65,6 +65,10 @@ void gst_gl_context_eagl_prepare_draw (GstGLContextEagl * context); void gst_gl_context_eagl_finish_draw (GstGLContextEagl * context); guintptr gst_gl_context_eagl_get_current_context (void); +/* private */ +typedef void (*GstGLContextEaglInvokeFunc) (gpointer data); +void _gst_gl_context_eagl_invoke (GstGLContext * context, + GstGLContextEaglInvokeFunc func, gpointer data, GDestroyNotify destroy); G_END_DECLS #endif /* __GST_GL_CONTEXT_EAGL_H__ */ diff --git a/gst-libs/gst/gl/eagl/gstglcontext_eagl.m b/gst-libs/gst/gl/eagl/gstglcontext_eagl.m index 42dde56cf4..293a80d9c6 100644 --- a/gst-libs/gst/gl/eagl/gstglcontext_eagl.m +++ b/gst-libs/gst/gl/eagl/gstglcontext_eagl.m @@ -31,6 +31,7 @@ #define GST_CAT_DEFAULT gst_gl_context_debug +static void gst_gl_context_eagl_finalize (GObject * object); static gboolean gst_gl_context_eagl_create_context (GstGLContext * context, GstGLAPI gl_api, GstGLContext * other_context, GError ** error); static void gst_gl_context_eagl_destroy_context (GstGLContext * context); @@ -53,6 +54,7 @@ struct _GstGLContextEaglPrivate GLuint framebuffer; GLuint color_renderbuffer; GLuint depth_renderbuffer; + GRecMutex current_lock; }; #define GST_GL_CONTEXT_EAGL_GET_PRIVATE(o) \ @@ -63,12 +65,13 @@ G_DEFINE_TYPE (GstGLContextEagl, gst_gl_context_eagl, GST_GL_TYPE_CONTEXT); static void gst_gl_context_eagl_class_init (GstGLContextEaglClass * klass) { - GstGLContextClass *context_class; - - context_class = (GstGLContextClass *) klass; + GObjectClass *gobject_class = (GObjectClass *) klass; + GstGLContextClass *context_class = (GstGLContextClass *) klass; g_type_class_add_private (klass, sizeof (GstGLContextEaglPrivate)); + gobject_class->finalize = gst_gl_context_eagl_finalize; + context_class->destroy_context = GST_DEBUG_FUNCPTR (gst_gl_context_eagl_destroy_context); context_class->create_context = @@ -90,6 +93,14 @@ static void gst_gl_context_eagl_init (GstGLContextEagl * context) { context->priv = GST_GL_CONTEXT_EAGL_GET_PRIVATE (context); + g_rec_mutex_init (&context->priv->current_lock); +} + +static void +gst_gl_context_eagl_finalize (GObject * object) +{ + g_rec_mutex_clear (&GST_GL_CONTEXT_EAGL (object)->priv->current_lock); + G_OBJECT_CLASS (gst_gl_context_eagl_parent_class)->finalize (object); } /* Must be called in the gl thread */ @@ -363,6 +374,20 @@ gst_gl_context_eagl_activate (GstGLContext * context, gboolean activate) return TRUE; } +void +_gst_gl_context_eagl_invoke (GstGLContext * context, + GstGLContextEaglInvokeFunc func, gpointer data, GDestroyNotify destroy) +{ + GstGLContextEagl *context_eagl = (GstGLContextEagl *) context; + + g_rec_mutex_lock (&context_eagl->priv->current_lock); + gst_gl_context_activate (context, TRUE); + func (data); + if (destroy) + destroy (data); + g_rec_mutex_unlock (&context_eagl->priv->current_lock); +} + static GstGLAPI gst_gl_context_eagl_get_gl_api (GstGLContext * context) { diff --git a/gst-libs/gst/gl/eagl/gstglwindow_eagl.m b/gst-libs/gst/gl/eagl/gstglwindow_eagl.m index eb9d4f7f4a..c90a3816d1 100644 --- a/gst-libs/gst/gl/eagl/gstglwindow_eagl.m +++ b/gst-libs/gst/gl/eagl/gstglwindow_eagl.m @@ -48,6 +48,10 @@ static void gst_gl_window_eagl_set_window_handle (GstGLWindow * window, static void gst_gl_window_eagl_set_preferred_size (GstGLWindow * window, gint width, gint height); static void gst_gl_window_eagl_draw (GstGLWindow * window); +static void gst_gl_window_eagl_send_message_async (GstGLWindow * window, + GstGLWindowCB callback, gpointer data, GDestroyNotify destroy); +static void gst_gl_window_eagl_send_message (GstGLWindow * window, + GstGLWindowCB callback, gpointer data); struct _GstGLWindowEaglPrivate { @@ -72,6 +76,10 @@ gst_gl_window_eagl_class_init (GstGLWindowEaglClass * klass) window_class->draw = GST_DEBUG_FUNCPTR (gst_gl_window_eagl_draw); window_class->set_preferred_size = GST_DEBUG_FUNCPTR (gst_gl_window_eagl_set_preferred_size); + window_class->send_message_async = + GST_DEBUG_FUNCPTR (gst_gl_window_eagl_send_message_async); + window_class->send_message = + GST_DEBUG_FUNCPTR (gst_gl_window_eagl_send_message); } static void @@ -125,6 +133,25 @@ gst_gl_window_eagl_set_preferred_size (GstGLWindow * window, gint width, gint he window_eagl->priv->preferred_width = width; window_eagl->priv->preferred_height = height; } + +static void +gst_gl_window_eagl_send_message_async (GstGLWindow * window, + GstGLWindowCB callback, gpointer data, GDestroyNotify destroy) +{ + GstGLContext *context = gst_gl_window_get_context (window); + _gst_gl_context_eagl_invoke (context, callback, data, destroy); + gst_object_unref (context); +} + +static void +gst_gl_window_eagl_send_message (GstGLWindow * window, + GstGLWindowCB callback, gpointer data) +{ + GstGLContext *context = gst_gl_window_get_context (window); + _gst_gl_context_eagl_invoke (context, callback, data, NULL); + gst_object_unref (context); +} + static void draw_cb (gpointer data)