gl/cocoa: ensure to call NSApplication:sharedApplication in the main thread

"(NSApplication *)sharedApplication This method also makes a connection
to the window server and completes other initialization"
The implicit thing which is not mentioned is that it required
to be called in the main thread.

Fix a regression introduces by 82b7c915bb
When using with gst-launch, it was not possible to click on the close
cross of the window anymore which is a bit anoying and also because
it's was possible before.

Prior to this commit the GstGLContextCocoaClass was initialized
in the main thread because gst_gl_context_new was called in the
state change function from going from ready to paused.

From this commit this call is done from the streaming thread.
So that the call to [NSApplication sharedApplication];
was not done in the main thread anymore.

We now ensure that by assuming there is a GMainLoop running.
It's for debugging purpose so that's ok to do that. Also
note we already do this assumtion to run app itereations.

The regression had no consequence on the cocoa/videooverlay example
(that should be moved from gst-plugins-gl to -bad) because the
application is responsible for that necessary call.
This commit is contained in:
Julien Isorce 2014-04-12 12:42:40 +01:00
parent 995db85435
commit 3c49f0f42a
2 changed files with 86 additions and 16 deletions

View file

@ -41,6 +41,40 @@ static GstGLPlatform gst_gl_context_cocoa_get_gl_platform (GstGLContext * contex
G_DEFINE_TYPE (GstGLContextCocoa, gst_gl_context_cocoa, GST_GL_TYPE_CONTEXT);
#ifndef GNUSTEP
static GMutex nsapp_lock;
static GCond nsapp_cond;
static gboolean
gst_gl_window_cocoa_init_nsapp (gpointer data)
{
NSAutoreleasePool *pool = nil;
g_mutex_lock (&nsapp_lock);
[[NSAutoreleasePool alloc] init];
/* The sharedApplication class method initializes
* the display environment and connects your program
* to the window server and the display server
*/
/* TODO: so consider to create GstGLDisplayCocoa
* in gst/gl/cocoa/gstgldisplay_cocoa.h/c
*/
/* has to be called in the main thread */
[NSApplication sharedApplication];
GST_DEBUG ("NSApp initialized from a GTimeoutSource");
[pool release];
g_cond_signal (&nsapp_cond);
g_mutex_unlock (&nsapp_lock);
return FALSE;
}
static gboolean
gst_gl_window_cocoa_nsapp_iteration (gpointer data)
{
@ -67,14 +101,12 @@ gst_gl_window_cocoa_nsapp_iteration (gpointer data)
static void
gst_gl_context_cocoa_class_init (GstGLContextCocoaClass * klass)
{
GstGLContextClass *context_class;
GstGLContextClass *context_class = (GstGLContextClass *) klass;
#ifndef GNUSTEP
NSAutoreleasePool* pool = nil;
#endif
context_class = (GstGLContextClass *) klass;
g_type_class_add_private (klass, sizeof (GstGLContextCocoaPrivate));
context_class->destroy_context =
@ -90,8 +122,57 @@ gst_gl_context_cocoa_class_init (GstGLContextCocoaClass * klass)
GST_DEBUG_FUNCPTR (gst_gl_context_cocoa_get_gl_platform);
#ifndef GNUSTEP
pool = [[NSAutoreleasePool alloc] init];
[NSApplication sharedApplication];
[[NSAutoreleasePool alloc] init];
/* [NSApplication sharedApplication] will usually be
* called in your application so it's not necessary
* to do that the following. Except for debugging
* purpose like when using gst-launch.
* So here we handle the two cases where the first
* GstGLContext is either created in the main thread
* or from another thread like a streaming thread
*/
if ([NSThread isMainThread]) {
/* In the main thread so just do the call now */
/* The sharedApplication class method initializes
* the display environment and connects your program
* to the window server and the display server
*/
/* TODO: so consider to create GstGLDisplayCocoa
* in gst/gl/cocoa/gstgldisplay_cocoa.h/c
*/
/* has to be called in the main thread */
[NSApplication sharedApplication];
GST_DEBUG ("NSApp initialized");
} else {
/* Not in the main thread, assume there is a
* glib main loop running this is for debugging
* purposes so that's ok to let us a chance
*/
gboolean is_loop_running = FALSE;
gint64 end_time = 0;
g_mutex_init (&nsapp_lock);
g_cond_init (&nsapp_cond);
g_mutex_lock (&nsapp_lock);
g_timeout_add_seconds (0, gst_gl_window_cocoa_init_nsapp, NULL);
end_time = g_get_monotonic_time () + 2 * 1000 * 1000;
is_loop_running = g_cond_wait_until (&nsapp_cond, &nsapp_lock, end_time);
g_mutex_unlock (&nsapp_lock);
if (!is_loop_running) {
GST_WARNING ("no mainloop running");
}
g_cond_clear (&nsapp_cond);
g_mutex_clear (&nsapp_lock);
}
[pool release];
#endif

View file

@ -91,10 +91,6 @@ static void
gst_gl_window_cocoa_class_init (GstGLWindowCocoaClass * klass)
{
GstGLWindowClass *window_class;
#ifndef GNUSTEP
NSAutoreleasePool* pool = nil;
#endif
window_class = (GstGLWindowClass *) klass;
@ -110,13 +106,6 @@ gst_gl_window_cocoa_class_init (GstGLWindowCocoaClass * klass)
window_class->quit = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_quit);
window_class->send_message_async =
GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_send_message_async);
#ifndef GNUSTEP
pool = [[NSAutoreleasePool alloc] init];
[NSApplication sharedApplication];
[pool release];
#endif
}
static void