Allow the render context to do necessary work when the video mode changes.
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2006 Sam Lantinga
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 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 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "SDL_config.h"
24 #include "SDL_cocoavideo.h"
26 /* NSOpenGL implementation of SDL OpenGL support */
28 #if SDL_VIDEO_OPENGL_CGL
29 #include <OpenGL/CGLTypes.h>
31 #include "SDL_loadso.h"
32 #include "SDL_opengl.h"
35 #define DEFAULT_OPENGL "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib"
37 /* This is implemented in Mac OS X 10.3 and above */
38 #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3
39 @implementation NSOpenGLContext(CGLContextAccess)
40 - (CGLContextObj)CGLContextObj;
42 return _contextAuxiliary;
48 Cocoa_GL_LoadLibrary(_THIS, const char *path)
50 if (_this->gl_config.driver_loaded) {
52 SDL_SetError("OpenGL library already loaded");
55 ++_this->gl_config.driver_loaded;
60 path = SDL_getenv("SDL_OPENGL_LIBRARY");
63 path = DEFAULT_OPENGL;
65 _this->gl_config.dll_handle = SDL_LoadObject(path);
66 if (!_this->gl_config.dll_handle) {
69 SDL_strlcpy(_this->gl_config.driver_path, path,
70 SDL_arraysize(_this->gl_config.driver_path));
71 _this->gl_config.driver_loaded = 1;
76 Cocoa_GL_GetProcAddress(_THIS, const char *proc)
78 return SDL_LoadFunction(_this->gl_config.dll_handle, proc);
82 Cocoa_GL_UnloadLibrary(_THIS)
84 if (_this->gl_config.driver_loaded > 0) {
85 if (--_this->gl_config.driver_loaded > 0) {
88 SDL_UnloadObject(_this->gl_config.dll_handle);
89 _this->gl_config.dll_handle = NULL;
94 Cocoa_GL_Initialize(_THIS)
97 ++_this->gl_data->initialized;
102 (struct SDL_GLDriverData *) SDL_calloc(1,
105 if (!_this->gl_data) {
109 _this->gl_data->initialized = 1;
111 if (Cocoa_GL_LoadLibrary(_this, NULL) < 0) {
118 Cocoa_GL_Shutdown(_THIS)
120 if (!_this->gl_data || (--_this->gl_data->initialized > 0)) {
124 Cocoa_GL_UnloadLibrary(_this);
126 SDL_free(_this->gl_data);
127 _this->gl_data = NULL;
131 Cocoa_GL_SetupWindow(_THIS, SDL_Window * window)
133 if (Cocoa_GL_Initialize(_this) < 0) {
140 Cocoa_GL_CleanupWindow(_THIS, SDL_Window * window)
142 Cocoa_GL_Shutdown(_this);
146 Cocoa_GL_CreateContext(_THIS, SDL_Window * window)
148 NSAutoreleasePool *pool;
149 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
150 SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata;
151 NSOpenGLPixelFormatAttribute attr[32];
152 NSOpenGLPixelFormat *fmt;
153 NSOpenGLContext *nscontext;
156 pool = [[NSAutoreleasePool alloc] init];
158 if (window->flags & SDL_WINDOW_FULLSCREEN) {
159 attr[i++] = NSOpenGLPFAFullScreen;
162 attr[i++] = NSOpenGLPFAColorSize;
163 attr[i++] = SDL_BYTESPERPIXEL(display->current_mode.format)*8;
165 attr[i++] = NSOpenGLPFADepthSize;
166 attr[i++] = _this->gl_config.depth_size;
168 if (_this->gl_config.double_buffer) {
169 attr[i++] = NSOpenGLPFADoubleBuffer;
172 if (_this->gl_config.stereo) {
173 attr[i++] = NSOpenGLPFAStereo;
176 if (_this->gl_config.stencil_size) {
177 attr[i++] = NSOpenGLPFAStencilSize;
178 attr[i++] = _this->gl_config.stencil_size;
181 if ((_this->gl_config.accum_red_size +
182 _this->gl_config.accum_green_size +
183 _this->gl_config.accum_blue_size +
184 _this->gl_config.accum_alpha_size) > 0) {
185 attr[i++] = NSOpenGLPFAAccumSize;
186 attr[i++] = _this->gl_config.accum_red_size + _this->gl_config.accum_green_size + _this->gl_config.accum_blue_size + _this->gl_config.accum_alpha_size;
189 if (_this->gl_config.multisamplebuffers) {
190 attr[i++] = NSOpenGLPFASampleBuffers;
191 attr[i++] = _this->gl_config.multisamplebuffers;
194 if (_this->gl_config.multisamplesamples) {
195 attr[i++] = NSOpenGLPFASamples;
196 attr[i++] = _this->gl_config.multisamplesamples;
197 attr[i++] = NSOpenGLPFANoRecovery;
200 if (_this->gl_config.accelerated > 0) {
201 attr[i++] = NSOpenGLPFAAccelerated;
204 attr[i++] = NSOpenGLPFAScreenMask;
205 attr[i++] = CGDisplayIDToOpenGLDisplayMask(displaydata->display);
208 fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr];
210 SDL_SetError ("Failed creating OpenGL pixel format");
215 nscontext = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:nil];
219 if (nscontext == nil) {
220 SDL_SetError ("Failed creating OpenGL context");
226 * Wisdom from Apple engineer in reference to UT2003's OpenGL performance:
227 * "You are blowing a couple of the internal OpenGL function caches. This
228 * appears to be happening in the VAO case. You can tell OpenGL to up
229 * the cache size by issuing the following calls right after you create
230 * the OpenGL context. The default cache size is 16." --ryan.
233 #ifndef GLI_ARRAY_FUNC_CACHE_MAX
234 #define GLI_ARRAY_FUNC_CACHE_MAX 284
237 #ifndef GLI_SUBMIT_FUNC_CACHE_MAX
238 #define GLI_SUBMIT_FUNC_CACHE_MAX 280
243 CGLContextObj ctx = [nscontext CGLContextObj];
244 CGLSetParameter (ctx, GLI_SUBMIT_FUNC_CACHE_MAX, &cache_max);
245 CGLSetParameter (ctx, GLI_ARRAY_FUNC_CACHE_MAX, &cache_max);
248 /* End Wisdom from Apple Engineer section. --ryan. */
250 /* FIXME: should this go somewhere else? */
251 if (window->flags & SDL_WINDOW_FULLSCREEN) {
252 [nscontext setFullScreen];
260 Cocoa_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
262 NSAutoreleasePool *pool;
264 pool = [[NSAutoreleasePool alloc] init];
267 SDL_WindowData *windowdata = (SDL_WindowData *)window->driverdata;
268 NSOpenGLContext *nscontext = (NSOpenGLContext *)context;
270 [nscontext setView:[windowdata->window contentView]];
272 [nscontext makeCurrentContext];
274 [NSOpenGLContext clearCurrentContext];
282 Cocoa_GL_SetSwapInterval(_THIS, int interval)
284 NSAutoreleasePool *pool;
285 NSOpenGLContext *nscontext;
289 pool = [[NSAutoreleasePool alloc] init];
291 nscontext = [NSOpenGLContext currentContext];
292 if (nscontext != nil) {
294 [nscontext setValues:&value forParameter:NSOpenGLCPSwapInterval];
297 SDL_SetError("No current OpenGL context");
306 Cocoa_GL_GetSwapInterval(_THIS)
308 NSAutoreleasePool *pool;
309 NSOpenGLContext *nscontext;
313 pool = [[NSAutoreleasePool alloc] init];
315 nscontext = [NSOpenGLContext currentContext];
316 if (nscontext != nil) {
317 [nscontext getValues:&value forParameter:NSOpenGLCPSwapInterval];
320 SDL_SetError("No current OpenGL context");
329 Cocoa_GL_SwapWindow(_THIS, SDL_Window * window)
331 NSAutoreleasePool *pool;
332 NSOpenGLContext *nscontext;
334 pool = [[NSAutoreleasePool alloc] init];
336 /* FIXME: Do we need to get the context for the window? */
337 nscontext = [NSOpenGLContext currentContext];
338 if (nscontext != nil) {
339 [nscontext flushBuffer];
346 Cocoa_GL_DeleteContext(_THIS, SDL_GLContext context)
348 NSAutoreleasePool *pool;
349 NSOpenGLContext *nscontext = (NSOpenGLContext *)context;
351 pool = [[NSAutoreleasePool alloc] init];
353 [nscontext clearDrawable];
359 #endif /* SDL_VIDEO_OPENGL_CGL */
361 /* vi: set ts=4 sw=4 expandtab: */