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