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