[818/906] window: add send_message_async vmethod

- provide a default synchronous send_message
- make context creation threadsafe again
This commit is contained in:
Matthew Waters 2013-09-25 12:26:57 +10:00
parent 225d372847
commit db1c7a242b
11 changed files with 308 additions and 248 deletions

View file

@ -48,8 +48,8 @@ static void gst_gl_window_android_egl_draw (GstGLWindow * window, guint width,
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);
@ -68,8 +68,8 @@ gst_gl_window_android_egl_class_init (GstGLWindowAndroidEGLClass * klass)
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);
}
@ -150,51 +150,41 @@ gst_gl_window_android_egl_quit (GstGLWindow * window, GstGLWindowCB callback,
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);
message->callback = callback;
message->data = data;
message->destroy = destroy;
g_main_context_invoke (window_egl->main_context, (GSourceFunc) _run_message,
&message);
g_mutex_lock (&message.lock);
while (!message.fired)
g_cond_wait (&message.cond, &message.lock);
g_mutex_unlock (&message.lock);
message);
}
static void

View file

@ -54,6 +54,7 @@ struct _GstGLContextCocoaPrivate
NSOpenGLContext *gl_context;
NSOpenGLContext *external_gl_context;
NSRect rect;
gint source_id;
};

View file

@ -29,6 +29,7 @@
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);
@ -38,6 +39,30 @@ 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)
{
@ -51,6 +76,8 @@ 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 =
@ -193,6 +220,11 @@ gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
return TRUE;
}
static void
gst_gl_context_cocoa_destroy_context (GstGLContext *context)
{
}
static guintptr
gst_gl_context_cocoa_get_gl_context (GstGLContext * context)
{

View file

@ -75,8 +75,8 @@ static void gst_gl_window_cocoa_set_window_handle (GstGLWindow * window,
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
{
@ -85,31 +85,8 @@ 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)
{
@ -131,8 +108,8 @@ 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];
@ -201,21 +178,22 @@ gst_gl_window_cocoa_set_window_handle (GstGLWindow * window, guintptr handle)
priv->parent = (NSWindow*) handle;
if (priv->internal_win_id) {
g_source_remove (priv->source_id);
GstGLContextCocoa *context = (GstGLContextCocoa *) gst_gl_window_get_context (window);
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
AppThreadPerformer* app_thread_performer = [[AppThreadPerformer alloc] init:window_cocoa];
if (GSRegisterCurrentThread()) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
AppThreadPerformer* app_thread_performer = [[AppThreadPerformer alloc] init:window_cocoa];
[app_thread_performer performSelectorOnMainThread:@selector(setWindow)
withObject:0 waitUntilDone:YES];
GSRegisterCurrentThread();
[pool release];
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];
}
}
@ -225,56 +203,54 @@ gst_gl_window_cocoa_draw (GstGLWindow * window, guint width, guint height)
{
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;
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);
NSRect mainRect = [[NSScreen mainScreen] visibleFrame];
NSRect windowRect = [priv->internal_win_id frame];
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 ("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 ("window rect: %d %d %d %d\n", (int) windowRect.origin.x, (int) windowRect.origin.y,
(int) windowRect.size.width, (int) windowRect.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;
x += 20;
y += 20;
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;
#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
@ -283,23 +259,19 @@ gst_gl_window_cocoa_run (GstGLWindow * window)
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;
@ -340,8 +312,8 @@ gst_gl_window_cocoa_quit (GstGLWindow * window)
/* 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;
@ -349,22 +321,18 @@ gst_gl_window_cocoa_send_message (GstGLWindow * window, GstGLWindowCB callback,
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];
}
}
@ -394,9 +362,9 @@ gst_gl_window_cocoa_send_message (GstGLWindow * window, GstGLWindowCB callback,
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) {
@ -596,7 +564,7 @@ gst_gl_window_cocoa_send_message (GstGLWindow * window, GstGLWindowCB callback,
}
- (void) sendToApp {
if (m_cocoa->priv->running && ![m_cocoa->priv->internal_win_id isClosed])
if (m_callback)
m_callback (m_data);
}

View file

@ -43,8 +43,8 @@ static void gst_gl_window_dispmanx_egl_draw (GstGLWindow * window, guint width,
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);
@ -68,8 +68,8 @@ gst_gl_window_dispmanx_egl_class_init (GstGLWindowDispmanxEGLClass * klass)
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 =
@ -180,51 +180,41 @@ gst_gl_window_dispmanx_egl_quit (GstGLWindow * window)
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);
message->callback = callback;
message->data = data;
message->destroy = destroy;
g_main_context_invoke (window_egl->main_context, (GSourceFunc) _run_message,
&message);
g_mutex_lock (&message.lock);
while (!message.fired)
g_cond_wait (&message.cond, &message.lock);
g_mutex_unlock (&message.lock);
message);
}
static guintptr
@ -283,8 +273,8 @@ window_resize (GstGLWindowDispmanxEGL * window_egl, guint width, guint height)
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;

View file

@ -513,6 +513,12 @@ _parse_gl_api (const gchar * apis_s)
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
@ -637,7 +643,10 @@ gst_gl_context_create_thread (GstGLContext * context)
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);

View file

@ -64,6 +64,9 @@ G_DEFINE_ABSTRACT_TYPE (GstGLWindow, gst_gl_window, G_TYPE_OBJECT);
#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;
@ -112,6 +115,8 @@ gst_gl_window_class_init (GstGLWindowClass * klass)
{
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;
}
@ -257,6 +262,55 @@ gst_gl_window_quit (GstGLWindow * window)
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)
@ -266,13 +320,27 @@ gst_gl_window_send_message (GstGLWindow * window, GstGLWindowCB callback,
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:
*

View file

@ -104,6 +104,7 @@ struct _GstGLWindowClass {
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);
@ -131,6 +132,7 @@ void gst_gl_window_draw (GstGLWindow *window, guint width, g
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);

View file

@ -48,8 +48,8 @@ static void gst_gl_window_wayland_egl_draw (GstGLWindow * window, guint width,
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);
@ -258,8 +258,8 @@ gst_gl_window_wayland_egl_class_init (GstGLWindowWaylandEGLClass * klass)
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 =
@ -379,51 +379,41 @@ gst_gl_window_wayland_egl_quit (GstGLWindow * window)
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);
message->callback = callback;
message->data = data;
message->destroy = destroy;
g_main_context_invoke (window_egl->main_context, (GSourceFunc) _run_message,
&message);
g_mutex_lock (&message.lock);
while (!message.fired)
g_cond_wait (&message.cond, &message.lock);
g_mutex_unlock (&message.lock);
message);
}
static guintptr

View file

@ -62,8 +62,8 @@ static void gst_gl_window_win32_draw (GstGLWindow * window, guint width,
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)
@ -78,8 +78,8 @@ 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);
}
@ -330,19 +330,47 @@ gst_gl_window_win32_quit (GstGLWindow * window)
}
}
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));
}
}
@ -449,8 +477,8 @@ window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
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;
}

View file

@ -66,8 +66,8 @@ void gst_gl_window_x11_draw_unlocked (GstGLWindow * window, guint width,
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);
@ -153,8 +153,8 @@ gst_gl_window_x11_class_init (GstGLWindowX11Class * klass)
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);
}
@ -397,7 +397,7 @@ gst_gl_window_x11_activate (GstGLWindow * window, gboolean activate)
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;
@ -541,32 +541,6 @@ gst_gl_window_x11_draw (GstGLWindow * window, guint width, guint height)
}
}
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)
{
@ -726,35 +700,43 @@ gst_gl_window_x11_quit (GstGLWindow * window)
GST_LOG ("quit sent");
}
/* Not called by the gl thread */
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;
}
void
gst_gl_window_x11_send_message (GstGLWindow * window, GstGLWindowCB callback,
gpointer data)
gst_gl_window_x11_send_message_async (GstGLWindow * window,
GstGLWindowCB callback, gpointer data, GDestroyNotify destroy)
{
GstGLWindowX11 *window_x11;
GstGLMessage *message;
window_x11 = GST_GL_WINDOW_X11 (window);
message = g_slice_new (GstGLMessage);
if (g_main_loop_is_running (window_x11->loop)) {
GstGLMessage message;
message->callback = callback;
message->data = data;
message->destroy = destroy;
message.window = window;
message.callback = callback;
message.data = data;
message.fired = FALSE;
g_mutex_init (&message.lock);
g_cond_init (&message.cond);
g_main_context_invoke (window_x11->main_context, (GSourceFunc) _run_message,
&message);
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_main_context_invoke (window_x11->main_context, (GSourceFunc) _run_message,
message);
}
static int