mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-10 01:54:11 +00:00
[818/906] window: add send_message_async vmethod
- provide a default synchronous send_message - make context creation threadsafe again
This commit is contained in:
parent
225d372847
commit
db1c7a242b
11 changed files with 308 additions and 248 deletions
|
@ -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
|
||||
|
|
|
@ -54,6 +54,7 @@ struct _GstGLContextCocoaPrivate
|
|||
NSOpenGLContext *gl_context;
|
||||
NSOpenGLContext *external_gl_context;
|
||||
NSRect rect;
|
||||
gint source_id;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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:
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue