static void gst_gl_window_android_egl_run (GstGLWindow * window);
static void gst_gl_window_android_egl_quit (GstGLWindow * window,
GstGLWindowCB callback, gpointer data);
-static void gst_gl_window_android_egl_send_message (GstGLWindow * window,
- GstGLWindowCB callback, gpointer data);
+static void gst_gl_window_android_egl_send_message_async (GstGLWindow * window,
+ GstGLWindowCB callback, gpointer data, GDestroyNotify destroy);
static gboolean gst_gl_window_android_egl_open (GstGLWindow * window,
GError ** error);
static void gst_gl_window_android_egl_close (GstGLWindow * window);
window_class->draw = GST_DEBUG_FUNCPTR (gst_gl_window_android_egl_draw);
window_class->run = GST_DEBUG_FUNCPTR (gst_gl_window_android_egl_run);
window_class->quit = GST_DEBUG_FUNCPTR (gst_gl_window_android_egl_quit);
- window_class->send_message =
- GST_DEBUG_FUNCPTR (gst_gl_window_android_egl_send_message);
+ window_class->send_message_async =
+ GST_DEBUG_FUNCPTR (gst_gl_window_android_egl_send_message_async);
window_class->open = GST_DEBUG_FUNCPTR (gst_gl_window_android_egl_open);
window_class->close = GST_DEBUG_FUNCPTR (gst_gl_window_android_egl_close);
}
typedef struct _GstGLMessage
{
- GMutex lock;
- GCond cond;
- gboolean fired;
-
GstGLWindowCB callback;
gpointer data;
+ GDestroyNotify destroy;
} GstGLMessage;
static gboolean
_run_message (GstGLMessage * message)
{
- g_mutex_lock (&message->lock);
-
if (message->callback)
message->callback (message->data);
- message->fired = TRUE;
- g_cond_signal (&message->cond);
- g_mutex_unlock (&message->lock);
+ if (message->destroy)
+ message->destroy (message->data);
+
+ g_slice_free (GstGLMessage, message);
return FALSE;
}
static void
-gst_gl_window_android_egl_send_message (GstGLWindow * window,
- GstGLWindowCB callback, gpointer data)
+gst_gl_window_android_egl_send_message_async (GstGLWindow * window,
+ GstGLWindowCB callback, gpointer data, GDestroyNotify destroy)
{
GstGLWindowAndroidEGL *window_egl;
- GstGLMessage message;
+ GstGLMessage *message;
window_egl = GST_GL_WINDOW_ANDROID_EGL (window);
- message.callback = callback;
- message.data = data;
- message.fired = FALSE;
- g_mutex_init (&message.lock);
- g_cond_init (&message.cond);
+ message = g_slice_new (GstGLMessage);
- g_main_context_invoke (window_egl->main_context, (GSourceFunc) _run_message,
- &message);
-
- g_mutex_lock (&message.lock);
+ message->callback = callback;
+ message->data = data;
+ message->destroy = destroy;
- while (!message.fired)
- g_cond_wait (&message.cond, &message.lock);
- g_mutex_unlock (&message.lock);
+ g_main_context_invoke (window_egl->main_context, (GSourceFunc) _run_message,
+ message);
}
static void
NSOpenGLContext *gl_context;
NSOpenGLContext *external_gl_context;
NSRect rect;
+ gint source_id;
};
static gboolean gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
GstGLContext * other_context, GError **error);
+static void gst_gl_context_cocoa_destroy_context (GstGLContext *context);
static guintptr gst_gl_context_cocoa_get_gl_context (GstGLContext * window);
static gboolean gst_gl_context_cocoa_activate (GstGLContext * context, gboolean activate);
static GstGLAPI gst_gl_context_cocoa_get_gl_api (GstGLContext * context);
G_DEFINE_TYPE (GstGLContextCocoa, gst_gl_context_cocoa, GST_GL_TYPE_CONTEXT);
+#ifndef GNUSTEP
+static gboolean
+gst_gl_window_cocoa_nsapp_iteration (gpointer data)
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ NSEvent *event = nil;
+
+ if ([NSThread isMainThread]) {
+
+ while ((event = ([NSApp nextEventMatchingMask:NSAnyEventMask
+ untilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]
+ inMode:NSDefaultRunLoopMode dequeue:YES])) != nil) {
+
+ [NSApp sendEvent:event];
+ }
+ }
+
+ [pool release];
+
+ return TRUE;
+}
+#endif
+
static void
gst_gl_context_cocoa_class_init (GstGLContextCocoaClass * klass)
{
g_type_class_add_private (klass, sizeof (GstGLContextCocoaPrivate));
+ context_class->destroy_context =
+ GST_DEBUG_FUNCPTR (gst_gl_context_cocoa_destroy_context);
context_class->create_context =
GST_DEBUG_FUNCPTR (gst_gl_context_cocoa_create_context);
context_class->get_gl_context =
return TRUE;
}
+static void
+gst_gl_context_cocoa_destroy_context (GstGLContext *context)
+{
+}
+
static guintptr
gst_gl_context_cocoa_get_gl_context (GstGLContext * context)
{
static void gst_gl_window_cocoa_draw (GstGLWindow * window, guint width, guint height);
static void gst_gl_window_cocoa_run (GstGLWindow * window);
static void gst_gl_window_cocoa_quit (GstGLWindow * window);
-static void gst_gl_window_cocoa_send_message (GstGLWindow * window,
- GstGLWindowCB callback, gpointer data);
+static void gst_gl_window_cocoa_send_message_async (GstGLWindow * window,
+ GstGLWindowCB callback, gpointer data, GDestroyNotify destroy);
struct _GstGLWindowCocoaPrivate
{
NSWindow *parent;
NSThread *thread;
gboolean running;
- guint source_id;
};
-gboolean
-gst_gl_window_cocoa_nsapp_iteration (gpointer data)
-{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
- NSEvent *event = nil;
-
- if ([NSThread isMainThread]) {
-
- while ((event = ([NSApp nextEventMatchingMask:NSAnyEventMask
- untilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]
- inMode:NSDefaultRunLoopMode dequeue:YES])) != nil) {
-
- [NSApp sendEvent:event];
- }
- }
-
- [pool release];
-
- return TRUE;
-}
-
static void
gst_gl_window_cocoa_class_init (GstGLWindowCocoaClass * klass)
{
window_class->draw = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_draw);
window_class->run = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_run);
window_class->quit = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_quit);
- window_class->send_message =
- GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_send_message);
+ window_class->send_message_async =
+ GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_send_message_async);
#ifndef GNUSTEP
pool = [[NSAutoreleasePool alloc] init];
priv->parent = (NSWindow*) handle;
if (priv->internal_win_id) {
- g_source_remove (priv->source_id);
-
- if (GSRegisterCurrentThread()) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ GstGLContextCocoa *context = (GstGLContextCocoa *) gst_gl_window_get_context (window);
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ AppThreadPerformer* app_thread_performer = [[AppThreadPerformer alloc] init:window_cocoa];
- AppThreadPerformer* app_thread_performer = [[AppThreadPerformer alloc] init:window_cocoa];
- [app_thread_performer performSelectorOnMainThread:@selector(setWindow)
- withObject:0 waitUntilDone:YES];
- [pool release];
+ GSRegisterCurrentThread();
- GSUnregisterCurrentThread();
- } else {
- GST_DEBUG ("failed to register current thread, cannot set external window id\n");
+ if (context) {
+ g_source_remove (context->priv->source_id);
+ gst_object_unref (context);
}
+
+ [app_thread_performer performSelectorOnMainThread:@selector(setWindow)
+ withObject:0 waitUntilDone:YES];
+
+ [pool release];
}
}
{
GstGLWindowCocoa *window_cocoa;
GstGLWindowCocoaPrivate *priv;
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ AppThreadPerformer* app_thread_performer;
window_cocoa = GST_GL_WINDOW_COCOA (window);
priv = window_cocoa->priv;
- if (GSRegisterCurrentThread()) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ GSRegisterCurrentThread();
- AppThreadPerformer* app_thread_performer = [[AppThreadPerformer alloc] init:window_cocoa];
- [app_thread_performer performSelector:@selector(updateWindow)
+ app_thread_performer = [[AppThreadPerformer alloc] init:window_cocoa];
+ [app_thread_performer performSelector:@selector(updateWindow)
onThread:priv->thread withObject:nil waitUntilDone:YES];
-
- if (!priv->parent && !priv->visible) {
- static gint x = 0;
- static gint y = 0;
- NSRect mainRect = [[NSScreen mainScreen] visibleFrame];
- NSRect windowRect = [priv->internal_win_id frame];
+ if (!priv->parent && !priv->visible) {
+ static gint x = 0;
+ static gint y = 0;
+
+ NSRect mainRect = [[NSScreen mainScreen] visibleFrame];
+ NSRect windowRect = [priv->internal_win_id frame];
- GST_DEBUG ("main screen rect: %d %d %d %d\n", (int) mainRect.origin.x, (int) mainRect.origin.y,
- (int) mainRect.size.width, (int) mainRect.size.height);
+ GST_DEBUG ("main screen rect: %d %d %d %d\n", (int) mainRect.origin.x,
+ (int) mainRect.origin.y, (int) mainRect.size.width,
+ (int) mainRect.size.height);
- windowRect.origin.x += x;
- windowRect.origin.y += mainRect.size.height > y ? (mainRect.size.height - y) * 0.5 : y;
- windowRect.size.width = width;
- windowRect.size.height = height;
+ windowRect.origin.x += x;
+ windowRect.origin.y += mainRect.size.height > y ? (mainRect.size.height - y) * 0.5 : y;
+ windowRect.size.width = width;
+ windowRect.size.height = height;
- GST_DEBUG ("window rect: %d %d %d %d\n", (int) windowRect.origin.x, (int) windowRect.origin.y,
- (int) windowRect.size.width, (int) windowRect.size.height);
+ GST_DEBUG ("window rect: %d %d %d %d\n", (int) windowRect.origin.x,
+ (int) windowRect.origin.y, (int) windowRect.size.width,
+ (int) windowRect.size.height);
- x += 20;
- y += 20;
+ x += 20;
+ y += 20;
#ifndef GNUSTEP
- [priv->internal_win_id setFrame:windowRect display:NO];
- GST_DEBUG ("make the window available\n");
- [priv->internal_win_id makeMainWindow];
+ [priv->internal_win_id setFrame:windowRect display:NO];
+ GST_DEBUG ("make the window available\n");
+ [priv->internal_win_id makeMainWindow];
#endif
- [app_thread_performer performSelector:@selector(orderFront)
- onThread:priv->thread withObject:nil waitUntilDone:YES];
+ [app_thread_performer performSelector:@selector(orderFront)
+ onThread:priv->thread withObject:nil waitUntilDone:YES];
- /*[priv->internal_win_id setViewsNeedDisplay:YES]; */
- priv->visible = TRUE;
- }
-
- [pool release];
-
- GSUnregisterCurrentThread();
+ /*[priv->internal_win_id setViewsNeedDisplay:YES]; */
+ priv->visible = TRUE;
}
- else
- GST_DEBUG ("failed to register current thread, cannot draw\n");
+
+ [pool release];
}
static void
GstGLWindowCocoa *window_cocoa;
GstGLWindowCocoaPrivate *priv;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-#ifndef GNUSTEP
NSRunLoop *run_loop = [NSRunLoop currentRunLoop];
-#endif
window_cocoa = GST_GL_WINDOW_COCOA (window);
priv = window_cocoa->priv;
+ [run_loop addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
+
GST_DEBUG ("begin loop\n");
-
+
if (priv->internal_win_id != nil) {
priv->running = TRUE;
-#ifndef GNUSTEP
while (priv->running)
[run_loop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
-#else
- [NSApp run];
-#endif
[priv->internal_win_id release];
priv->internal_win_id = nil;
/* Thread safe */
static void
-gst_gl_window_cocoa_send_message (GstGLWindow * window, GstGLWindowCB callback,
- gpointer data)
+gst_gl_window_cocoa_send_message_async (GstGLWindow * window,
+ GstGLWindowCB callback, gpointer data, GDestroyNotify destroy)
{
GstGLWindowCocoa *window_cocoa;
GstGLWindowCocoaPrivate *priv;
window_cocoa = GST_GL_WINDOW_COCOA (window);
priv = window_cocoa->priv;
+ GSRegisterCurrentThread ();
+
if (window) {
- if (GSRegisterCurrentThread()) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- AppThreadPerformer* app_thread_performer = [[AppThreadPerformer alloc]
- initWithAll:window_cocoa callback:callback userData:data];
-
- [app_thread_performer performSelector:@selector(sendToApp) onThread:priv->thread
- withObject:nil waitUntilDone:YES];
+ AppThreadPerformer* app_thread_performer = [[AppThreadPerformer alloc]
+ initWithAll:window_cocoa callback:callback userData:data];
- [pool release];
+ [app_thread_performer performSelector:@selector(sendToApp) onThread:priv->thread
+ withObject:nil waitUntilDone:NO];
- GSUnregisterCurrentThread();
- }
- else
- GST_DEBUG ("failed to register current thread, cannot send message\n");
+ [pool release];
}
}
GST_DEBUG ("initializing GstGLNSWindow\n");
[self setTitle:@"OpenGL renderer"];
-
+
[self setBackgroundColor:[NSColor clearColor]];
-
+
[self orderOut:m_cocoa->priv->internal_win_id];
if (m_cocoa->priv->parent) {
}
- (void) sendToApp {
- if (m_cocoa->priv->running && ![m_cocoa->priv->internal_win_id isClosed])
+ if (m_callback)
m_callback (m_data);
}
guint height);
static void gst_gl_window_dispmanx_egl_run (GstGLWindow * window);
static void gst_gl_window_dispmanx_egl_quit (GstGLWindow * window);
-static void gst_gl_window_dispmanx_egl_send_message (GstGLWindow * window,
- GstGLWindowCB callback, gpointer data);
+static void gst_gl_window_dispmanx_egl_send_message_async (GstGLWindow * window,
+ GstGLWindowCB callback, gpointer data, GDestroyNotify destroy);
static void gst_gl_window_dispmanx_egl_close (GstGLWindow * window);
static gboolean gst_gl_window_dispmanx_egl_open (GstGLWindow * window,
GError ** error);
window_class->draw = GST_DEBUG_FUNCPTR (gst_gl_window_dispmanx_egl_draw);
window_class->run = GST_DEBUG_FUNCPTR (gst_gl_window_dispmanx_egl_run);
window_class->quit = GST_DEBUG_FUNCPTR (gst_gl_window_dispmanx_egl_quit);
- window_class->send_message =
- GST_DEBUG_FUNCPTR (gst_gl_window_dispmanx_egl_send_message);
+ window_class->send_message_async =
+ GST_DEBUG_FUNCPTR (gst_gl_window_dispmanx_egl_send_message_async);
window_class->close = GST_DEBUG_FUNCPTR (gst_gl_window_dispmanx_egl_close);
window_class->open = GST_DEBUG_FUNCPTR (gst_gl_window_dispmanx_egl_open);
window_class->get_display =
typedef struct _GstGLMessage
{
- GMutex lock;
- GCond cond;
- gboolean fired;
-
GstGLWindowCB callback;
gpointer data;
+ GDestroyNotify destroy;
} GstGLMessage;
static gboolean
_run_message (GstGLMessage * message)
{
- g_mutex_lock (&message->lock);
-
if (message->callback)
message->callback (message->data);
- message->fired = TRUE;
- g_cond_signal (&message->cond);
- g_mutex_unlock (&message->lock);
+ if (message->destroy)
+ message->destroy (message->data);
+
+ g_slice_free (GstGLMessage, message);
return FALSE;
}
static void
-gst_gl_window_dispmanx_egl_send_message (GstGLWindow * window,
- GstGLWindowCB callback, gpointer data)
+gst_gl_window_dispmanx_egl_send_message_async (GstGLWindow * window,
+ GstGLWindowCB callback, gpointer data, GDestroyNotify destroy)
{
GstGLWindowDispmanxEGL *window_egl;
- GstGLMessage message;
+ GstGLMessage *message;
window_egl = GST_GL_WINDOW_DISPMANX_EGL (window);
- message.callback = callback;
- message.data = data;
- message.fired = FALSE;
- g_mutex_init (&message.lock);
- g_cond_init (&message.cond);
+ message = g_slice_new (GstGLMessage);
- g_main_context_invoke (window_egl->main_context, (GSourceFunc) _run_message,
- &message);
-
- g_mutex_lock (&message.lock);
+ message->callback = callback;
+ message->data = data;
+ message->destroy = destroy;
- while (!message.fired)
- g_cond_wait (&message.cond, &message.lock);
- g_mutex_unlock (&message.lock);
+ g_main_context_invoke (window_egl->main_context, (GSourceFunc) _run_message,
+ message);
}
static guintptr
vc_dispmanx_update_submit_sync (dispman_update);
if (GST_GL_WINDOW (window_egl)->resize)
- GST_GL_WINDOW (window_egl)->
- resize (GST_GL_WINDOW (window_egl)->resize_data, width, height);
+ GST_GL_WINDOW (window_egl)->resize (GST_GL_WINDOW (window_egl)->
+ resize_data, width, height);
}
window_egl->native.width = width;
return ret;
}
+static void
+_unlock_create_thread (GstGLContext * context)
+{
+ g_mutex_unlock (&context->priv->render_lock);
+}
+
//gboolean
//gst_gl_context_create (GstGLContext * context, GstGLContext * other_context, GError ** error)
static gpointer
context->priv->alive = TRUE;
g_cond_signal (&context->priv->create_cond);
- g_mutex_unlock (&context->priv->render_lock);
+
+// g_mutex_unlock (&context->priv->render_lock);
+ gst_gl_window_send_message_async (context->window,
+ (GstGLWindowCB) _unlock_create_thread, context, NULL);
gst_gl_window_run (context->window);
#define GST_GL_WINDOW_GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_WINDOW, GstGLWindowPrivate))
+static void gst_gl_window_default_send_message (GstGLWindow * window,
+ GstGLWindowCB callback, gpointer data);
+
struct _GstGLWindowPrivate
{
GstGLDisplay *display;
{
g_type_class_add_private (klass, sizeof (GstGLWindowPrivate));
+ klass->send_message = GST_DEBUG_FUNCPTR (gst_gl_window_default_send_message);
+
G_OBJECT_CLASS (klass)->finalize = gst_gl_window_finalize;
}
GST_INFO ("quit received from gl window");
}
+typedef struct _GstGLSyncMessage
+{
+ GMutex lock;
+ GCond cond;
+ gboolean fired;
+
+ GstGLWindowCB callback;
+ gpointer data;
+} GstGLSyncMessage;
+
+static void
+_run_message_sync (GstGLSyncMessage * message)
+{
+ g_mutex_lock (&message->lock);
+
+ if (message->callback)
+ message->callback (message->data);
+
+ message->fired = TRUE;
+ g_cond_signal (&message->cond);
+ g_mutex_unlock (&message->lock);
+}
+
+void
+gst_gl_window_default_send_message (GstGLWindow * window,
+ GstGLWindowCB callback, gpointer data)
+{
+ GstGLSyncMessage message;
+
+ message.callback = callback;
+ message.data = data;
+ message.fired = FALSE;
+ g_mutex_init (&message.lock);
+ g_cond_init (&message.cond);
+
+ gst_gl_window_send_message_async (window, (GstGLWindowCB) _run_message_sync,
+ &message, NULL);
+
+ g_mutex_lock (&message.lock);
+
+ /* block until opengl calls have been executed in the gl thread */
+ while (!message.fired)
+ g_cond_wait (&message.cond, &message.lock);
+ g_mutex_unlock (&message.lock);
+
+ g_mutex_clear (&message.lock);
+ g_cond_clear (&message.cond);
+}
+
void
gst_gl_window_send_message (GstGLWindow * window, GstGLWindowCB callback,
gpointer data)
g_return_if_fail (GST_GL_IS_WINDOW (window));
g_return_if_fail (callback != NULL);
window_class = GST_GL_WINDOW_GET_CLASS (window);
- g_return_if_fail (window_class->quit != NULL);
+ g_return_if_fail (window_class->send_message != NULL);
GST_GL_WINDOW_LOCK (window);
window_class->send_message (window, callback, data);
GST_GL_WINDOW_UNLOCK (window);
}
+void
+gst_gl_window_send_message_async (GstGLWindow * window, GstGLWindowCB callback,
+ gpointer data, GDestroyNotify destroy)
+{
+ GstGLWindowClass *window_class;
+
+ g_return_if_fail (GST_GL_IS_WINDOW (window));
+ g_return_if_fail (callback != NULL);
+ window_class = GST_GL_WINDOW_GET_CLASS (window);
+ g_return_if_fail (window_class->send_message_async != NULL);
+
+ window_class->send_message_async (window, callback, data, destroy);
+}
+
/**
* gst_gl_window_set_need_lock:
*
void (*run) (GstGLWindow *window);
void (*quit) (GstGLWindow *window);
void (*send_message) (GstGLWindow *window, GstGLWindowCB callback, gpointer data);
+ void (*send_message_async) (GstGLWindow *window, GstGLWindowCB callback, gpointer data, GDestroyNotify destroy);
gboolean (*open) (GstGLWindow *window, GError **error);
void (*close) (GstGLWindow *window);
void gst_gl_window_run (GstGLWindow *window);
void gst_gl_window_quit (GstGLWindow *window);
void gst_gl_window_send_message (GstGLWindow *window, GstGLWindowCB callback, gpointer data);
+void gst_gl_window_send_message_async (GstGLWindow *window, GstGLWindowCB callback, gpointer data, GDestroyNotify destroy);
guintptr gst_gl_window_get_display (GstGLWindow *window);
GstGLContext * gst_gl_window_get_context (GstGLWindow *window);
guint height);
static void gst_gl_window_wayland_egl_run (GstGLWindow * window);
static void gst_gl_window_wayland_egl_quit (GstGLWindow * window);
-static void gst_gl_window_wayland_egl_send_message (GstGLWindow * window,
- GstGLWindowCB callback, gpointer data);
+static void gst_gl_window_wayland_egl_send_message_async (GstGLWindow * window,
+ GstGLWindowCB callback, gpointer data, GDestroyNotify destroy);
static void gst_gl_window_wayland_egl_close (GstGLWindow * window);
static gboolean gst_gl_window_wayland_egl_open (GstGLWindow * window,
GError ** error);
window_class->draw = GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_draw);
window_class->run = GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_run);
window_class->quit = GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_quit);
- window_class->send_message =
- GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_send_message);
+ window_class->send_message_async =
+ GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_send_message_async);
window_class->close = GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_close);
window_class->open = GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_open);
window_class->get_display =
typedef struct _GstGLMessage
{
- GMutex lock;
- GCond cond;
- gboolean fired;
-
GstGLWindowCB callback;
gpointer data;
+ GDestroyNotify destroy;
} GstGLMessage;
static gboolean
_run_message (GstGLMessage * message)
{
- g_mutex_lock (&message->lock);
-
if (message->callback)
message->callback (message->data);
- message->fired = TRUE;
- g_cond_signal (&message->cond);
- g_mutex_unlock (&message->lock);
+ if (message->destroy)
+ message->destroy (message->data);
+
+ g_slice_free (GstGLMessage, message);
return FALSE;
}
static void
-gst_gl_window_wayland_egl_send_message (GstGLWindow * window,
- GstGLWindowCB callback, gpointer data)
+gst_gl_window_wayland_egl_send_message_async (GstGLWindow * window,
+ GstGLWindowCB callback, gpointer data, GDestroyNotify destroy)
{
GstGLWindowWaylandEGL *window_egl;
- GstGLMessage message;
+ GstGLMessage *message;
window_egl = GST_GL_WINDOW_WAYLAND_EGL (window);
- message.callback = callback;
- message.data = data;
- message.fired = FALSE;
- g_mutex_init (&message.lock);
- g_cond_init (&message.cond);
+ message = g_slice_new (GstGLMessage);
- g_main_context_invoke (window_egl->main_context, (GSourceFunc) _run_message,
- &message);
-
- g_mutex_lock (&message.lock);
+ message->callback = callback;
+ message->data = data;
+ message->destroy = destroy;
- while (!message.fired)
- g_cond_wait (&message.cond, &message.lock);
- g_mutex_unlock (&message.lock);
+ g_main_context_invoke (window_egl->main_context, (GSourceFunc) _run_message,
+ message);
}
static guintptr
guint height);
static void gst_gl_window_win32_run (GstGLWindow * window);
static void gst_gl_window_win32_quit (GstGLWindow * window);
-static void gst_gl_window_win32_send_message (GstGLWindow * window,
- GstGLWindowCB callback, gpointer data);
+static void gst_gl_window_win32_send_message_async (GstGLWindow * window,
+ GstGLWindowCB callback, gpointer data, GDestroyNotify destroy);
static void
gst_gl_window_win32_class_init (GstGLWindowWin32Class * klass)
window_class->draw = GST_DEBUG_FUNCPTR (gst_gl_window_win32_draw);
window_class->run = GST_DEBUG_FUNCPTR (gst_gl_window_win32_run);
window_class->quit = GST_DEBUG_FUNCPTR (gst_gl_window_win32_quit);
- window_class->send_message =
- GST_DEBUG_FUNCPTR (gst_gl_window_win32_send_message);
+ window_class->send_message_async =
+ GST_DEBUG_FUNCPTR (gst_gl_window_win32_send_message_async);
window_class->get_display =
GST_DEBUG_FUNCPTR (gst_gl_window_win32_get_display);
}
}
}
+typedef struct _GstGLMessage
+{
+ GstGLWindowCB callback;
+ gpointer data;
+ GDestroyNotify destroy;
+} GstGLMessage;
+
+static gboolean
+_run_message (GstGLMessage * message)
+{
+ if (message->callback)
+ message->callback (message->data);
+
+ if (message->destroy)
+ message->destroy (message->data);
+
+ g_slice_free (GstGLMessage, message);
+
+ return FALSE;
+}
+
/* Thread safe */
static void
-gst_gl_window_win32_send_message (GstGLWindow * window, GstGLWindowCB callback,
- gpointer data)
+gst_gl_window_win32_send_message_async (GstGLWindow * window,
+ GstGLWindowCB callback, gpointer data, GDestroyNotify destroy)
{
GstGLWindowWin32 *window_win32;
+ GstGLMessage *message;
window_win32 = GST_GL_WINDOW_WIN32 (window);
+ message = g_slice_new (GstGLMessage);
if (window_win32) {
- LRESULT res =
- SendMessage (window_win32->internal_win_id, WM_GST_GL_WINDOW_CUSTOM,
- (WPARAM) data, (LPARAM) callback);
+ LRESULT res;
+
+ message->callback = callback;
+ message->data = data;
+ message->destroy = destroy;
+
+ res = PostMessage (window_win32->internal_win_id, WM_GST_GL_WINDOW_CUSTOM,
+ (WPARAM) message, (LPARAM) NULL);
g_return_if_fail (SUCCEEDED (res));
}
}
case WM_GST_GL_WINDOW_CUSTOM:
{
if (!window_win32->is_closed) {
- GstGLWindowCB custom_cb = (GstGLWindowCB) lParam;
- custom_cb ((gpointer) wParam);
+ GstGLMessage *message = (GstGLMessage *) wParam;
+ _run_message (message);
}
break;
}
void gst_gl_window_x11_draw (GstGLWindow * window, guint width, guint height);
void gst_gl_window_x11_run (GstGLWindow * window);
void gst_gl_window_x11_quit (GstGLWindow * window);
-void gst_gl_window_x11_send_message (GstGLWindow * window,
- GstGLWindowCB callback, gpointer data);
+void gst_gl_window_x11_send_message_async (GstGLWindow * window,
+ GstGLWindowCB callback, gpointer data, GDestroyNotify destroy);
gboolean gst_gl_window_x11_create_context (GstGLWindow * window,
GstGLAPI gl_api, guintptr external_gl_context, GError ** error);
gboolean gst_gl_window_x11_open (GstGLWindow * window, GError ** error);
window_class->draw = GST_DEBUG_FUNCPTR (gst_gl_window_x11_draw);
window_class->run = GST_DEBUG_FUNCPTR (gst_gl_window_x11_run);
window_class->quit = GST_DEBUG_FUNCPTR (gst_gl_window_x11_quit);
- window_class->send_message =
- GST_DEBUG_FUNCPTR (gst_gl_window_x11_send_message);
+ window_class->send_message_async =
+ GST_DEBUG_FUNCPTR (gst_gl_window_x11_send_message_async);
window_class->open = GST_DEBUG_FUNCPTR (gst_gl_window_x11_open);
window_class->close = GST_DEBUG_FUNCPTR (gst_gl_window_x11_close);
}
priv = window_x11->priv;
priv->activate = activate;
- gst_gl_window_x11_send_message (window, GST_GL_WINDOW_CB (callback_activate),
+ gst_gl_window_send_message (window, GST_GL_WINDOW_CB (callback_activate),
window_x11);
return priv->activate_result;
}
}
-typedef struct _GstGLMessage
-{
- GstGLWindow *window;
- GMutex lock;
- GCond cond;
- gboolean fired;
-
- GstGLWindowCB callback;
- gpointer data;
-} GstGLMessage;
-
-static gboolean
-_run_message (GstGLMessage * message)
-{
- g_mutex_lock (&message->lock);
-
- if (message->callback)
- message->callback (message->data);
-
- message->fired = TRUE;
- g_cond_signal (&message->cond);
- g_mutex_unlock (&message->lock);
-
- return FALSE;
-}
-
void
gst_gl_window_x11_run (GstGLWindow * window)
{
GST_LOG ("quit sent");
}
-/* Not called by the gl thread */
-void
-gst_gl_window_x11_send_message (GstGLWindow * window, GstGLWindowCB callback,
- gpointer data)
+typedef struct _GstGLMessage
{
- GstGLWindowX11 *window_x11;
+ GstGLWindowCB callback;
+ gpointer data;
+ GDestroyNotify destroy;
+} GstGLMessage;
- window_x11 = GST_GL_WINDOW_X11 (window);
+static gboolean
+_run_message (GstGLMessage * message)
+{
+ if (message->callback)
+ message->callback (message->data);
- if (g_main_loop_is_running (window_x11->loop)) {
- GstGLMessage message;
+ if (message->destroy)
+ message->destroy (message->data);
+
+ g_slice_free (GstGLMessage, message);
+
+ return FALSE;
+}
- message.window = window;
- message.callback = callback;
- message.data = data;
- message.fired = FALSE;
- g_mutex_init (&message.lock);
- g_cond_init (&message.cond);
+void
+gst_gl_window_x11_send_message_async (GstGLWindow * window,
+ GstGLWindowCB callback, gpointer data, GDestroyNotify destroy)
+{
+ GstGLWindowX11 *window_x11;
+ GstGLMessage *message;
- g_main_context_invoke (window_x11->main_context, (GSourceFunc) _run_message,
- &message);
+ window_x11 = GST_GL_WINDOW_X11 (window);
+ message = g_slice_new (GstGLMessage);
- g_mutex_lock (&message.lock);
+ message->callback = callback;
+ message->data = data;
+ message->destroy = destroy;
- /* block until opengl calls have been executed in the gl thread */
- while (!message.fired)
- g_cond_wait (&message.cond, &message.lock);
- g_mutex_unlock (&message.lock);
- }
+ g_main_context_invoke (window_x11->main_context, (GSourceFunc) _run_message,
+ message);
}
static int