summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2014-09-26 14:21:46 +0300
committerSebastian Dröge <sebastian@centricular.com>2014-10-14 10:00:53 +0200
commitad4f17075bf4ff32933eb83a8ab33e275bcff34e (patch)
treea41ed6639ef6014be7cd586543f392a8a70c46d0
parent2825929d1c1f6dcfd91629523c870bfeb1bb7661 (diff)
downloadgstreamer-plugins-bad-ad4f17075bf4ff32933eb83a8ab33e275bcff34e.tar.gz
gl/cocoa: Call UI related API from the application main thread
-rw-r--r--gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m113
-rw-r--r--gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m113
2 files changed, 108 insertions, 118 deletions
diff --git a/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m b/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m
index e83b33de2..131e06e72 100644
--- a/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m
+++ b/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m
@@ -85,7 +85,7 @@ gst_gl_window_cocoa_nsapp_iteration (gpointer data)
if ([NSThread isMainThread]) {
while ((event = ([NSApp nextEventMatchingMask:NSAnyEventMask
- untilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]
+ untilDate:[NSDate dateWithTimeIntervalSinceNow:0.05]
inMode:NSDefaultRunLoopMode dequeue:YES])) != nil) {
[NSApp sendEvent:event];
@@ -135,7 +135,7 @@ gst_gl_context_cocoa_class_init (GstGLContextCocoaClass * klass)
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
@@ -201,17 +201,11 @@ gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
GstGLContextCocoaPrivate *priv = context_cocoa->priv;
GstGLWindow *window = gst_gl_context_get_window (context);
GstGLWindowCocoa *window_cocoa = GST_GL_WINDOW_COCOA (window);
- GstGLNSView *glView = nil;
- NSWindow *window_handle;
- NSRect rect;
- NSAutoreleasePool *pool;
- NSOpenGLPixelFormat *fmt = nil;
- NSOpenGLContext *glContext = nil;
- NSOpenGLPixelFormatAttribute attribs[] = {
- NSOpenGLPFADoubleBuffer,
- NSOpenGLPFAAccumSize, 32,
- 0
- };
+ __block NSOpenGLContext *glContext = nil;
+
+#ifndef GNUSTEP
+ priv->source_id = g_timeout_add (200, gst_gl_window_cocoa_nsapp_iteration, NULL);
+#endif
priv->gl_context = nil;
if (other_context)
@@ -219,52 +213,64 @@ gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
else
priv->external_gl_context = NULL;
-#ifdef GNUSTEP
- GSRegisterCurrentThread();
-#endif
+ dispatch_sync (dispatch_get_main_queue (), ^{
+ NSAutoreleasePool *pool;
+ NSOpenGLPixelFormat *fmt = nil;
+ GstGLNSView *glView = nil;
+ NSOpenGLPixelFormatAttribute attribs[] = {
+ NSOpenGLPFADoubleBuffer,
+ NSOpenGLPFAAccumSize, 32,
+ 0
+ };
+ NSRect rect;
+ NSWindow *window_handle;
- pool = [[NSAutoreleasePool alloc] init];
+ pool = [[NSAutoreleasePool alloc] init];
#ifdef GNUSTEP
- [NSApplication sharedApplication];
+ [NSApplication sharedApplication];
#endif
+ rect.origin.x = 0;
+ rect.origin.y = 0;
+ rect.size.width = 320;
+ rect.size.height = 240;
+
+ gst_gl_window_cocoa_create_window (window_cocoa, rect);
+ window_handle = (NSWindow *) gst_gl_window_get_window_handle (window);
+
+ fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
+ if (!fmt) {
+ gst_object_unref (window);
+ GST_WARNING ("cannot create NSOpenGLPixelFormat");
+ return;
+ }
- rect.origin.x = 0;
- rect.origin.y = 0;
- rect.size.width = 320;
- rect.size.height = 240;
-
- gst_gl_window_cocoa_create_window (window_cocoa, rect);
- window_handle = (NSWindow *) gst_gl_window_get_window_handle (window);
-
- glView = [GstGLNSView alloc];
-
- fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
-
- if (!fmt) {
- gst_object_unref (window);
- GST_WARNING ("cannot create NSOpenGLPixelFormat");
- return FALSE;
- }
-
- glView = [glView initWithFrame:window_cocoa rect:rect];
+ glView = [[GstGLNSView alloc] initWithFrame:window_cocoa rect:rect];
- [window_handle setContentView:glView];
+ [window_handle setContentView:glView];
#ifndef GNUSTEP
- glContext = [[NSOpenGLContext alloc] initWithFormat:fmt
- shareContext:context_cocoa->priv->external_gl_context];
+ glContext = [[NSOpenGLContext alloc] initWithFormat:fmt
+ shareContext:context_cocoa->priv->external_gl_context];
- GST_DEBUG ("NSOpenGL context created: %"G_GUINTPTR_FORMAT, (guintptr) glContext);
+ GST_DEBUG ("NSOpenGL context created: %"G_GUINTPTR_FORMAT, (guintptr) glContext);
- context_cocoa->priv->gl_context = glContext;
+ context_cocoa->priv->gl_context = glContext;
- [glContext setView:glView];
+ [glContext setView:glView];
#else
- /* FIXME try to make context sharing work in GNUstep */
- context_cocoa->priv->gl_context = glContext;
+ /* FIXME try to make context sharing work in GNUstep */
+ context_cocoa->priv->gl_context = glContext;
#endif
+ [pool release];
+ });
+
+ if (!glContext) {
+ g_source_remove (priv->source_id);
+ priv->source_id = 0;
+ return FALSE;
+ }
/* OpenGL context is made current only one time threre.
* Indeed, all OpenGL calls are made in only one thread,
@@ -290,14 +296,7 @@ gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
}
NS_ENDHANDLER
- GST_DEBUG ("opengl GstGLNSWindow initialized: %d x %d\n",
- (gint) rect.size.width, (gint) rect.size.height);
-
- [pool release];
-
-#ifndef GNUSTEP
- priv->source_id = g_timeout_add_seconds (1, gst_gl_window_cocoa_nsapp_iteration, NULL);
-#endif
+ GST_DEBUG ("opengl GstGLNSWindow initialized");
gst_object_unref (window);
@@ -307,6 +306,14 @@ gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
static void
gst_gl_context_cocoa_destroy_context (GstGLContext *context)
{
+ GstGLContextCocoa *context_cocoa = GST_GL_CONTEXT_COCOA (context);
+ GstGLContextCocoaPrivate *priv = context_cocoa->priv;
+
+ /* FIXME: Need to release context and other things? */
+ if (priv->source_id) {
+ g_source_remove (priv->source_id);
+ priv->source_id = 0;
+ }
}
static guintptr
diff --git a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m
index 706983562..4f6687179 100644
--- a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m
+++ b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m
@@ -123,20 +123,20 @@ gst_gl_window_cocoa_new (void)
return window;
}
+/* Must be called from the main thread */
gboolean
gst_gl_window_cocoa_create_window (GstGLWindowCocoa *window_cocoa, NSRect rect)
{
GstGLWindowCocoaPrivate *priv = window_cocoa->priv;
- /* FIXME: This should probably be done in the application main thread */
priv->internal_win_id = [[GstGLNSWindow alloc] initWithContentRect:rect styleMask:
- (NSTitledWindowMask | NSClosableWindowMask |
- NSResizableWindowMask | NSMiniaturizableWindowMask)
- backing: NSBackingStoreBuffered defer: NO screen: nil gstWin: window_cocoa];
+ (NSTitledWindowMask | NSClosableWindowMask |
+ NSResizableWindowMask | NSMiniaturizableWindowMask)
+ backing: NSBackingStoreBuffered defer: NO screen: nil gstWin: window_cocoa];
- GST_DEBUG ("NSWindow id: %"G_GUINTPTR_FORMAT, (guintptr) priv->internal_win_id);
+ GST_DEBUG ("NSWindow id: %"G_GUINTPTR_FORMAT, (guintptr) priv->internal_win_id);
- [NSApp setDelegate: priv->internal_win_id];
+ [NSApp setDelegate: priv->internal_win_id];
return TRUE;
}
@@ -176,21 +176,6 @@ gst_gl_window_cocoa_get_window_handle (GstGLWindow *window)
}
static void
-set_window_handle_cb (gpointer data)
-{
- GstGLWindowCocoa * window_cocoa = data;
- NSView *view = [window_cocoa->priv->internal_win_id contentView];
-
- /* FIXME: This should probably be in the application main thread! */
- [window_cocoa->priv->internal_win_id orderOut:window_cocoa->priv->internal_win_id];
-
- [window_cocoa->priv->external_view addSubview: view];
-
- [view setFrame: [window_cocoa->priv->external_view bounds]];
- [view setAutoresizingMask: NSViewWidthSizable|NSViewHeightSizable];
-}
-
-static void
gst_gl_window_cocoa_set_window_handle (GstGLWindow * window, guintptr handle)
{
GstGLWindowCocoa *window_cocoa;
@@ -200,16 +185,6 @@ gst_gl_window_cocoa_set_window_handle (GstGLWindow * window, guintptr handle)
priv = window_cocoa->priv;
if (priv->internal_win_id) {
- GstGLContextCocoa *context = (GstGLContextCocoa *) gst_gl_window_get_context (window);
-
- if (context) {
- if (context->priv->source_id) {
- g_source_remove (context->priv->source_id);
- context->priv->source_id = 0;
- }
- gst_object_unref (context);
- }
-
if (handle) {
priv->external_view = (NSView *) handle;
priv->visible = TRUE;
@@ -220,7 +195,15 @@ gst_gl_window_cocoa_set_window_handle (GstGLWindow * window, guintptr handle)
}
- gst_gl_window_send_message (window, (GstGLWindowCB) set_window_handle_cb, window_cocoa);
+ dispatch_async (dispatch_get_main_queue (), ^{
+ NSView *view = [window_cocoa->priv->internal_win_id contentView];
+ [window_cocoa->priv->internal_win_id orderOut:window_cocoa->priv->internal_win_id];
+
+ [window_cocoa->priv->external_view addSubview: view];
+
+ [view setFrame: [window_cocoa->priv->external_view bounds]];
+ [view setAutoresizingMask: NSViewWidthSizable|NSViewHeightSizable];
+ });
} else {
/* no internal window yet so delay it to the next drawing */
priv->external_view = (NSView*) handle;
@@ -250,39 +233,38 @@ draw_cb (gpointer data)
}
if (!priv->external_view && !priv->visible) {
- gint x = 0;
- gint y = 0;
+ dispatch_sync (dispatch_get_main_queue (), ^{
+ NSRect mainRect = [[NSScreen mainScreen] visibleFrame];
+ NSRect windowRect = [priv->internal_win_id frame];
+ gint x = 0;
+ gint y = 0;
- /* FIXME: This should probably be done from the application main thread */
+ 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 = draw_data->width;
+ windowRect.size.height = draw_data->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 = draw_data->width;
- windowRect.size.height = draw_data->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
- [priv->internal_win_id orderFrontRegardless];
+ [priv->internal_win_id orderFrontRegardless];
- /*[priv->internal_win_id setViewsNeedDisplay:YES]; */
+ [priv->internal_win_id setViewsNeedDisplay:YES];
+ });
priv->visible = TRUE;
}
@@ -383,6 +365,7 @@ gst_gl_window_cocoa_send_message_async (GstGLWindow * window,
/* */
/* =============================================================*/
+/* Must be called from the main thread */
@implementation GstGLNSWindow
- (id) initWithContentRect: (NSRect) contentRect
@@ -446,7 +429,6 @@ close_window_cb (gpointer data)
window = GST_GL_WINDOW (window_cocoa);
- [window_cocoa->priv->internal_win_id setClosed];
if (window->close) {
window->close (window->close_data);
}
@@ -456,7 +438,8 @@ close_window_cb (gpointer data)
- (BOOL) windowShouldClose:(id)sender {
GST_DEBUG ("user clicked the close button\n");
- gst_gl_window_send_message (GST_GL_WINDOW (window_cocoa), (GstGLWindowCB) close_window_cb, window_cocoa);
+ [window_cocoa->priv->internal_win_id setClosed];
+ gst_gl_window_send_message_async (GST_GL_WINDOW (window_cocoa), (GstGLWindowCB) close_window_cb, gst_object_ref (window_cocoa), (GDestroyNotify) gst_object_unref);
return YES;
}
@@ -496,9 +479,9 @@ close_window_cb (gpointer data)
@implementation GstGLNSView
+/* Must be called from the application main thread */
- (id)initWithFrame:(GstGLWindowCocoa *)window rect:(NSRect)contentRect {
- /* FIXME: This should probably be done from the application main thread */
self = [super initWithFrame: contentRect];
window_cocoa = window;
@@ -556,7 +539,7 @@ resize_cb (gpointer data)
NSRect bounds = [self bounds];
NSRect visibleRect = [self visibleRect];
NSSize frameSize = [self frame].size;
- struct resize resize_data;
+ struct resize *resize_data = g_new (struct resize, 1);
GST_DEBUG_OBJECT (window, "Window resized: bounds %lf %lf %lf %lf, "
"visibleRect %lf %lf %lf %lf, frame size %lf %lf",
@@ -566,12 +549,12 @@ resize_cb (gpointer data)
visibleRect.size.width, visibleRect.size.height,
frameSize.width, frameSize.height);
- resize_data.window = window_cocoa;
- resize_data.bounds = bounds;
- resize_data.visibleRect = visibleRect;
- resize_data.frameSize = frameSize;
+ resize_data->window = window_cocoa;
+ resize_data->bounds = bounds;
+ resize_data->visibleRect = visibleRect;
+ resize_data->frameSize = frameSize;
- gst_gl_window_send_message (GST_GL_WINDOW (window_cocoa), (GstGLWindowCB) resize_cb, &resize_data);
+ gst_gl_window_send_message_async (GST_GL_WINDOW (window_cocoa), (GstGLWindowCB) resize_cb, resize_data, (GDestroyNotify) g_free);
}
}