src/video/cocoa/SDL_cocoaopengl.m
author Sam Lantinga <slouken@libsdl.org>
Wed, 01 Dec 2010 12:23:16 -0800
changeset 4925 514f811a4887
parent 4498 3d91e31fcf71
child 5246 58265e606e4e
permissions -rw-r--r--
Removed support for 10.3.9
Fixed building on Mac OS X 10.5
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2010 Sam Lantinga
     4 
     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.
     9 
    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.
    14 
    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
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 #include "SDL_cocoavideo.h"
    25 
    26 /* NSOpenGL implementation of SDL OpenGL support */
    27 
    28 #if SDL_VIDEO_OPENGL_CGL
    29 #include <OpenGL/CGLTypes.h>
    30 #include <OpenGL/OpenGL.h>
    31 #include <OpenGL/CGLRenderers.h>
    32 
    33 #include "SDL_loadso.h"
    34 #include "SDL_opengl.h"
    35 
    36 
    37 #define DEFAULT_OPENGL  "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib"
    38 
    39 int
    40 Cocoa_GL_LoadLibrary(_THIS, const char *path)
    41 {
    42     /* Load the OpenGL library */
    43     if (path == NULL) {
    44         path = SDL_getenv("SDL_OPENGL_LIBRARY");
    45     }
    46     if (path == NULL) {
    47         path = DEFAULT_OPENGL;
    48     }
    49     _this->gl_config.dll_handle = SDL_LoadObject(path);
    50     if (!_this->gl_config.dll_handle) {
    51         return -1;
    52     }
    53     SDL_strlcpy(_this->gl_config.driver_path, path,
    54                 SDL_arraysize(_this->gl_config.driver_path));
    55     return 0;
    56 }
    57 
    58 void *
    59 Cocoa_GL_GetProcAddress(_THIS, const char *proc)
    60 {
    61     return SDL_LoadFunction(_this->gl_config.dll_handle, proc);
    62 }
    63 
    64 void
    65 Cocoa_GL_UnloadLibrary(_THIS)
    66 {
    67     SDL_UnloadObject(_this->gl_config.dll_handle);
    68     _this->gl_config.dll_handle = NULL;
    69 }
    70 
    71 SDL_GLContext
    72 Cocoa_GL_CreateContext(_THIS, SDL_Window * window)
    73 {
    74     NSAutoreleasePool *pool;
    75     SDL_VideoDisplay *display = window->display;
    76     SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata;
    77     NSOpenGLPixelFormatAttribute attr[32];
    78     NSOpenGLPixelFormat *fmt;
    79     NSOpenGLContext *context;
    80     int i = 0;
    81 
    82     pool = [[NSAutoreleasePool alloc] init];
    83 
    84     if (window->flags & SDL_WINDOW_FULLSCREEN) {
    85         attr[i++] = NSOpenGLPFAFullScreen;
    86     }
    87 
    88     attr[i++] = NSOpenGLPFAColorSize;
    89     attr[i++] = SDL_BYTESPERPIXEL(display->current_mode.format)*8;
    90 
    91     attr[i++] = NSOpenGLPFADepthSize;
    92     attr[i++] = _this->gl_config.depth_size;
    93 
    94     if (_this->gl_config.double_buffer) {
    95         attr[i++] = NSOpenGLPFADoubleBuffer;
    96     }
    97 
    98     if (_this->gl_config.stereo) {
    99         attr[i++] = NSOpenGLPFAStereo;
   100     }
   101 
   102     if (_this->gl_config.stencil_size) {
   103         attr[i++] = NSOpenGLPFAStencilSize;
   104         attr[i++] = _this->gl_config.stencil_size;
   105     }
   106 
   107     if ((_this->gl_config.accum_red_size +
   108          _this->gl_config.accum_green_size +
   109          _this->gl_config.accum_blue_size +
   110          _this->gl_config.accum_alpha_size) > 0) {
   111         attr[i++] = NSOpenGLPFAAccumSize;
   112         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;
   113     }
   114 
   115     if (_this->gl_config.multisamplebuffers) {
   116         attr[i++] = NSOpenGLPFASampleBuffers;
   117         attr[i++] = _this->gl_config.multisamplebuffers;
   118     }
   119 
   120     if (_this->gl_config.multisamplesamples) {
   121         attr[i++] = NSOpenGLPFASamples;
   122         attr[i++] = _this->gl_config.multisamplesamples;
   123         attr[i++] = NSOpenGLPFANoRecovery;
   124     }
   125 
   126     if (_this->gl_config.accelerated >= 0) {
   127         if (_this->gl_config.accelerated) {
   128             attr[i++] = NSOpenGLPFAAccelerated;
   129         } else {
   130             attr[i++] = NSOpenGLPFARendererID;
   131             attr[i++] = kCGLRendererGenericFloatID;
   132         }
   133     }
   134 
   135     attr[i++] = NSOpenGLPFAScreenMask;
   136     attr[i++] = CGDisplayIDToOpenGLDisplayMask(displaydata->display);
   137     attr[i] = 0;
   138 
   139     fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr];
   140     if (fmt == nil) {
   141         SDL_SetError ("Failed creating OpenGL pixel format");
   142         [pool release];
   143         return NULL;
   144     }
   145 
   146     context = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:nil];
   147 
   148     [fmt release];
   149 
   150     if (context == nil) {
   151         SDL_SetError ("Failed creating OpenGL context");
   152         [pool release];
   153         return NULL;
   154     }
   155 
   156     /*
   157      * Wisdom from Apple engineer in reference to UT2003's OpenGL performance:
   158      *  "You are blowing a couple of the internal OpenGL function caches. This
   159      *  appears to be happening in the VAO case.  You can tell OpenGL to up
   160      *  the cache size by issuing the following calls right after you create
   161      *  the OpenGL context.  The default cache size is 16."    --ryan.
   162      */
   163 
   164     #ifndef GLI_ARRAY_FUNC_CACHE_MAX
   165     #define GLI_ARRAY_FUNC_CACHE_MAX 284
   166     #endif
   167 
   168     #ifndef GLI_SUBMIT_FUNC_CACHE_MAX
   169     #define GLI_SUBMIT_FUNC_CACHE_MAX 280
   170     #endif
   171 
   172     {
   173         GLint cache_max = 64;
   174         CGLContextObj ctx = [context CGLContextObj];
   175         CGLSetParameter (ctx, GLI_SUBMIT_FUNC_CACHE_MAX, &cache_max);
   176         CGLSetParameter (ctx, GLI_ARRAY_FUNC_CACHE_MAX, &cache_max);
   177     }
   178 
   179     /* End Wisdom from Apple Engineer section. --ryan. */
   180 
   181     [pool release];
   182 
   183     if ( Cocoa_GL_MakeCurrent(_this, window, context) < 0 ) {
   184         Cocoa_GL_DeleteContext(_this, context);
   185         return NULL;
   186     }
   187 
   188     return context;
   189 }
   190 
   191 int
   192 Cocoa_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
   193 {
   194     NSAutoreleasePool *pool;
   195 
   196     pool = [[NSAutoreleasePool alloc] init];
   197 
   198     if (context) {
   199         SDL_WindowData *windowdata = (SDL_WindowData *)window->driverdata;
   200         NSOpenGLContext *nscontext = (NSOpenGLContext *)context;
   201 
   202         if (window->flags & SDL_WINDOW_FULLSCREEN) {
   203             [nscontext setFullScreen];
   204         } else {
   205             [nscontext setView:[windowdata->nswindow contentView]];
   206             [nscontext update];
   207         }
   208         [nscontext makeCurrentContext];
   209     } else {
   210         [NSOpenGLContext clearCurrentContext];
   211     }
   212 
   213     [pool release];
   214     return 0;
   215 }
   216 
   217 int
   218 Cocoa_GL_SetSwapInterval(_THIS, int interval)
   219 {
   220     NSAutoreleasePool *pool;
   221     NSOpenGLContext *nscontext;
   222     GLint value;
   223     int status;
   224 
   225     pool = [[NSAutoreleasePool alloc] init];
   226 
   227     nscontext = [NSOpenGLContext currentContext];
   228     if (nscontext != nil) {
   229         value = interval;
   230         [nscontext setValues:&value forParameter:NSOpenGLCPSwapInterval];
   231         status = 0;
   232     } else {
   233         SDL_SetError("No current OpenGL context");
   234         status = -1;
   235     }
   236 
   237     [pool release];
   238     return status;
   239 }
   240 
   241 int
   242 Cocoa_GL_GetSwapInterval(_THIS)
   243 {
   244     NSAutoreleasePool *pool;
   245     NSOpenGLContext *nscontext;
   246     GLint value;
   247     int status;
   248 
   249     pool = [[NSAutoreleasePool alloc] init];
   250 
   251     nscontext = [NSOpenGLContext currentContext];
   252     if (nscontext != nil) {
   253         [nscontext getValues:&value forParameter:NSOpenGLCPSwapInterval];
   254         status = (int)value;
   255     } else {
   256         SDL_SetError("No current OpenGL context");
   257         status = -1;
   258     }
   259 
   260     [pool release];
   261     return status;
   262 }
   263 
   264 void
   265 Cocoa_GL_SwapWindow(_THIS, SDL_Window * window)
   266 {
   267     NSAutoreleasePool *pool;
   268     NSOpenGLContext *nscontext;
   269 
   270     pool = [[NSAutoreleasePool alloc] init];
   271 
   272     /* FIXME: Do we need to get the context for the window? */
   273     nscontext = [NSOpenGLContext currentContext];
   274     if (nscontext != nil) {
   275         [nscontext flushBuffer];
   276     }
   277 
   278     [pool release];
   279 }
   280 
   281 void
   282 Cocoa_GL_DeleteContext(_THIS, SDL_GLContext context)
   283 {
   284     NSAutoreleasePool *pool;
   285     NSOpenGLContext *nscontext = (NSOpenGLContext *)context;
   286 
   287     pool = [[NSAutoreleasePool alloc] init];
   288 
   289     [nscontext clearDrawable];
   290     [nscontext release];
   291 
   292     [pool release];
   293 }
   294 
   295 #endif /* SDL_VIDEO_OPENGL_CGL */
   296 
   297 /* vi: set ts=4 sw=4 expandtab: */