3 * Copyright (C) 2012 Matthew Waters <ystreet00@gmail.com>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
25 #include <Cocoa/Cocoa.h>
27 #include "gstglcontext_cocoa.h"
28 #include "gstgl_cocoa_private.h"
30 static gboolean gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
31 GstGLContext * other_context, GError **error);
32 static void gst_gl_context_cocoa_destroy_context (GstGLContext *context);
33 static guintptr gst_gl_context_cocoa_get_gl_context (GstGLContext * window);
34 static gboolean gst_gl_context_cocoa_activate (GstGLContext * context, gboolean activate);
35 static GstGLAPI gst_gl_context_cocoa_get_gl_api (GstGLContext * context);
37 #define GST_GL_CONTEXT_COCOA_GET_PRIVATE(o) \
38 (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_CONTEXT_COCOA, GstGLContextCocoaPrivate))
40 G_DEFINE_TYPE (GstGLContextCocoa, gst_gl_context_cocoa, GST_GL_TYPE_CONTEXT);
44 gst_gl_window_cocoa_nsapp_iteration (gpointer data)
46 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
50 if ([NSThread isMainThread]) {
52 while ((event = ([NSApp nextEventMatchingMask:NSAnyEventMask
53 untilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]
54 inMode:NSDefaultRunLoopMode dequeue:YES])) != nil) {
56 [NSApp sendEvent:event];
67 gst_gl_context_cocoa_class_init (GstGLContextCocoaClass * klass)
69 GstGLContextClass *context_class;
72 NSAutoreleasePool* pool = nil;
75 context_class = (GstGLContextClass *) klass;
77 g_type_class_add_private (klass, sizeof (GstGLContextCocoaPrivate));
79 context_class->destroy_context =
80 GST_DEBUG_FUNCPTR (gst_gl_context_cocoa_destroy_context);
81 context_class->create_context =
82 GST_DEBUG_FUNCPTR (gst_gl_context_cocoa_create_context);
83 context_class->get_gl_context =
84 GST_DEBUG_FUNCPTR (gst_gl_context_cocoa_get_gl_context);
85 context_class->activate = GST_DEBUG_FUNCPTR (gst_gl_context_cocoa_activate);
86 context_class->get_gl_api =
87 GST_DEBUG_FUNCPTR (gst_gl_context_cocoa_get_gl_api);
90 pool = [[NSAutoreleasePool alloc] init];
91 [NSApplication sharedApplication];
98 gst_gl_context_cocoa_init (GstGLContextCocoa * context)
100 context->priv = GST_GL_CONTEXT_COCOA_GET_PRIVATE (context);
103 /* Must be called in the gl thread */
105 gst_gl_context_cocoa_new (void)
107 GstGLContextCocoa *context = g_object_new (GST_GL_TYPE_CONTEXT_COCOA, NULL);
113 gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
114 GstGLContext *other_context, GError **error)
116 GstGLContextCocoa *context_cocoa = GST_GL_CONTEXT_COCOA (context);
117 GstGLContextCocoaPrivate *priv = context_cocoa->priv;
118 GstGLWindow *window = gst_gl_context_get_window (context);
119 GstGLWindowCocoa *window_cocoa = GST_GL_WINDOW_COCOA (window);
120 GstGLNSOpenGLView *glView = nil;
121 NSWindow *window_handle;
123 NSAutoreleasePool *pool;
124 NSOpenGLPixelFormat *fmt = nil;
125 NSOpenGLContext *glContext = nil;
126 NSOpenGLPixelFormatAttribute attribs[] = {
127 NSOpenGLPFADoubleBuffer,
128 NSOpenGLPFAAccumSize, 32,
132 priv->gl_context = nil;
134 priv->external_gl_context = (NSOpenGLContext *) gst_gl_context_get_gl_context (other_context);
136 priv->external_gl_context = NULL;
138 GSRegisterCurrentThread();
140 pool = [[NSAutoreleasePool alloc] init];
143 [NSApplication sharedApplication];
148 rect.size.width = 320;
149 rect.size.height = 240;
153 gst_gl_window_cocoa_create_window (window_cocoa);
154 window_handle = (NSWindow *) gst_gl_window_get_window_handle (window);
156 glView = [GstGLNSOpenGLView alloc];
158 fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
161 gst_object_unref (window);
162 GST_WARNING ("cannot create NSOpenGLPixelFormat");
166 glView = [glView initWithFrame:window_cocoa rect:rect pixelFormat:fmt];
168 [window_handle setContentView:glView];
171 glContext = [[NSOpenGLContext alloc] initWithFormat:fmt
172 shareContext:context_cocoa->priv->external_gl_context];
174 GST_DEBUG ("NSOpenGL context created: %lud\n", (guintptr) glContext);
176 context_cocoa->priv->gl_context = glContext;
178 [glView setOpenGLContext:glContext];
181 /* FIXME try to make context sharing work in GNUstep */
182 context_cocoa->priv->gl_context = [glView openGLContext];
185 /* OpenGL context is made current only one time threre.
186 * Indeed, all OpenGL calls are made in only one thread,
187 * the Application thread */
188 [glContext makeCurrentContext];
192 /* Back and front buffers are swapped only during the vertical retrace of the monitor.
193 * Discarded if you configured your driver to Never-use-V-Sync.
198 const long swapInterval = 1;
200 const GLint swapInterval = 1;
202 [[glView openGLContext] setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
205 GST_DEBUG ("your back-end does not implement NSOpenglContext::setValues\n");
209 GST_DEBUG ("opengl GstGLNSWindow initialized: %d x %d\n",
210 (gint) rect.size.width, (gint) rect.size.height);
215 priv->source_id = g_timeout_add_seconds (1, gst_gl_window_cocoa_nsapp_iteration, NULL);
218 gst_object_unref (window);
224 gst_gl_context_cocoa_destroy_context (GstGLContext *context)
229 gst_gl_context_cocoa_get_gl_context (GstGLContext * context)
231 return (guintptr) GST_GL_CONTEXT_COCOA (context)->priv->gl_context;
235 gst_gl_context_cocoa_activate (GstGLContext * context, gboolean activate)
237 GstGLContextCocoa *context_cocoa;
239 context_cocoa = GST_GL_CONTEXT_COCOA (context);
242 [context_cocoa->priv->gl_context makeCurrentContext];
246 [context_cocoa->priv->gl_context clearCurrentContext];
252 gst_gl_context_cocoa_get_gl_api (GstGLContext * context)
254 return GST_GL_API_OPENGL;