src/video/quartz/SDL_QuartzGL.m
changeset 761 c5b2b6d2d1fe
child 770 ac44ddb84f6f
equal deleted inserted replaced
760:cf9dd3aa6756 761:c5b2b6d2d1fe
       
     1 /*
       
     2     SDL - Simple DirectMedia Layer
       
     3     Copyright (C) 1997-2003  Sam Lantinga
       
     4 
       
     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.
       
     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     Library General Public License for more details.
       
    14 
       
    15     You should have received a copy of the GNU Library General Public
       
    16     License along with this library; if not, write to the Free
       
    17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    18 
       
    19     Sam Lantinga
       
    20     slouken@libsdl.org
       
    21 */
       
    22 
       
    23 #include "SDL_QuartzVideo.h"
       
    24 
       
    25 /* 
       
    26     This is a workaround to directly access NSOpenGLContext's CGL context
       
    27     We need this to check for errors NSOpenGLContext doesn't support
       
    28 */
       
    29 @interface NSOpenGLContext (CGLContextAccess)
       
    30 - (CGLContextObj) cglContext;
       
    31 @end
       
    32 
       
    33 @implementation NSOpenGLContext (CGLContextAccess)
       
    34 - (CGLContextObj) cglContext;
       
    35 {
       
    36     return _contextAuxiliary;
       
    37 }
       
    38 @end
       
    39 
       
    40 /* OpenGL helper functions (used internally) */
       
    41 
       
    42 int QZ_SetupOpenGL (_THIS, int bpp, Uint32 flags) {
       
    43 
       
    44     NSOpenGLPixelFormatAttribute attr[32];
       
    45     NSOpenGLPixelFormat *fmt;
       
    46     int i = 0;
       
    47     int colorBits = bpp;
       
    48 
       
    49     if ( flags & SDL_FULLSCREEN ) {
       
    50 
       
    51         attr[i++] = NSOpenGLPFAFullScreen;
       
    52     }
       
    53     /* In windowed mode, the OpenGL pixel depth must match device pixel depth */
       
    54     else if ( colorBits != device_bpp ) {
       
    55 
       
    56         colorBits = device_bpp;
       
    57     }
       
    58 
       
    59     attr[i++] = NSOpenGLPFAColorSize;
       
    60     attr[i++] = colorBits;
       
    61 
       
    62     attr[i++] = NSOpenGLPFADepthSize;
       
    63     attr[i++] = this->gl_config.depth_size;
       
    64 
       
    65     if ( this->gl_config.double_buffer ) {
       
    66         attr[i++] = NSOpenGLPFADoubleBuffer;
       
    67     }
       
    68 
       
    69     if ( this->gl_config.stereo ) {
       
    70         attr[i++] = NSOpenGLPFAStereo;
       
    71     }
       
    72 
       
    73     if ( this->gl_config.stencil_size != 0 ) {
       
    74         attr[i++] = NSOpenGLPFAStencilSize;
       
    75         attr[i++] = this->gl_config.stencil_size;
       
    76     }
       
    77 
       
    78 #if NSOPENGL_CURRENT_VERSION > 1  /* What version should this be? */
       
    79     if ( this->gl_config.multisamplebuffers != 0 ) {
       
    80         attr[i++] = NSOpenGLPFASampleBuffers;
       
    81         attr[i++] = this->gl_config.multisamplebuffers;
       
    82     }
       
    83 
       
    84     if ( this->gl_config.multisamplesamples != 0 ) {
       
    85         attr[i++] = NSOpenGLPFASamples;
       
    86         attr[i++] = this->gl_config.multisamplesamples;
       
    87     }
       
    88 #endif
       
    89 
       
    90     attr[i++] = NSOpenGLPFAScreenMask;
       
    91     attr[i++] = CGDisplayIDToOpenGLDisplayMask (display_id);
       
    92     attr[i] = 0;
       
    93 
       
    94     fmt = [ [ NSOpenGLPixelFormat alloc ] initWithAttributes:attr ];
       
    95     if (fmt == nil) {
       
    96         SDL_SetError ("Failed creating OpenGL pixel format");
       
    97         return 0;
       
    98     }
       
    99 
       
   100     gl_context = [ [ NSOpenGLContext alloc ] initWithFormat:fmt
       
   101                                                shareContext:nil];
       
   102 
       
   103     if (gl_context == nil) {
       
   104         SDL_SetError ("Failed creating OpenGL context");
       
   105         return 0;
       
   106     }
       
   107 
       
   108     /*
       
   109      * Wisdom from Apple engineer in reference to UT2003's OpenGL performance:
       
   110      *  "You are blowing a couple of the internal OpenGL function caches. This
       
   111      *  appears to be happening in the VAO case.  You can tell OpenGL to up
       
   112      *  the cache size by issuing the following calls right after you create
       
   113      *  the OpenGL context.  The default cache size is 16."    --ryan.
       
   114      */
       
   115 
       
   116     #ifndef GLI_ARRAY_FUNC_CACHE_MAX
       
   117     #define GLI_ARRAY_FUNC_CACHE_MAX 284
       
   118     #endif
       
   119 
       
   120     #ifndef GLI_SUBMIT_FUNC_CACHE_MAX
       
   121     #define GLI_SUBMIT_FUNC_CACHE_MAX 280
       
   122     #endif
       
   123 
       
   124     {
       
   125         long cache_max = 64;
       
   126         CGLContextObj ctx = [ gl_context cglContext ];
       
   127         CGLSetParameter (ctx, GLI_SUBMIT_FUNC_CACHE_MAX, &cache_max);
       
   128         CGLSetParameter (ctx, GLI_ARRAY_FUNC_CACHE_MAX, &cache_max);
       
   129     }
       
   130 
       
   131     /* End Wisdom from Apple Engineer section. --ryan. */
       
   132 
       
   133     /* Convince SDL that the GL "driver" is loaded */
       
   134     this->gl_config.driver_loaded = 1;
       
   135 
       
   136     [ fmt release ];
       
   137 
       
   138     return 1;
       
   139 }
       
   140 
       
   141 void QZ_TearDownOpenGL (_THIS) {
       
   142 
       
   143     [ NSOpenGLContext clearCurrentContext ];
       
   144     [ gl_context clearDrawable ];
       
   145     [ gl_context release ];
       
   146 }
       
   147 
       
   148 
       
   149 /* SDL OpenGL functions */
       
   150 
       
   151 int    QZ_GL_LoadLibrary    (_THIS, const char *location) {
       
   152     this->gl_config.driver_loaded = 1;
       
   153     return 1;
       
   154 }
       
   155 
       
   156 void*  QZ_GL_GetProcAddress (_THIS, const char *proc) {
       
   157 
       
   158     /* We may want to cache the bundleRef at some point */
       
   159     CFBundleRef bundle;
       
   160     CFURLRef bundleURL = CFURLCreateWithFileSystemPath (kCFAllocatorDefault,
       
   161                                                         CFSTR("/System/Library/Frameworks/OpenGL.framework"), kCFURLPOSIXPathStyle, true);
       
   162 
       
   163     CFStringRef functionName = CFStringCreateWithCString
       
   164         (kCFAllocatorDefault, proc, kCFStringEncodingASCII);
       
   165 
       
   166     void *function;
       
   167 
       
   168     bundle = CFBundleCreate (kCFAllocatorDefault, bundleURL);
       
   169     assert (bundle != NULL);
       
   170 
       
   171     function = CFBundleGetFunctionPointerForName (bundle, functionName);
       
   172 
       
   173     CFRelease ( bundleURL );
       
   174     CFRelease ( functionName );
       
   175     CFRelease ( bundle );
       
   176 
       
   177     return function;
       
   178 }
       
   179 
       
   180 int    QZ_GL_GetAttribute   (_THIS, SDL_GLattr attrib, int* value) {
       
   181 
       
   182     GLenum attr = 0;
       
   183 
       
   184     QZ_GL_MakeCurrent (this);
       
   185 
       
   186     switch (attrib) {
       
   187         case SDL_GL_RED_SIZE: attr = GL_RED_BITS;   break;
       
   188         case SDL_GL_BLUE_SIZE: attr = GL_BLUE_BITS;  break;
       
   189         case SDL_GL_GREEN_SIZE: attr = GL_GREEN_BITS; break;
       
   190         case SDL_GL_ALPHA_SIZE: attr = GL_ALPHA_BITS; break;
       
   191         case SDL_GL_DOUBLEBUFFER: attr = GL_DOUBLEBUFFER; break;
       
   192         case SDL_GL_DEPTH_SIZE: attr = GL_DEPTH_BITS;  break;
       
   193         case SDL_GL_STENCIL_SIZE: attr = GL_STENCIL_BITS; break;
       
   194         case SDL_GL_ACCUM_RED_SIZE: attr = GL_ACCUM_RED_BITS; break;
       
   195         case SDL_GL_ACCUM_GREEN_SIZE: attr = GL_ACCUM_GREEN_BITS; break;
       
   196         case SDL_GL_ACCUM_BLUE_SIZE: attr = GL_ACCUM_BLUE_BITS; break;
       
   197         case SDL_GL_ACCUM_ALPHA_SIZE: attr = GL_ACCUM_ALPHA_BITS; break;
       
   198         case SDL_GL_STEREO: attr = GL_STEREO; break;
       
   199         case SDL_GL_MULTISAMPLEBUFFERS: attr = GL_SAMPLE_BUFFERS_ARB; break;
       
   200         case SDL_GL_MULTISAMPLESAMPLES: attr = GL_SAMPLES_ARB; break;
       
   201         case SDL_GL_BUFFER_SIZE:
       
   202         {
       
   203             GLint bits = 0;
       
   204             GLint component;
       
   205 
       
   206             /* there doesn't seem to be a single flag in OpenGL for this! */
       
   207             glGetIntegerv (GL_RED_BITS, &component);   bits += component;
       
   208             glGetIntegerv (GL_GREEN_BITS,&component);  bits += component;
       
   209             glGetIntegerv (GL_BLUE_BITS, &component);  bits += component;
       
   210             glGetIntegerv (GL_ALPHA_BITS, &component); bits += component;
       
   211 
       
   212             *value = bits;
       
   213         }
       
   214         return 0;
       
   215     }
       
   216 
       
   217     glGetIntegerv (attr, (GLint *)value);
       
   218     return 0;
       
   219 }
       
   220 
       
   221 int    QZ_GL_MakeCurrent    (_THIS) {
       
   222     [ gl_context makeCurrentContext ];
       
   223     return 0;
       
   224 }
       
   225 
       
   226 void   QZ_GL_SwapBuffers    (_THIS) {
       
   227     [ gl_context flushBuffer ];
       
   228 }