summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2014-09-26 13:05:27 +0300
committerSebastian Dröge <sebastian@centricular.com>2014-10-14 10:00:34 +0200
commit2825929d1c1f6dcfd91629523c870bfeb1bb7661 (patch)
tree8e4e5a5b32360eafb5824743b5fd9e343e16a3ac
parentfdb81f02d7a09ee23ded57a938ad2ff3bc09a08b (diff)
downloadgstreamer-plugins-bad-2825929d1c1f6dcfd91629523c870bfeb1bb7661.tar.gz
gl/cocoa: Switch to a plain NSView subclass instead of NSOpenGLView
We don't and can't use NSOpenGLView as it's supposed to be used and it gets into our way by being to clever in various situations.
-rw-r--r--gst-libs/gst/gl/cocoa/gstgl_cocoa_private.h12
-rw-r--r--gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m16
-rw-r--r--gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m101
3 files changed, 76 insertions, 53 deletions
diff --git a/gst-libs/gst/gl/cocoa/gstgl_cocoa_private.h b/gst-libs/gst/gl/cocoa/gstgl_cocoa_private.h
index 726d6071b..fa7178b47 100644
--- a/gst-libs/gst/gl/cocoa/gstgl_cocoa_private.h
+++ b/gst-libs/gst/gl/cocoa/gstgl_cocoa_private.h
@@ -34,25 +34,23 @@ struct _GstGLContextCocoaPrivate
{
NSOpenGLContext *gl_context;
NSOpenGLContext *external_gl_context;
- NSRect rect;
gint source_id;
};
/* =============================================================*/
/* */
-/* GstGLNSOpenGLView declaration */
+/* GstGLNSView declaration */
/* */
/* =============================================================*/
-@interface GstGLNSOpenGLView: NSOpenGLView {
- GstGLWindowCocoa *m_cocoa;
+@interface GstGLNSView: NSView {
+ GstGLWindowCocoa *window_cocoa;
}
-- (id) initWithFrame:(GstGLWindowCocoa *)window rect:(NSRect)contentRect
- pixelFormat:(NSOpenGLPixelFormat *)fmt;
+- (id) initWithFrame:(GstGLWindowCocoa *)window rect:(NSRect)contentRect;
@end
-gboolean gst_gl_window_cocoa_create_window (GstGLWindowCocoa *window_cocoa);
+gboolean gst_gl_window_cocoa_create_window (GstGLWindowCocoa *window_cocoa, NSRect rect);
G_END_DECLS
diff --git a/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m b/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m
index a4d1cd914..e83b33de2 100644
--- a/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m
+++ b/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m
@@ -201,7 +201,7 @@ 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);
- GstGLNSOpenGLView *glView = nil;
+ GstGLNSView *glView = nil;
NSWindow *window_handle;
NSRect rect;
NSAutoreleasePool *pool;
@@ -234,12 +234,10 @@ gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
rect.size.width = 320;
rect.size.height = 240;
- priv->rect = rect;
-
- gst_gl_window_cocoa_create_window (window_cocoa);
+ gst_gl_window_cocoa_create_window (window_cocoa, rect);
window_handle = (NSWindow *) gst_gl_window_get_window_handle (window);
- glView = [GstGLNSOpenGLView alloc];
+ glView = [GstGLNSView alloc];
fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
@@ -249,7 +247,7 @@ gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
return FALSE;
}
- glView = [glView initWithFrame:window_cocoa rect:rect pixelFormat:fmt];
+ glView = [glView initWithFrame:window_cocoa rect:rect];
[window_handle setContentView:glView];
@@ -263,11 +261,9 @@ gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
[glContext setView:glView];
- [glView setOpenGLContext:glContext];
-
#else
/* FIXME try to make context sharing work in GNUstep */
- context_cocoa->priv->gl_context = [glView openGLContext];
+ context_cocoa->priv->gl_context = glContext;
#endif
/* OpenGL context is made current only one time threre.
@@ -287,7 +283,7 @@ gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
#else
const GLint swapInterval = 1;
#endif
- [[glView openGLContext] setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
+ [glContext setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
}
} NS_HANDLER {
GST_DEBUG ("your back-end does not implement NSOpenglContext::setValues\n");
diff --git a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m
index 4cb5a3def..706983562 100644
--- a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m
+++ b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m
@@ -1,6 +1,7 @@
/*
* GStreamer
* Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
+ * Copyright (C) 2014 Sebastian Dröge <sebastian@centricular.com>
*
* This library is free software; you can redistribute it and/or
* modify it un der the terms of the GNU Library General Public
@@ -34,7 +35,7 @@
@interface GstGLNSWindow: NSWindow {
BOOL m_isClosed;
- GstGLWindowCocoa *m_cocoa;
+ GstGLWindowCocoa *window_cocoa;
}
- (id)initWithContentRect:(NSRect)contentRect
styleMask: (unsigned int) styleMask
@@ -123,17 +124,12 @@ gst_gl_window_cocoa_new (void)
}
gboolean
-gst_gl_window_cocoa_create_window (GstGLWindowCocoa *window_cocoa)
+gst_gl_window_cocoa_create_window (GstGLWindowCocoa *window_cocoa, NSRect rect)
{
- GstGLWindow *window = GST_GL_WINDOW (window_cocoa);
- GstGLContext *context = gst_gl_window_get_context (window);
- GstGLContextCocoa *context_cocoa = GST_GL_CONTEXT_COCOA (context);
GstGLWindowCocoaPrivate *priv = window_cocoa->priv;
- NSRect rect = context_cocoa->priv->rect;
/* FIXME: This should probably be done in the application main thread */
- priv->internal_win_id = [GstGLNSWindow alloc];
- [priv->internal_win_id initWithContentRect:rect styleMask:
+ priv->internal_win_id = [[GstGLNSWindow alloc] initWithContentRect:rect styleMask:
(NSTitledWindowMask | NSClosableWindowMask |
NSResizableWindowMask | NSMiniaturizableWindowMask)
backing: NSBackingStoreBuffered defer: NO screen: nil gstWin: window_cocoa];
@@ -142,8 +138,6 @@ gst_gl_window_cocoa_create_window (GstGLWindowCocoa *window_cocoa)
[NSApp setDelegate: priv->internal_win_id];
- gst_object_unref (context);
-
return TRUE;
}
@@ -256,8 +250,8 @@ draw_cb (gpointer data)
}
if (!priv->external_view && !priv->visible) {
- static gint x = 0;
- static gint y = 0;
+ gint x = 0;
+ gint y = 0;
/* FIXME: This should probably be done from the application main thread */
@@ -294,11 +288,16 @@ draw_cb (gpointer data)
if (g_main_loop_is_running (priv->loop)) {
if (![priv->internal_win_id isClosed]) {
+ GstGLContext *context = gst_gl_window_get_context (GST_GL_WINDOW (window_cocoa));
+ NSOpenGLContext * glContext = (NSOpenGLContext *) gst_gl_context_get_gl_context (context);
+
/* draw opengl scene in the back buffer */
GST_GL_WINDOW (window_cocoa)->draw (GST_GL_WINDOW (window_cocoa)->draw_data);
/* Copy the back buffer to the front buffer */
- [[[priv->internal_win_id contentView] openGLContext] flushBuffer];
+ [glContext flushBuffer];
+
+ gst_object_unref (context);
}
}
}
@@ -393,7 +392,7 @@ gst_gl_window_cocoa_send_message_async (GstGLWindow * window,
gstWin: (GstGLWindowCocoa *) cocoa {
m_isClosed = NO;
- m_cocoa = cocoa;
+ window_cocoa = cocoa;
self = [super initWithContentRect: contentRect
styleMask: styleMask backing: bufferingType
@@ -407,14 +406,14 @@ gst_gl_window_cocoa_send_message_async (GstGLWindow * window,
[self setBackgroundColor:[NSColor clearColor]];
- [self orderOut:m_cocoa->priv->internal_win_id];
+ [self orderOut:window_cocoa->priv->internal_win_id];
- if (m_cocoa->priv->external_view) {
+ if (window_cocoa->priv->external_view) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- NSView *view = [m_cocoa->priv->internal_win_id contentView];
+ NSView *view = [window_cocoa->priv->internal_win_id contentView];
- [m_cocoa->priv->external_view addSubview: view];
- [view setFrame: [m_cocoa->priv->external_view bounds]];
+ [window_cocoa->priv->external_view addSubview: view];
+ [view setFrame: [window_cocoa->priv->external_view bounds]];
[view setAutoresizingMask: NSViewWidthSizable|NSViewHeightSizable];
[pool release];
@@ -457,7 +456,7 @@ 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 (m_cocoa), (GstGLWindowCB) close_window_cb, m_cocoa);
+ gst_gl_window_send_message (GST_GL_WINDOW (window_cocoa), (GstGLWindowCB) close_window_cb, window_cocoa);
return YES;
}
@@ -491,29 +490,39 @@ close_window_cb (gpointer data)
/* =============================================================*/
/* */
-/* GstGLNSOpenGLView implementation */
+/* GstGLNSView implementation */
/* */
/* =============================================================*/
-@implementation GstGLNSOpenGLView
+@implementation GstGLNSView
-- (id)initWithFrame:(GstGLWindowCocoa *)window rect:(NSRect)contentRect pixelFormat:(NSOpenGLPixelFormat *)fmt {
+- (id)initWithFrame:(GstGLWindowCocoa *)window rect:(NSRect)contentRect {
- self = [super initWithFrame: contentRect pixelFormat: fmt];
+ /* FIXME: This should probably be done from the application main thread */
+ self = [super initWithFrame: contentRect];
- m_cocoa = window;
+ window_cocoa = window;
#ifndef GNUSTEP
[self setWantsLayer:NO];
#endif
+ /* Get notified about changes */
+ [[NSNotificationCenter defaultCenter] addObserver: self selector:@selector(reshape) name: NSViewFrameDidChangeNotification object: self];
+
return self;
}
+- (void) dealloc {
+ [[NSNotificationCenter defaultCenter] removeObserver: self];
+ [super dealloc];
+}
+
struct resize
{
GstGLWindowCocoa * window;
- gint width, height;
+ NSRect bounds, visibleRect;
+ NSSize frameSize;
};
static void
@@ -522,36 +531,56 @@ resize_cb (gpointer data)
struct resize *resize_data = data;
GstGLWindowCocoa *window_cocoa = resize_data->window;
GstGLWindow *window = GST_GL_WINDOW (window_cocoa);
+ GstGLContext *context = gst_gl_window_get_context (window);
+ NSOpenGLContext * glContext = (NSOpenGLContext *) gst_gl_context_get_gl_context (context);
if (g_main_loop_is_running (window_cocoa->priv->loop) && ![window_cocoa->priv->internal_win_id isClosed]) {
+ /* FIXME: Need to adjust viewport for clipping here */
if (window->resize) {
- window->resize (window->resize_data, resize_data->width, resize_data->height);
+ window->resize (window->resize_data, resize_data->bounds.size.width, resize_data->bounds.size.height);
}
- [[[window_cocoa->priv->internal_win_id contentView] openGLContext] update];
- GST_GL_WINDOW (window_cocoa)->draw (GST_GL_WINDOW (window_cocoa)->draw_data);
- [[[window_cocoa->priv->internal_win_id contentView] openGLContext] flushBuffer];
+ [glContext update];
+ GST_GL_WINDOW (window_cocoa)->draw (GST_GL_WINDOW (window_cocoa)->draw_data);
+ [glContext flushBuffer];
}
+ gst_object_unref (context);
}
- (void)reshape {
GstGLWindow *window;
- window = GST_GL_WINDOW (m_cocoa);
+ window = GST_GL_WINDOW (window_cocoa);
if (window->resize) {
NSRect bounds = [self bounds];
+ NSRect visibleRect = [self visibleRect];
+ NSSize frameSize = [self frame].size;
struct resize resize_data;
- resize_data.window = m_cocoa;
- resize_data.width = bounds.size.width;
- resize_data.height = bounds.size.height;
+ GST_DEBUG_OBJECT (window, "Window resized: bounds %lf %lf %lf %lf, "
+ "visibleRect %lf %lf %lf %lf, frame size %lf %lf",
+ bounds.origin.x, bounds.origin.y,
+ bounds.size.width, bounds.size.height,
+ visibleRect.origin.x, visibleRect.origin.y,
+ 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;
- gst_gl_window_send_message (GST_GL_WINDOW (m_cocoa), (GstGLWindowCB) resize_cb, &resize_data);
+ gst_gl_window_send_message (GST_GL_WINDOW (window_cocoa), (GstGLWindowCB) resize_cb, &resize_data);
}
}
-- (void) update {
+- (BOOL) isOpaque {
+ return YES;
+}
+
+- (BOOL) isFlipped {
+ return YES;
}
@end