3 * Copyright (C) 2015 Matthew Waters <matthew@centricular.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 "gstgl_cocoa_private.h"
29 @implementation GstGLCAOpenGLLayer
31 GST_TRACE ("dealloc GstGLCAOpenGLLayer %p context %p", self, self->gst_gl_context);
36 - (id)initWithGstGLContext:(GstGLContextCocoa *)parent_gl_context {
39 GST_TRACE ("init CAOpenGLLayer");
41 self->gst_gl_context = parent_gl_context;
46 - (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask {
47 CGLPixelFormatObj fmt = NULL;
49 if (self->gst_gl_context)
50 fmt = gst_gl_context_cocoa_get_pixel_format (self->gst_gl_context);
53 CGLPixelFormatAttribute attribs[] = {
61 GST_DEBUG ("creating new pixel format for CAOpenGLLayer %p", self);
63 ret = CGLChoosePixelFormat (attribs, &fmt, &npix);
64 if (ret != kCGLNoError) {
65 GST_ERROR ("CAOpenGLLayer cannot choose a pixel format: %s", CGLErrorString (ret));
72 - (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat {
73 CGLContextObj external_context = NULL;
76 if (self->gst_gl_context)
77 external_context = (CGLContextObj) gst_gl_context_get_gl_context (GST_GL_CONTEXT (self->gst_gl_context));
79 GST_INFO ("attempting to create CGLContext for CAOpenGLLayer with "
80 "share context %p", external_context);
82 ret = CGLCreateContext (pixelFormat, external_context, &self->gl_context);
83 if (ret != kCGLNoError) {
84 GST_ERROR ("failed to create CGL context in CAOpenGLLayer with share context %p: %s", external_context, CGLErrorString(ret));
87 return self->gl_context;
90 - (void)resize:(NSRect)bounds {
91 const GstGLFuncs *gl = ((GstGLContext *)self->gst_gl_context)->gl_vtable;
93 gl->GetIntegerv (GL_VIEWPORT, self->expected_dims);
96 - (void)releaseCGLContext:(CGLContextObj)glContext {
97 CGLReleaseContext (glContext);
100 - (void)drawInCGLContext:(CGLContextObj)glContext
101 pixelFormat:(CGLPixelFormatObj)pixelFormat
102 forLayerTime:(CFTimeInterval)interval
103 displayTime:(const CVTimeStamp *)timeStamp {
104 GstGLWindow *window = gst_gl_context_get_window (GST_GL_CONTEXT (self->gst_gl_context));
105 const GstGLFuncs *gl = ((GstGLContext *)self->gst_gl_context)->gl_vtable;
108 GST_LOG ("CAOpenGLLayer drawing with window %p cgl context %p", window, glContext);
110 /* attempt to get the correct viewport back due to CA being too smart
111 * and messing around with it so center the expected viewport into
112 * the CA viewport set up on entry to this function */
113 gl->GetIntegerv (GL_VIEWPORT, ca_viewport);
115 GstVideoRectangle src, dst, result;
117 src.x = self->expected_dims[0];
118 src.y = self->expected_dims[1];
119 src.w = self->expected_dims[2];
120 src.h = self->expected_dims[3];
122 dst.x = ca_viewport[0];
123 dst.y = ca_viewport[1];
124 dst.w = ca_viewport[2];
125 dst.h = ca_viewport[3];
127 gst_video_sink_center_rect (src, dst, &result, TRUE);
129 gl->Viewport (result.x, result.y, result.w, result.h);
132 gst_gl_window_cocoa_draw_thread (GST_GL_WINDOW_COCOA (window));
134 gst_object_unref (window);
137 /* flushes the buffer */
138 [super drawInCGLContext:glContext pixelFormat:pixelFormat forLayerTime:interval displayTime:timeStamp];