mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-09 07:52:36 +00:00
[362/906] make cocoa backend work on MacOSX
It works with both gst-launch and a cocoa app (non-embedded and embedded) But there is still some problems: - sometimes crash when closing - flickering when resizing - embedded mode not perfect I will first make the CMake build work with cocoa backend in order to generate a XCode project. Then it should be easier to fix those issues.
This commit is contained in:
parent
263eb59fcf
commit
a9ab2abea4
1 changed files with 235 additions and 131 deletions
302
gst-libs/gst/gl/gstglwindow_cocoa.m
Normal file → Executable file
302
gst-libs/gst/gl/gstglwindow_cocoa.m
Normal file → Executable file
|
@ -3,7 +3,7 @@
|
||||||
* Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
|
* Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it un der the terms of the GNU Library General Public
|
||||||
* License as published by the Free Software Foundation; either
|
* License as published by the Free Software Foundation; either
|
||||||
* version 2 of the License, or (at your option) any later version.
|
* version 2 of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
|
@ -27,11 +27,11 @@
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================= */
|
/* =============================================================*/
|
||||||
/* */
|
/* */
|
||||||
/* GstGLNSWindow declaration */
|
/* GstGLNSWindow declaration */
|
||||||
/* */
|
/* */
|
||||||
/* ============================================================= */
|
/* =============================================================*/
|
||||||
|
|
||||||
@interface GstGLNSWindow: NSWindow {
|
@interface GstGLNSWindow: NSWindow {
|
||||||
BOOL m_isClosed;
|
BOOL m_isClosed;
|
||||||
|
@ -42,36 +42,54 @@
|
||||||
backing: (NSBackingStoreType) bufferingType
|
backing: (NSBackingStoreType) bufferingType
|
||||||
defer: (BOOL) flag screen: (NSScreen *) aScreen
|
defer: (BOOL) flag screen: (NSScreen *) aScreen
|
||||||
gstWin: (GstGLWindowPrivate *) priv;
|
gstWin: (GstGLWindowPrivate *) priv;
|
||||||
|
- (BOOL) isClosed;
|
||||||
|
@end
|
||||||
|
|
||||||
|
/* =============================================================*/
|
||||||
|
/* */
|
||||||
|
/* GstGLNSOpenGLView declaration */
|
||||||
|
/* */
|
||||||
|
/* =============================================================*/
|
||||||
|
|
||||||
|
@interface GstGLNSOpenGLView: NSOpenGLView {
|
||||||
|
GstGLWindowPrivate *m_priv;
|
||||||
|
}
|
||||||
|
- (id) initWithFrame:(NSRect)contentRect pixelFormat:(NSOpenGLPixelFormat *)fmt
|
||||||
|
private: (GstGLWindowPrivate *) priv;
|
||||||
|
- (void) reshape;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================= */
|
/* =============================================================*/
|
||||||
/* */
|
/* */
|
||||||
/* AppThreadPerformer declaration */
|
/* AppThreadPerformer declaration */
|
||||||
/* */
|
/* */
|
||||||
/* ============================================================= */
|
/* =============================================================*/
|
||||||
|
|
||||||
/* Perform actions in the Application thread */
|
/* Perform actions in the Application thread */
|
||||||
@interface AppThreadPerformer : NSObject {
|
@interface AppThreadPerformer : NSObject {
|
||||||
GstGLWindowPrivate *m_priv;
|
GstGLWindowPrivate *m_priv;
|
||||||
GstGLWindowCB m_callback;
|
GstGLWindowCB m_callback;
|
||||||
|
GstGLWindowCB2 m_callback2;
|
||||||
gpointer m_data;
|
gpointer m_data;
|
||||||
|
gint m_width;
|
||||||
|
gint m_height;
|
||||||
}
|
}
|
||||||
- (id) initWithPrivate : (GstGLWindowPrivate *) priv;
|
- (id) initWithPrivate: (GstGLWindowPrivate *) priv;
|
||||||
- (id) initWithCallback : (GstGLWindowCB) callback userData: (gpointer) data;
|
- (id) initWithCallback: (GstGLWindowCB) callback userData: (gpointer) data;
|
||||||
|
- (id) initWithSize: (GstGLWindowCB2) callback userData: (gpointer) data toSize: (NSSize) size private: (GstGLWindowPrivate *) priv;
|
||||||
- (id) initWithAll: (GstGLWindowCB) callback userData: (gpointer) data private: (GstGLWindowPrivate *) priv;
|
- (id) initWithAll: (GstGLWindowCB) callback userData: (gpointer) data private: (GstGLWindowPrivate *) priv;
|
||||||
- (void) updateWindow;
|
- (void) updateWindow;
|
||||||
- (void) sendToApp;
|
- (void) sendToApp;
|
||||||
- (void) setWindow: (NSWindow *) window;
|
- (void) setWindow;
|
||||||
- (void) stopApp;
|
- (void) stopApp;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
/* =============================================================*/
|
||||||
/* ============================================================= */
|
|
||||||
/* */
|
/* */
|
||||||
/* GstGLWindow */
|
/* GstGLWindow */
|
||||||
/* */
|
/* */
|
||||||
/* ============================================================= */
|
/* =============================================================*/
|
||||||
|
|
||||||
#ifndef GNUSTEP
|
#ifndef GNUSTEP
|
||||||
static BOOL GSRegisterCurrentThread(void) { return TRUE; };
|
static BOOL GSRegisterCurrentThread(void) { return TRUE; };
|
||||||
|
@ -89,6 +107,7 @@ enum
|
||||||
struct _GstGLWindowPrivate
|
struct _GstGLWindowPrivate
|
||||||
{
|
{
|
||||||
GstGLNSWindow *internal_win_id;
|
GstGLNSWindow *internal_win_id;
|
||||||
|
NSOpenGLContext *external_gl_context;
|
||||||
GstGLWindowCB draw_cb;
|
GstGLWindowCB draw_cb;
|
||||||
gpointer draw_data;
|
gpointer draw_data;
|
||||||
GstGLWindowCB2 resize_cb;
|
GstGLWindowCB2 resize_cb;
|
||||||
|
@ -97,6 +116,8 @@ struct _GstGLWindowPrivate
|
||||||
gpointer close_data;
|
gpointer close_data;
|
||||||
gboolean visible;
|
gboolean visible;
|
||||||
NSWindow *parent;
|
NSWindow *parent;
|
||||||
|
NSThread *thread;
|
||||||
|
gboolean running;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (GstGLWindow, gst_gl_window, G_TYPE_OBJECT);
|
G_DEFINE_TYPE (GstGLWindow, gst_gl_window, G_TYPE_OBJECT);
|
||||||
|
@ -122,11 +143,23 @@ gst_gl_window_log_handler (const gchar * domain, GLogLevelFlags flags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_gl_window_nsapp_init (gpointer data)
|
||||||
|
{
|
||||||
|
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
[NSApplication sharedApplication];
|
||||||
|
[pool release];
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_gl_window_class_init (GstGLWindowClass * klass)
|
gst_gl_window_class_init (GstGLWindowClass * klass)
|
||||||
{
|
{
|
||||||
GObjectClass *obj_class = G_OBJECT_CLASS (klass);
|
GObjectClass *obj_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
g_idle_add (gst_gl_window_nsapp_init, NULL);
|
||||||
|
|
||||||
g_type_class_add_private (klass, sizeof (GstGLWindowPrivate));
|
g_type_class_add_private (klass, sizeof (GstGLWindowPrivate));
|
||||||
|
|
||||||
obj_class->finalize = gst_gl_window_finalize;
|
obj_class->finalize = gst_gl_window_finalize;
|
||||||
|
@ -144,6 +177,7 @@ gst_gl_window_init (GstGLWindow * window)
|
||||||
gst_gl_window_log_handler, NULL);
|
gst_gl_window_log_handler, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Must be called in the gl thread */
|
/* Must be called in the gl thread */
|
||||||
GstGLWindow *
|
GstGLWindow *
|
||||||
gst_gl_window_new (gint width, gint height, gulong external_gl_context)
|
gst_gl_window_new (gint width, gint height, gulong external_gl_context)
|
||||||
|
@ -161,6 +195,7 @@ gst_gl_window_new (gint width, gint height, gulong external_gl_context)
|
||||||
y += 20;
|
y += 20;
|
||||||
|
|
||||||
priv->internal_win_id = nil;
|
priv->internal_win_id = nil;
|
||||||
|
priv->external_gl_context = (NSOpenGLContext *) external_gl_context;
|
||||||
priv->draw_cb = NULL;
|
priv->draw_cb = NULL;
|
||||||
priv->draw_data = NULL;
|
priv->draw_data = NULL;
|
||||||
priv->resize_cb = NULL;
|
priv->resize_cb = NULL;
|
||||||
|
@ -169,29 +204,31 @@ gst_gl_window_new (gint width, gint height, gulong external_gl_context)
|
||||||
priv->close_data = NULL;
|
priv->close_data = NULL;
|
||||||
priv->visible = FALSE;
|
priv->visible = FALSE;
|
||||||
priv->parent = nil;
|
priv->parent = nil;
|
||||||
|
priv->thread = nil;
|
||||||
|
priv->running = TRUE;
|
||||||
|
|
||||||
GSRegisterCurrentThread();
|
GSRegisterCurrentThread();
|
||||||
|
|
||||||
pool = [[NSAutoreleasePool alloc] init];
|
pool = [[NSAutoreleasePool alloc] init];
|
||||||
[NSApplication sharedApplication];
|
|
||||||
|
|
||||||
rect.origin.x = 0;
|
rect.origin.x = 0;
|
||||||
rect.origin.y = 0;
|
rect.origin.y = 0;
|
||||||
rect.size.width = width;
|
rect.size.width = width;
|
||||||
rect.size.height = height;
|
rect.size.height = height;
|
||||||
|
|
||||||
priv->internal_win_id =[[GstGLNSWindow alloc] initWithContentRect:rect
|
priv->internal_win_id =[[GstGLNSWindow alloc] initWithContentRect:rect styleMask:
|
||||||
styleMask: (NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask)
|
(NSTitledWindowMask | NSClosableWindowMask |
|
||||||
|
NSResizableWindowMask |NSMiniaturizableWindowMask)
|
||||||
backing: NSBackingStoreBuffered defer: NO screen: nil gstWin: priv];
|
backing: NSBackingStoreBuffered defer: NO screen: nil gstWin: priv];
|
||||||
|
|
||||||
if (priv->internal_win_id) {
|
if (priv->internal_win_id) {
|
||||||
NSRect windowRect;
|
NSRect windowRect;
|
||||||
NSRect mainRect = [[NSScreen mainScreen] visibleFrame];
|
NSRect mainRect = [[NSScreen mainScreen] visibleFrame];
|
||||||
GST_DEBUG ("main screen rect: %d %d %d %d", (int) mainRect.origin.x, (int) mainRect.origin.y,
|
g_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);
|
(int) mainRect.size.width, (int) mainRect.size.height);
|
||||||
|
|
||||||
windowRect = [priv->internal_win_id frame];
|
windowRect = [priv->internal_win_id frame];
|
||||||
GST_DEBUG ("window rect: %d %d %d %d", (int) windowRect.origin.x, (int) windowRect.origin.y,
|
g_debug ("window rect: %d %d %d %d\n", (int) windowRect.origin.x, (int) windowRect.origin.y,
|
||||||
(int) windowRect.size.width, (int) windowRect.size.height);
|
(int) windowRect.size.width, (int) windowRect.size.height);
|
||||||
|
|
||||||
windowRect.origin.x += x;
|
windowRect.origin.x += x;
|
||||||
|
@ -199,6 +236,10 @@ gst_gl_window_new (gint width, gint height, gulong external_gl_context)
|
||||||
[priv->internal_win_id setFrame:windowRect display:NO];
|
[priv->internal_win_id setFrame:windowRect display:NO];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv->thread = [NSThread currentThread];
|
||||||
|
|
||||||
|
[NSApp setDelegate: priv->internal_win_id];
|
||||||
|
|
||||||
[pool release];
|
[pool release];
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
|
@ -219,7 +260,9 @@ gst_gl_window_set_external_window_id (GstGLWindow * window, gulong id)
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
AppThreadPerformer* app_thread_performer = [[AppThreadPerformer alloc] initWithPrivate:priv];
|
AppThreadPerformer* app_thread_performer = [[AppThreadPerformer alloc] initWithPrivate:priv];
|
||||||
[app_thread_performer performSelectorOnMainThread:@selector(setWindow) withObject:(NSWindow *)(gulong)id waitUntilDone:YES];
|
priv->parent = (NSWindow*) id;
|
||||||
|
[app_thread_performer performSelectorOnMainThread:@selector(setWindow)
|
||||||
|
withObject:nil waitUntilDone:YES];
|
||||||
|
|
||||||
[pool release];
|
[pool release];
|
||||||
|
|
||||||
|
@ -278,7 +321,8 @@ gst_gl_window_draw (GstGLWindow * window)
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
AppThreadPerformer* app_thread_performer = [[AppThreadPerformer alloc] initWithPrivate:priv];
|
AppThreadPerformer* app_thread_performer = [[AppThreadPerformer alloc] initWithPrivate:priv];
|
||||||
[app_thread_performer performSelectorOnMainThread:@selector(updateWindow) withObject:nil waitUntilDone:YES];
|
[app_thread_performer performSelector:@selector(updateWindow)
|
||||||
|
onThread:priv->thread withObject:nil waitUntilDone:YES];
|
||||||
|
|
||||||
[pool release];
|
[pool release];
|
||||||
|
|
||||||
|
@ -288,18 +332,55 @@ gst_gl_window_draw (GstGLWindow * window)
|
||||||
g_debug ("failed to register current thread, cannot draw");
|
g_debug ("failed to register current thread, cannot draw");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_gl_window_nsapp_iteration (gpointer data)
|
||||||
|
{
|
||||||
|
NSEvent *event = nil;
|
||||||
|
|
||||||
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
|
if ([NSThread isMainThread]) {
|
||||||
|
|
||||||
|
while ((event = ([NSApp nextEventMatchingMask:NSAnyEventMask
|
||||||
|
untilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]
|
||||||
|
inMode:NSDefaultRunLoopMode dequeue:YES])) != nil)
|
||||||
|
[NSApp sendEvent:event];
|
||||||
|
|
||||||
|
[pool release];
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_gl_window_run_loop (GstGLWindow * window)
|
gst_gl_window_run_loop (GstGLWindow * window)
|
||||||
{
|
{
|
||||||
GstGLWindowPrivate *priv = window->priv;
|
GstGLWindowPrivate *priv = window->priv;
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
NSRunLoop *run_loop = [NSRunLoop currentRunLoop];
|
||||||
|
|
||||||
g_debug ("begin loop\n");
|
g_debug ("begin loop: %lud\n", (gulong) run_loop);
|
||||||
|
|
||||||
if (priv->internal_win_id != nil) {
|
if (priv->internal_win_id != nil) {
|
||||||
[NSApp setDelegate:priv->internal_win_id];
|
while(priv->running) {
|
||||||
[NSApp run];
|
|
||||||
|
if (!priv->parent) {
|
||||||
|
|
||||||
|
[run_loop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
|
||||||
|
|
||||||
|
if (!priv->visible) {
|
||||||
|
g_debug ("make the window available");
|
||||||
|
[priv->internal_win_id orderFront:priv->internal_win_id];
|
||||||
|
priv->visible = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_idle_add (gst_gl_window_nsapp_iteration, priv->internal_win_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
[priv->internal_win_id release];
|
[priv->internal_win_id release];
|
||||||
|
priv->internal_win_id = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
[pool release];
|
[pool release];
|
||||||
|
@ -312,12 +393,17 @@ void
|
||||||
gst_gl_window_quit_loop (GstGLWindow * window, GstGLWindowCB callback,
|
gst_gl_window_quit_loop (GstGLWindow * window, GstGLWindowCB callback,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (window) {
|
if (window) {
|
||||||
if (GSRegisterCurrentThread()) {
|
if (GSRegisterCurrentThread()) {
|
||||||
|
GstGLWindowPrivate *priv = window->priv;
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
AppThreadPerformer* app_thread_performer = [[AppThreadPerformer alloc] initWithCallback:callback userData:data];
|
AppThreadPerformer* app_thread_performer = [[AppThreadPerformer alloc] initWithAll:callback
|
||||||
[app_thread_performer performSelectorOnMainThread:@selector(stopApp) withObject:nil waitUntilDone:YES];
|
userData:data private:priv];
|
||||||
|
|
||||||
|
[app_thread_performer performSelector:@selector(stopApp) onThread:priv->thread
|
||||||
|
withObject:nil waitUntilDone:YES];
|
||||||
|
|
||||||
[pool release];
|
[pool release];
|
||||||
|
|
||||||
|
@ -338,8 +424,11 @@ gst_gl_window_send_message (GstGLWindow * window, GstGLWindowCB callback,
|
||||||
if (GSRegisterCurrentThread()) {
|
if (GSRegisterCurrentThread()) {
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
AppThreadPerformer* app_thread_performer = [[AppThreadPerformer alloc] initWithAll:callback userData:data private:priv];
|
AppThreadPerformer* app_thread_performer = [[AppThreadPerformer alloc] initWithAll:callback
|
||||||
[app_thread_performer performSelectorOnMainThread:@selector(sendToApp) withObject:nil waitUntilDone:YES];
|
userData:data private:priv];
|
||||||
|
|
||||||
|
[app_thread_performer performSelector:@selector(sendToApp) onThread:priv->thread
|
||||||
|
withObject:nil waitUntilDone:YES];
|
||||||
|
|
||||||
[pool release];
|
[pool release];
|
||||||
|
|
||||||
|
@ -351,11 +440,11 @@ gst_gl_window_send_message (GstGLWindow * window, GstGLWindowCB callback,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================= */
|
/* =============================================================*/
|
||||||
/* */
|
/* */
|
||||||
/* GstGLNSWindow implementation */
|
/* GstGLNSWindow implementation */
|
||||||
/* */
|
/* */
|
||||||
/* ============================================================= */
|
/* =============================================================*/
|
||||||
|
|
||||||
@implementation GstGLNSWindow
|
@implementation GstGLNSWindow
|
||||||
|
|
||||||
|
@ -365,17 +454,12 @@ gst_gl_window_send_message (GstGLWindow * window, GstGLWindowCB callback,
|
||||||
defer: (BOOL) flag screen: (NSScreen *) aScreen
|
defer: (BOOL) flag screen: (NSScreen *) aScreen
|
||||||
gstWin: (GstGLWindowPrivate *) priv {
|
gstWin: (GstGLWindowPrivate *) priv {
|
||||||
|
|
||||||
NSOpenGLView *glView = nil;
|
GstGLNSOpenGLView *glView = nil;
|
||||||
NSOpenGLPixelFormat *fmt = nil;
|
NSOpenGLPixelFormat *fmt = nil;
|
||||||
NSOpenGLContext *glContext = nil;
|
NSOpenGLContext *glContext = nil;
|
||||||
NSOpenGLPixelFormatAttribute attribs[] = {
|
NSOpenGLPixelFormatAttribute attribs[] = {
|
||||||
NSOpenGLPFAAccelerated,
|
|
||||||
NSOpenGLPFANoRecovery,
|
|
||||||
NSOpenGLPFADoubleBuffer,
|
NSOpenGLPFADoubleBuffer,
|
||||||
NSOpenGLPFAColorSize, 24,
|
NSOpenGLPFADepthSize, 32,
|
||||||
NSOpenGLPFAAlphaSize, 8,
|
|
||||||
NSOpenGLPFADepthSize, 24,
|
|
||||||
NSOpenGLPFAWindow,
|
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -390,9 +474,7 @@ gst_gl_window_send_message (GstGLWindow * window, GstGLWindowCB callback,
|
||||||
|
|
||||||
g_debug ("initializing GstGLNSWindow");
|
g_debug ("initializing GstGLNSWindow");
|
||||||
|
|
||||||
glView = [NSOpenGLView alloc];
|
glView = [GstGLNSOpenGLView alloc];
|
||||||
|
|
||||||
[self setContentView:glView];
|
|
||||||
|
|
||||||
fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
|
fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
|
||||||
|
|
||||||
|
@ -401,9 +483,14 @@ gst_gl_window_send_message (GstGLWindow * window, GstGLWindowCB callback,
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
glView = [glView initWithFrame:contentRect pixelFormat:fmt];
|
glView = [glView initWithFrame:contentRect pixelFormat:fmt private: m_priv];
|
||||||
|
|
||||||
glContext = [glView openGLContext];
|
[self setContentView:glView];
|
||||||
|
|
||||||
|
glContext = [[NSOpenGLContext alloc] initWithFormat:fmt
|
||||||
|
shareContext:m_priv->external_gl_context];
|
||||||
|
|
||||||
|
[glView setOpenGLContext:glContext];
|
||||||
|
|
||||||
/* OpenGL context is made current only one time threre.
|
/* OpenGL context is made current only one time threre.
|
||||||
* Indeed, all OpenGL calls are made in only one thread,
|
* Indeed, all OpenGL calls are made in only one thread,
|
||||||
|
@ -416,23 +503,22 @@ gst_gl_window_send_message (GstGLWindow * window, GstGLWindowCB callback,
|
||||||
* Discarded if you configured your driver to Never-use-V-Sync.
|
* Discarded if you configured your driver to Never-use-V-Sync.
|
||||||
*/
|
*/
|
||||||
NS_DURING {
|
NS_DURING {
|
||||||
#if 0
|
|
||||||
/* FIXME doesn't compile */
|
|
||||||
if (glContext) {
|
if (glContext) {
|
||||||
long swapInterval = 1;
|
long swapInterval = 1;
|
||||||
[[glView openGLContext] setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
|
[[glView openGLContext] setValues:(const GLint *)&swapInterval forParameter:NSOpenGLCPSwapInterval];
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
} NS_HANDLER {
|
} NS_HANDLER {
|
||||||
g_debug ("your back-end does not implement NSOpenglContext::setValues");
|
g_debug ("your back-end does not implement NSOpenglContext::setValues");
|
||||||
}
|
}
|
||||||
NS_ENDHANDLER
|
NS_ENDHANDLER
|
||||||
|
|
||||||
g_debug ("opengl GstGLNSWindow initialized: %d x %d",
|
g_debug ("opengl GstGLNSWindow initialized: %d x %d",
|
||||||
(int) contentRect.size.width, (int) contentRect.size.height);
|
(gint) contentRect.size.width, (gint) contentRect.size.height);
|
||||||
|
|
||||||
[self setTitle:@"OpenGL renderer"];
|
[self setTitle:@"OpenGL renderer"];
|
||||||
|
|
||||||
|
[self setBackgroundColor:[NSColor clearColor]];
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,15 +540,6 @@ gst_gl_window_send_message (GstGLWindow * window, GstGLWindowCB callback,
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) windowDidResize: (NSNotification *) not {
|
|
||||||
NSLog(@"windowDidResize"); //FIXME: seems to be not reached on win32
|
|
||||||
if (m_priv->resize_cb) {
|
|
||||||
NSWindow *window = [not object];
|
|
||||||
NSRect rect = [window frame];
|
|
||||||
m_priv->resize_cb (m_priv->resize_data, rect.size.width, rect.size.height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) applicationDidFinishLaunching: (NSNotification *) not {
|
- (void) applicationDidFinishLaunching: (NSNotification *) not {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,64 +557,98 @@ gst_gl_window_send_message (GstGLWindow * window, GstGLWindowCB callback,
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================= */
|
/* =============================================================*/
|
||||||
|
/* */
|
||||||
|
/* GstGLNSOpenGLView implementation */
|
||||||
|
/* */
|
||||||
|
/* =============================================================*/
|
||||||
|
|
||||||
|
@implementation GstGLNSOpenGLView
|
||||||
|
|
||||||
|
- (id)initWithFrame:(NSRect)contentRect pixelFormat:(NSOpenGLPixelFormat *)fmt private: (GstGLWindowPrivate *) priv {
|
||||||
|
|
||||||
|
self = [super initWithFrame: contentRect pixelFormat: fmt];
|
||||||
|
|
||||||
|
m_priv = priv;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)reshape {
|
||||||
|
if (m_priv->resize_cb) {
|
||||||
|
|
||||||
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
NSRect bounds = [self bounds];
|
||||||
|
AppThreadPerformer* app_thread_performer = [[AppThreadPerformer alloc]
|
||||||
|
initWithSize:m_priv->resize_cb userData:m_priv->resize_data
|
||||||
|
toSize:bounds.size private:m_priv];
|
||||||
|
|
||||||
|
[app_thread_performer performSelector:@selector(resizeWindow) onThread:m_priv->thread
|
||||||
|
withObject:nil waitUntilDone:NO];
|
||||||
|
|
||||||
|
[pool release];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
/* =============================================================*/
|
||||||
/* */
|
/* */
|
||||||
/* AppThreadPerformer implementation */
|
/* AppThreadPerformer implementation */
|
||||||
/* */
|
/* */
|
||||||
/* ============================================================= */
|
/* =============================================================*/
|
||||||
|
|
||||||
@implementation AppThreadPerformer
|
@implementation AppThreadPerformer
|
||||||
|
|
||||||
- (id) initWithPrivate: (GstGLWindowPrivate *) priv {
|
- (id) initWithPrivate: (GstGLWindowPrivate *) priv {
|
||||||
m_priv = priv;
|
m_priv = priv;
|
||||||
m_callback = NULL;
|
m_callback = NULL;
|
||||||
|
m_callback2 = NULL;
|
||||||
m_data = NULL;
|
m_data = NULL;
|
||||||
|
m_width = 0;
|
||||||
|
m_height = 0;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) initWithCallback: (GstGLWindowCB) callback userData: (gpointer) data {
|
- (id) initWithCallback: (GstGLWindowCB) callback userData: (gpointer) data {
|
||||||
m_priv = NULL;
|
m_priv = NULL;
|
||||||
m_callback = callback;
|
m_callback = callback;
|
||||||
|
m_callback2 = NULL;
|
||||||
m_data = data;
|
m_data = data;
|
||||||
|
m_width = 0;
|
||||||
|
m_height = 0;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) initWithAll: (GstGLWindowCB) callback userData: (gpointer) data private: (GstGLWindowPrivate *) priv {
|
- (id) initWithSize: (GstGLWindowCB2) callback userData: (gpointer) data
|
||||||
|
toSize: (NSSize) size private: (GstGLWindowPrivate *) priv {
|
||||||
|
m_priv = priv;
|
||||||
|
m_callback = NULL;
|
||||||
|
m_callback2 = callback;
|
||||||
|
m_data = data;
|
||||||
|
m_width = size.width;
|
||||||
|
m_height = size.height;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) initWithAll: (GstGLWindowCB) callback userData: (gpointer) data
|
||||||
|
private: (GstGLWindowPrivate *) priv {
|
||||||
m_priv = priv;
|
m_priv = priv;
|
||||||
m_callback = callback;
|
m_callback = callback;
|
||||||
|
m_callback2 = NULL;
|
||||||
m_data = data;
|
m_data = data;
|
||||||
|
m_width = 0;
|
||||||
|
m_height = 0;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) updateWindow {
|
- (void) updateWindow {
|
||||||
if ([NSApp isRunning]) {
|
if (m_priv->running) {
|
||||||
|
|
||||||
if (![m_priv->internal_win_id isClosed]) {
|
if (![m_priv->internal_win_id isClosed]) {
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
if (!m_priv->visible) {
|
|
||||||
g_debug ("make the window available");
|
|
||||||
[m_priv->internal_win_id makeMainWindow];
|
|
||||||
//[m_priv->internal_win_id center];
|
|
||||||
[m_priv->internal_win_id orderFront:m_priv->internal_win_id];
|
|
||||||
m_priv->visible = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_priv->parent) {
|
|
||||||
NSRect parent_rect = [[m_priv->internal_win_id parentWindow] frame];
|
|
||||||
NSRect rect = [m_priv->internal_win_id frame];
|
|
||||||
|
|
||||||
if (rect.origin.x != parent_rect.origin.x || rect.origin.y != parent_rect.origin.y ||
|
|
||||||
rect.size.width != parent_rect.size.width || rect.size.height != parent_rect.size.height) {
|
|
||||||
|
|
||||||
[m_priv->internal_win_id setFrame:parent_rect display:YES];
|
|
||||||
|
|
||||||
g_debug ("parent resize: %d, %d, %d, %d\n",
|
|
||||||
(int) parent_rect.origin.x, (int) parent_rect.origin.y,
|
|
||||||
(int) parent_rect.size.width, (int) parent_rect.size.height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([[m_priv->internal_win_id contentView] lockFocusIfCanDraw]) {
|
if ([[m_priv->internal_win_id contentView] lockFocusIfCanDraw]) {
|
||||||
/* draw opengl scene in the back buffer */
|
/* draw opengl scene in the back buffer */
|
||||||
m_priv->draw_cb (m_priv->draw_data);
|
m_priv->draw_cb (m_priv->draw_data);
|
||||||
|
@ -551,36 +662,29 @@ gst_gl_window_send_message (GstGLWindow * window, GstGLWindowCB callback,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) sendToApp {
|
- (void) resizeWindow {
|
||||||
if ([NSApp isRunning]) {
|
if (m_priv->running)
|
||||||
if (![m_priv->internal_win_id isClosed]) {
|
m_callback2 (m_data, m_width, m_height);
|
||||||
m_callback (m_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setWindow: (NSWindow *) window {
|
- (void) sendToApp {
|
||||||
if ([NSApp isRunning]) {
|
if (m_priv->running)
|
||||||
|
m_callback (m_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setWindow {
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
NSWindow *window = m_priv->parent;
|
||||||
|
|
||||||
[m_priv->internal_win_id setParentWindow:window];
|
[window setContentView: [m_priv->internal_win_id contentView]];
|
||||||
|
|
||||||
m_priv->parent = window;
|
[m_priv->internal_win_id orderOut:m_priv->internal_win_id];
|
||||||
|
|
||||||
[m_priv->internal_win_id setFrame:[window frame] display:YES];
|
|
||||||
|
|
||||||
[pool release];
|
[pool release];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) stopApp {
|
- (void) stopApp {
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
m_priv->running = FALSE;
|
||||||
|
|
||||||
if ([NSApp isRunning])
|
|
||||||
[NSApp stop:self];
|
|
||||||
|
|
||||||
[pool release];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
Loading…
Reference in a new issue