src/video/cocoa/SDL_cocoaopengl.m
changeset 6832 156e608ec4ef
parent 6567 d50613615139
child 6848 478ecc8a58b3
equal deleted inserted replaced
6831:935b871e1ffe 6832:156e608ec4ef
    78 Cocoa_GL_CreateContext(_THIS, SDL_Window * window)
    78 Cocoa_GL_CreateContext(_THIS, SDL_Window * window)
    79 {
    79 {
    80     const int wantver = (_this->gl_config.major_version << 8) |
    80     const int wantver = (_this->gl_config.major_version << 8) |
    81                         (_this->gl_config.minor_version);
    81                         (_this->gl_config.minor_version);
    82     SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
    82     SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
    83     NSAutoreleasePool *pool;
       
    84     SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
    83     SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
    85     SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata;
    84     SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata;
    86     NSOpenGLPixelFormatAttribute attr[32];
    85     NSOpenGLPixelFormatAttribute attr[32];
    87     NSOpenGLPixelFormat *fmt;
    86     NSOpenGLPixelFormat *fmt;
    88     NSOpenGLContext *context;
    87     NSOpenGLContext *context;
    98     if (wantver > 0x0302) {
    97     if (wantver > 0x0302) {
    99         SDL_SetError ("OpenGL > 3.2 is not supported on this platform");
    98         SDL_SetError ("OpenGL > 3.2 is not supported on this platform");
   100         return NULL;
    99         return NULL;
   101     }
   100     }
   102 
   101 
   103     pool = [[NSAutoreleasePool alloc] init];
   102     @autoreleasepool {
   104 
   103         /* specify a profile if we're on Lion (10.7) or later. */
   105     /* specify a profile if we're on Lion (10.7) or later. */
   104         if (data->osversion >= 0x1070) {
   106     if (data->osversion >= 0x1070) {
   105             NSOpenGLPixelFormatAttribute profile = kCGLOGLPVersion_Legacy;
   107         NSOpenGLPixelFormatAttribute profile = kCGLOGLPVersion_Legacy;
   106             if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_CORE) {
   108         if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_CORE) {
   107                 if (wantver == 0x0302) {
   109             if (wantver == 0x0302) {
   108                     profile = kCGLOGLPVersion_3_2_Core;
   110                 profile = kCGLOGLPVersion_3_2_Core;
   109                 }
   111             }
   110             }
   112         }
   111             attr[i++] = kCGLPFAOpenGLProfile;
   113         attr[i++] = kCGLPFAOpenGLProfile;
   112             attr[i++] = profile;
   114         attr[i++] = profile;
   113         }
   115     }
   114 
   116 
   115     #ifndef FULLSCREEN_TOGGLEABLE
   117 #ifndef FULLSCREEN_TOGGLEABLE
   116         if (window->flags & SDL_WINDOW_FULLSCREEN) {
   118     if (window->flags & SDL_WINDOW_FULLSCREEN) {
   117             attr[i++] = NSOpenGLPFAFullScreen;
   119         attr[i++] = NSOpenGLPFAFullScreen;
   118         }
   120     }
       
   121 #endif
       
   122 
       
   123     attr[i++] = NSOpenGLPFAColorSize;
       
   124     attr[i++] = SDL_BYTESPERPIXEL(display->current_mode.format)*8;
       
   125 
       
   126     attr[i++] = NSOpenGLPFADepthSize;
       
   127     attr[i++] = _this->gl_config.depth_size;
       
   128 
       
   129     if (_this->gl_config.double_buffer) {
       
   130         attr[i++] = NSOpenGLPFADoubleBuffer;
       
   131     }
       
   132 
       
   133     if (_this->gl_config.stereo) {
       
   134         attr[i++] = NSOpenGLPFAStereo;
       
   135     }
       
   136 
       
   137     if (_this->gl_config.stencil_size) {
       
   138         attr[i++] = NSOpenGLPFAStencilSize;
       
   139         attr[i++] = _this->gl_config.stencil_size;
       
   140     }
       
   141 
       
   142     if ((_this->gl_config.accum_red_size +
       
   143          _this->gl_config.accum_green_size +
       
   144          _this->gl_config.accum_blue_size +
       
   145          _this->gl_config.accum_alpha_size) > 0) {
       
   146         attr[i++] = NSOpenGLPFAAccumSize;
       
   147         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;
       
   148     }
       
   149 
       
   150     if (_this->gl_config.multisamplebuffers) {
       
   151         attr[i++] = NSOpenGLPFASampleBuffers;
       
   152         attr[i++] = _this->gl_config.multisamplebuffers;
       
   153     }
       
   154 
       
   155     if (_this->gl_config.multisamplesamples) {
       
   156         attr[i++] = NSOpenGLPFASamples;
       
   157         attr[i++] = _this->gl_config.multisamplesamples;
       
   158         attr[i++] = NSOpenGLPFANoRecovery;
       
   159     }
       
   160 
       
   161     if (_this->gl_config.accelerated >= 0) {
       
   162         if (_this->gl_config.accelerated) {
       
   163             attr[i++] = NSOpenGLPFAAccelerated;
       
   164         } else {
       
   165             attr[i++] = NSOpenGLPFARendererID;
       
   166             attr[i++] = kCGLRendererGenericFloatID;
       
   167         }
       
   168     }
       
   169 
       
   170     attr[i++] = NSOpenGLPFAScreenMask;
       
   171     attr[i++] = CGDisplayIDToOpenGLDisplayMask(displaydata->display);
       
   172     attr[i] = 0;
       
   173 
       
   174     fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr];
       
   175     if (fmt == nil) {
       
   176         SDL_SetError ("Failed creating OpenGL pixel format");
       
   177         [pool release];
       
   178         return NULL;
       
   179     }
       
   180 
       
   181     context = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:nil];
       
   182 
       
   183     [fmt release];
       
   184 
       
   185     if (context == nil) {
       
   186         SDL_SetError ("Failed creating OpenGL context");
       
   187         [pool release];
       
   188         return NULL;
       
   189     }
       
   190 
       
   191     /*
       
   192      * Wisdom from Apple engineer in reference to UT2003's OpenGL performance:
       
   193      *  "You are blowing a couple of the internal OpenGL function caches. This
       
   194      *  appears to be happening in the VAO case.  You can tell OpenGL to up
       
   195      *  the cache size by issuing the following calls right after you create
       
   196      *  the OpenGL context.  The default cache size is 16."    --ryan.
       
   197      */
       
   198 
       
   199     #ifndef GLI_ARRAY_FUNC_CACHE_MAX
       
   200     #define GLI_ARRAY_FUNC_CACHE_MAX 284
       
   201     #endif
   119     #endif
   202 
   120 
   203     #ifndef GLI_SUBMIT_FUNC_CACHE_MAX
   121         attr[i++] = NSOpenGLPFAColorSize;
   204     #define GLI_SUBMIT_FUNC_CACHE_MAX 280
   122         attr[i++] = SDL_BYTESPERPIXEL(display->current_mode.format)*8;
   205     #endif
   123 
   206 
   124         attr[i++] = NSOpenGLPFADepthSize;
   207     {
   125         attr[i++] = _this->gl_config.depth_size;
   208         GLint cache_max = 64;
   126 
   209         CGLContextObj ctx = [context CGLContextObj];
   127         if (_this->gl_config.double_buffer) {
   210         CGLSetParameter (ctx, GLI_SUBMIT_FUNC_CACHE_MAX, &cache_max);
   128             attr[i++] = NSOpenGLPFADoubleBuffer;
   211         CGLSetParameter (ctx, GLI_ARRAY_FUNC_CACHE_MAX, &cache_max);
   129         }
   212     }
   130 
   213 
   131         if (_this->gl_config.stereo) {
       
   132             attr[i++] = NSOpenGLPFAStereo;
       
   133         }
       
   134 
       
   135         if (_this->gl_config.stencil_size) {
       
   136             attr[i++] = NSOpenGLPFAStencilSize;
       
   137             attr[i++] = _this->gl_config.stencil_size;
       
   138         }
       
   139 
       
   140         if ((_this->gl_config.accum_red_size +
       
   141              _this->gl_config.accum_green_size +
       
   142              _this->gl_config.accum_blue_size +
       
   143              _this->gl_config.accum_alpha_size) > 0) {
       
   144             attr[i++] = NSOpenGLPFAAccumSize;
       
   145             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;
       
   146         }
       
   147 
       
   148         if (_this->gl_config.multisamplebuffers) {
       
   149             attr[i++] = NSOpenGLPFASampleBuffers;
       
   150             attr[i++] = _this->gl_config.multisamplebuffers;
       
   151         }
       
   152 
       
   153         if (_this->gl_config.multisamplesamples) {
       
   154             attr[i++] = NSOpenGLPFASamples;
       
   155             attr[i++] = _this->gl_config.multisamplesamples;
       
   156             attr[i++] = NSOpenGLPFANoRecovery;
       
   157         }
       
   158 
       
   159         if (_this->gl_config.accelerated >= 0) {
       
   160             if (_this->gl_config.accelerated) {
       
   161                 attr[i++] = NSOpenGLPFAAccelerated;
       
   162             } else {
       
   163                 attr[i++] = NSOpenGLPFARendererID;
       
   164                 attr[i++] = kCGLRendererGenericFloatID;
       
   165             }
       
   166         }
       
   167 
       
   168         attr[i++] = NSOpenGLPFAScreenMask;
       
   169         attr[i++] = CGDisplayIDToOpenGLDisplayMask(displaydata->display);
       
   170         attr[i] = 0;
       
   171 
       
   172         fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr];
       
   173         if (fmt == nil) {
       
   174             SDL_SetError ("Failed creating OpenGL pixel format");
       
   175             return NULL;
       
   176         }
       
   177 
       
   178         context = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:nil];
       
   179 
       
   180         [fmt release];
       
   181 
       
   182         if (context == nil) {
       
   183             SDL_SetError ("Failed creating OpenGL context");
       
   184             return NULL;
       
   185         }
       
   186 
       
   187         /*
       
   188          * Wisdom from Apple engineer in reference to UT2003's OpenGL performance:
       
   189          *  "You are blowing a couple of the internal OpenGL function caches. This
       
   190          *  appears to be happening in the VAO case.  You can tell OpenGL to up
       
   191          *  the cache size by issuing the following calls right after you create
       
   192          *  the OpenGL context.  The default cache size is 16."    --ryan.
       
   193          */
       
   194 
       
   195         #ifndef GLI_ARRAY_FUNC_CACHE_MAX
       
   196         #define GLI_ARRAY_FUNC_CACHE_MAX 284
       
   197         #endif
       
   198 
       
   199         #ifndef GLI_SUBMIT_FUNC_CACHE_MAX
       
   200         #define GLI_SUBMIT_FUNC_CACHE_MAX 280
       
   201         #endif
       
   202 
       
   203         {
       
   204             GLint cache_max = 64;
       
   205             CGLContextObj ctx = [context CGLContextObj];
       
   206             CGLSetParameter (ctx, GLI_SUBMIT_FUNC_CACHE_MAX, &cache_max);
       
   207             CGLSetParameter (ctx, GLI_ARRAY_FUNC_CACHE_MAX, &cache_max);
       
   208         }
       
   209     }
   214     /* End Wisdom from Apple Engineer section. --ryan. */
   210     /* End Wisdom from Apple Engineer section. --ryan. */
   215 
       
   216     [pool release];
       
   217 
   211 
   218     if ( Cocoa_GL_MakeCurrent(_this, window, context) < 0 ) {
   212     if ( Cocoa_GL_MakeCurrent(_this, window, context) < 0 ) {
   219         Cocoa_GL_DeleteContext(_this, context);
   213         Cocoa_GL_DeleteContext(_this, context);
   220         return NULL;
   214         return NULL;
   221     }
   215     }
   224 }
   218 }
   225 
   219 
   226 int
   220 int
   227 Cocoa_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
   221 Cocoa_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
   228 {
   222 {
   229     NSAutoreleasePool *pool;
   223     @autoreleasepool {
   230 
   224         if (context) {
   231     pool = [[NSAutoreleasePool alloc] init];
   225             SDL_WindowData *windowdata = (SDL_WindowData *)window->driverdata;
   232 
   226             NSOpenGLContext *nscontext = (NSOpenGLContext *)context;
   233     if (context) {
   227 
   234         SDL_WindowData *windowdata = (SDL_WindowData *)window->driverdata;
   228             if (window->flags & SDL_WINDOW_SHOWN) {
   235         NSOpenGLContext *nscontext = (NSOpenGLContext *)context;
   229     #ifndef FULLSCREEN_TOGGLEABLE
   236 
   230                 if (window->flags & SDL_WINDOW_FULLSCREEN) {
   237         if (window->flags & SDL_WINDOW_SHOWN) {
   231                     [nscontext setFullScreen];
   238 #ifndef FULLSCREEN_TOGGLEABLE
   232                 } else
   239             if (window->flags & SDL_WINDOW_FULLSCREEN) {
   233     #endif
   240                 [nscontext setFullScreen];
   234                 {
   241             } else
   235                     [nscontext setView:[windowdata->nswindow contentView]];
   242 #endif
   236                     [nscontext update];
   243             {
   237                 }
   244                 [nscontext setView:[windowdata->nswindow contentView]];
       
   245                 [nscontext update];
       
   246             }
   238             }
   247         }
   239             [nscontext makeCurrentContext];
   248         [nscontext makeCurrentContext];
   240         } else {
   249     } else {
   241             [NSOpenGLContext clearCurrentContext];
   250         [NSOpenGLContext clearCurrentContext];
   242         }
   251     }
   243     }
   252 
   244 
   253     [pool release];
       
   254     return 0;
   245     return 0;
   255 }
   246 }
   256 
   247 
   257 int
   248 int
   258 Cocoa_GL_SetSwapInterval(_THIS, int interval)
   249 Cocoa_GL_SetSwapInterval(_THIS, int interval)
   259 {
   250 {
   260     NSAutoreleasePool *pool;
       
   261     NSOpenGLContext *nscontext;
   251     NSOpenGLContext *nscontext;
   262     GLint value;
   252     GLint value;
   263     int status;
   253     int status;
   264 
   254 
   265     pool = [[NSAutoreleasePool alloc] init];
   255     @autoreleasepool {
   266 
   256         nscontext = [NSOpenGLContext currentContext];
   267     nscontext = [NSOpenGLContext currentContext];
   257         if (nscontext != nil) {
   268     if (nscontext != nil) {
   258             value = interval;
   269         value = interval;
   259             [nscontext setValues:&value forParameter:NSOpenGLCPSwapInterval];
   270         [nscontext setValues:&value forParameter:NSOpenGLCPSwapInterval];
   260             status = 0;
   271         status = 0;
   261         } else {
   272     } else {
   262             SDL_SetError("No current OpenGL context");
   273         SDL_SetError("No current OpenGL context");
   263             status = -1;
   274         status = -1;
   264         }
   275     }
   265     }
   276 
   266 
   277     [pool release];
       
   278     return status;
   267     return status;
   279 }
   268 }
   280 
   269 
   281 int
   270 int
   282 Cocoa_GL_GetSwapInterval(_THIS)
   271 Cocoa_GL_GetSwapInterval(_THIS)
   283 {
   272 {
   284     NSAutoreleasePool *pool;
       
   285     NSOpenGLContext *nscontext;
   273     NSOpenGLContext *nscontext;
   286     GLint value;
   274     GLint value;
   287     int status = 0;
   275     int status = 0;
   288 
   276 
   289     pool = [[NSAutoreleasePool alloc] init];
   277     @autoreleasepool {
   290 
   278         nscontext = [NSOpenGLContext currentContext];
   291     nscontext = [NSOpenGLContext currentContext];
   279         if (nscontext != nil) {
   292     if (nscontext != nil) {
   280             [nscontext getValues:&value forParameter:NSOpenGLCPSwapInterval];
   293         [nscontext getValues:&value forParameter:NSOpenGLCPSwapInterval];
   281             status = (int)value;
   294         status = (int)value;
   282         }
   295     }
   283     }
   296 
   284 
   297     [pool release];
       
   298     return status;
   285     return status;
   299 }
   286 }
   300 
   287 
   301 void
   288 void
   302 Cocoa_GL_SwapWindow(_THIS, SDL_Window * window)
   289 Cocoa_GL_SwapWindow(_THIS, SDL_Window * window)
   303 {
   290 {
   304     NSAutoreleasePool *pool;
       
   305     NSOpenGLContext *nscontext;
   291     NSOpenGLContext *nscontext;
   306 
   292 
   307     pool = [[NSAutoreleasePool alloc] init];
   293     @autoreleasepool {
   308 
   294         /* FIXME: Do we need to get the context for the window? */
   309     /* FIXME: Do we need to get the context for the window? */
   295         nscontext = [NSOpenGLContext currentContext];
   310     nscontext = [NSOpenGLContext currentContext];
   296         if (nscontext != nil) {
   311     if (nscontext != nil) {
   297             [nscontext flushBuffer];
   312         [nscontext flushBuffer];
   298         }
   313     }
   299     }
   314 
       
   315     [pool release];
       
   316 }
   300 }
   317 
   301 
   318 void
   302 void
   319 Cocoa_GL_DeleteContext(_THIS, SDL_GLContext context)
   303 Cocoa_GL_DeleteContext(_THIS, SDL_GLContext context)
   320 {
   304 {
   321     NSAutoreleasePool *pool;
       
   322     NSOpenGLContext *nscontext = (NSOpenGLContext *)context;
   305     NSOpenGLContext *nscontext = (NSOpenGLContext *)context;
   323 
   306 
   324     pool = [[NSAutoreleasePool alloc] init];
   307     @autoreleasepool {
   325 
   308         [nscontext clearDrawable];
   326     [nscontext clearDrawable];
   309         [nscontext release];
   327     [nscontext release];
   310     }
   328 
       
   329     [pool release];
       
   330 }
   311 }
   331 
   312 
   332 #endif /* SDL_VIDEO_OPENGL_CGL */
   313 #endif /* SDL_VIDEO_OPENGL_CGL */
   333 
   314 
   334 /* vi: set ts=4 sw=4 expandtab: */
   315 /* vi: set ts=4 sw=4 expandtab: */