src/video/cocoa/SDL_cocoaopengl.m
author Ryan C. Gordon <icculus@icculus.org>
Thu, 26 Mar 2020 13:42:56 -0400
changeset 13673 be892626e1aa
parent 13647 c8f27a5e868e
child 13703 19c4516de68d
permissions -rw-r--r--
cocoa: Just update the OpenGL context directly if on the main thread.
slouken@1936
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@13422
     3
  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
slouken@1936
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@1936
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@1936
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@1936
    20
*/
icculus@8093
    21
#include "../../SDL_internal.h"
slouken@1936
    22
slouken@1936
    23
/* NSOpenGL implementation of SDL OpenGL support */
slouken@1936
    24
slouken@1952
    25
#if SDL_VIDEO_OPENGL_CGL
slouken@6044
    26
#include "SDL_cocoavideo.h"
jorgen@7594
    27
#include "SDL_cocoaopengl.h"
slouken@11723
    28
#include "SDL_cocoaopengles.h"
slouken@6044
    29
slouken@1936
    30
#include <OpenGL/CGLTypes.h>
slouken@2738
    31
#include <OpenGL/OpenGL.h>
slouken@3570
    32
#include <OpenGL/CGLRenderers.h>
slouken@1936
    33
slouken@1936
    34
#include "SDL_loadso.h"
slouken@1936
    35
#include "SDL_opengl.h"
slouken@1936
    36
icculus@6567
    37
#define DEFAULT_OPENGL  "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib"
slouken@1936
    38
icculus@12863
    39
/* We still support OpenGL as long as Apple offers it, deprecated or not, so disable deprecation warnings about it. */
icculus@12863
    40
#ifdef __clang__
icculus@12863
    41
#pragma clang diagnostic push
icculus@12863
    42
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
icculus@12863
    43
#endif
icculus@12863
    44
jorgen@7594
    45
@implementation SDLOpenGLContext : NSOpenGLContext
jorgen@7594
    46
jorgen@7594
    47
- (id)initWithFormat:(NSOpenGLPixelFormat *)format
jorgen@7594
    48
        shareContext:(NSOpenGLContext *)share
jorgen@7594
    49
{
jorgen@7595
    50
    self = [super initWithFormat:format shareContext:share];
jorgen@7595
    51
    if (self) {
jorgen@7595
    52
        SDL_AtomicSet(&self->dirty, 0);
jorgen@7595
    53
        self->window = NULL;
jorgen@7595
    54
    }
jorgen@7595
    55
    return self;
jorgen@7594
    56
}
jorgen@7594
    57
jorgen@7594
    58
- (void)scheduleUpdate
jorgen@7594
    59
{
jorgen@7594
    60
    SDL_AtomicAdd(&self->dirty, 1);
jorgen@7594
    61
}
jorgen@7594
    62
jorgen@7594
    63
/* This should only be called on the thread on which a user is using the context. */
jorgen@7594
    64
- (void)updateIfNeeded
jorgen@7594
    65
{
jorgen@7594
    66
    int value = SDL_AtomicSet(&self->dirty, 0);
jorgen@7594
    67
    if (value > 0) {
jorgen@7594
    68
        /* We call the real underlying update here, since -[SDLOpenGLContext update] just calls us. */
icculus@13673
    69
        if ([NSThread isMainThread]) {
icculus@13673
    70
            [super update];
icculus@13673
    71
        } else {
icculus@13673
    72
            [super performSelectorOnMainThread:@selector(update) withObject:nil waitUntilDone:NO];
icculus@13673
    73
        }
jorgen@7594
    74
    }
jorgen@7594
    75
}
jorgen@7594
    76
jorgen@7594
    77
/* This should only be called on the thread on which a user is using the context. */
jorgen@7594
    78
- (void)update
jorgen@7594
    79
{
jorgen@7594
    80
    /* This ensures that regular 'update' calls clear the atomic dirty flag. */
jorgen@7594
    81
    [self scheduleUpdate];
jorgen@7594
    82
    [self updateIfNeeded];
jorgen@7594
    83
}
jorgen@7594
    84
jorgen@7595
    85
/* Updates the drawable for the contexts and manages related state. */
jorgen@7595
    86
- (void)setWindow:(SDL_Window *)newWindow
jorgen@7595
    87
{
jorgen@7595
    88
    if (self->window) {
jorgen@7595
    89
        SDL_WindowData *oldwindowdata = (SDL_WindowData *)self->window->driverdata;
jorgen@7595
    90
jorgen@7595
    91
        /* Make sure to remove us from the old window's context list, or we'll get scheduled updates from it too. */
jorgen@7595
    92
        NSMutableArray *contexts = oldwindowdata->nscontexts;
jorgen@7595
    93
        @synchronized (contexts) {
jorgen@7595
    94
            [contexts removeObject:self];
jorgen@7595
    95
        }
jorgen@7595
    96
    }
jorgen@7595
    97
jorgen@7595
    98
    self->window = newWindow;
jorgen@7595
    99
jorgen@7595
   100
    if (newWindow) {
jorgen@7595
   101
        SDL_WindowData *windowdata = (SDL_WindowData *)newWindow->driverdata;
slime73@12940
   102
        NSView *contentview = windowdata->sdlContentView;
slime73@12940
   103
slime73@12940
   104
        /* This should never be nil since sdlContentView is only nil if the
slime73@12940
   105
           window was created via SDL_CreateWindowFrom, and SDL doesn't allow
slime73@12940
   106
           OpenGL contexts to be created in that case. However, it doesn't hurt
slime73@12940
   107
           to check. */
slime73@12940
   108
        if (contentview == nil) {
slime73@12940
   109
            /* Prefer to access the cached content view above instead of this,
slime73@12940
   110
               since as of Xcode 11 + SDK 10.15, [window contentView] causes
slime73@12940
   111
               Apple's Main Thread Checker to output a warning. */
slime73@12940
   112
            contentview = [windowdata->nswindow contentView];
slime73@12940
   113
        }
jorgen@7595
   114
jorgen@7595
   115
        /* Now sign up for scheduled updates for the new window. */
jorgen@7595
   116
        NSMutableArray *contexts = windowdata->nscontexts;
jorgen@7595
   117
        @synchronized (contexts) {
jorgen@7595
   118
            [contexts addObject:self];
jorgen@7595
   119
        }
jorgen@7595
   120
slime73@12940
   121
        if ([self view] != contentview) {
slime73@12940
   122
            [self setView:contentview];
jorgen@8258
   123
            if (self == [NSOpenGLContext currentContext]) {
jorgen@8258
   124
                [self update];
jorgen@8258
   125
            } else {
jorgen@8258
   126
                [self scheduleUpdate];
jorgen@8258
   127
            }
jorgen@7595
   128
        }
jorgen@7595
   129
    } else {
jorgen@7595
   130
        [self clearDrawable];
jorgen@8258
   131
        if (self == [NSOpenGLContext currentContext]) {
jorgen@8258
   132
            [self update];
jorgen@8258
   133
        } else {
jorgen@8258
   134
            [self scheduleUpdate];
jorgen@8258
   135
        }
jorgen@7595
   136
    }
jorgen@7595
   137
}
jorgen@7595
   138
jorgen@7594
   139
@end
jorgen@7594
   140
slouken@1936
   141
slouken@1936
   142
int
slouken@1936
   143
Cocoa_GL_LoadLibrary(_THIS, const char *path)
slouken@1936
   144
{
slouken@3057
   145
    /* Load the OpenGL library */
slouken@1936
   146
    if (path == NULL) {
slouken@1952
   147
        path = SDL_getenv("SDL_OPENGL_LIBRARY");
slouken@1952
   148
    }
slouken@1952
   149
    if (path == NULL) {
slouken@1952
   150
        path = DEFAULT_OPENGL;
slouken@1936
   151
    }
slouken@1936
   152
    _this->gl_config.dll_handle = SDL_LoadObject(path);
slouken@1936
   153
    if (!_this->gl_config.dll_handle) {
slouken@1936
   154
        return -1;
slouken@1936
   155
    }
slouken@1936
   156
    SDL_strlcpy(_this->gl_config.driver_path, path,
slouken@1936
   157
                SDL_arraysize(_this->gl_config.driver_path));
slouken@1936
   158
    return 0;
slouken@1936
   159
}
slouken@1936
   160
slouken@1936
   161
void *
slouken@1936
   162
Cocoa_GL_GetProcAddress(_THIS, const char *proc)
slouken@1936
   163
{
slouken@1936
   164
    return SDL_LoadFunction(_this->gl_config.dll_handle, proc);
slouken@1936
   165
}
slouken@1936
   166
slouken@3057
   167
void
slouken@1936
   168
Cocoa_GL_UnloadLibrary(_THIS)
slouken@1936
   169
{
slouken@3057
   170
    SDL_UnloadObject(_this->gl_config.dll_handle);
slouken@3057
   171
    _this->gl_config.dll_handle = NULL;
slouken@1936
   172
}
slouken@1936
   173
slouken@1936
   174
SDL_GLContext
slouken@1936
   175
Cocoa_GL_CreateContext(_THIS, SDL_Window * window)
slime73@9587
   176
{ @autoreleasepool
slouken@1936
   177
{
slouken@5246
   178
    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
slouken@1936
   179
    SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata;
slouken@8986
   180
    SDL_bool lion_or_later = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6;
slouken@1936
   181
    NSOpenGLPixelFormatAttribute attr[32];
slouken@1936
   182
    NSOpenGLPixelFormat *fmt;
jorgen@7594
   183
    SDLOpenGLContext *context;
flibitijibibo@7152
   184
    NSOpenGLContext *share_context = nil;
slouken@1936
   185
    int i = 0;
icculus@8276
   186
    const char *glversion;
icculus@8276
   187
    int glversion_major;
icculus@8276
   188
    int glversion_minor;
slouken@1936
   189
icculus@6567
   190
    if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
slouken@11723
   191
#if SDL_VIDEO_OPENGL_EGL
slouken@11723
   192
        /* Switch to EGL based functions */
slouken@11723
   193
        Cocoa_GL_UnloadLibrary(_this);
slouken@11723
   194
        _this->GL_LoadLibrary = Cocoa_GLES_LoadLibrary;
slouken@11723
   195
        _this->GL_GetProcAddress = Cocoa_GLES_GetProcAddress;
slouken@11723
   196
        _this->GL_UnloadLibrary = Cocoa_GLES_UnloadLibrary;
slouken@11723
   197
        _this->GL_CreateContext = Cocoa_GLES_CreateContext;
slouken@11723
   198
        _this->GL_MakeCurrent = Cocoa_GLES_MakeCurrent;
slouken@11723
   199
        _this->GL_SetSwapInterval = Cocoa_GLES_SetSwapInterval;
slouken@11723
   200
        _this->GL_GetSwapInterval = Cocoa_GLES_GetSwapInterval;
slouken@11723
   201
        _this->GL_SwapWindow = Cocoa_GLES_SwapWindow;
slouken@11723
   202
        _this->GL_DeleteContext = Cocoa_GLES_DeleteContext;
slouken@11723
   203
        
slouken@11723
   204
        if (Cocoa_GLES_LoadLibrary(_this, NULL) != 0) {
slouken@11723
   205
            return NULL;
slouken@11723
   206
        }
slouken@11723
   207
        return Cocoa_GLES_CreateContext(_this, window);
slouken@11723
   208
#else
slouken@11723
   209
        SDL_SetError("SDL not configured with EGL support");
icculus@6567
   210
        return NULL;
slouken@11723
   211
#endif
icculus@6567
   212
    }
slouken@8986
   213
    if ((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_CORE) && !lion_or_later) {
icculus@8276
   214
        SDL_SetError ("OpenGL Core Profile is not supported on this platform version");
icculus@6567
   215
        return NULL;
icculus@6567
   216
    }
icculus@6567
   217
icculus@10008
   218
    attr[i++] = NSOpenGLPFAAllowOfflineRenderers;
icculus@10008
   219
slouken@6848
   220
    /* specify a profile if we're on Lion (10.7) or later. */
slouken@8986
   221
    if (lion_or_later) {
icculus@8276
   222
        NSOpenGLPixelFormatAttribute profile = NSOpenGLProfileVersionLegacy;
slouken@6848
   223
        if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_CORE) {
icculus@8276
   224
            profile = NSOpenGLProfileVersion3_2Core;
alexey@6832
   225
        }
icculus@8276
   226
        attr[i++] = NSOpenGLPFAOpenGLProfile;
slouken@6848
   227
        attr[i++] = profile;
slouken@6848
   228
    }
slouken@6848
   229
slouken@6848
   230
    attr[i++] = NSOpenGLPFAColorSize;
slouken@6848
   231
    attr[i++] = SDL_BYTESPERPIXEL(display->current_mode.format)*8;
slouken@6848
   232
slouken@6848
   233
    attr[i++] = NSOpenGLPFADepthSize;
slouken@6848
   234
    attr[i++] = _this->gl_config.depth_size;
slouken@6848
   235
slouken@6848
   236
    if (_this->gl_config.double_buffer) {
slouken@6848
   237
        attr[i++] = NSOpenGLPFADoubleBuffer;
slouken@6848
   238
    }
slouken@6848
   239
slouken@6848
   240
    if (_this->gl_config.stereo) {
slouken@6848
   241
        attr[i++] = NSOpenGLPFAStereo;
slouken@6848
   242
    }
slouken@6848
   243
slouken@6848
   244
    if (_this->gl_config.stencil_size) {
slouken@6848
   245
        attr[i++] = NSOpenGLPFAStencilSize;
slouken@6848
   246
        attr[i++] = _this->gl_config.stencil_size;
slouken@6848
   247
    }
slouken@6848
   248
slouken@6848
   249
    if ((_this->gl_config.accum_red_size +
slouken@6848
   250
         _this->gl_config.accum_green_size +
slouken@6848
   251
         _this->gl_config.accum_blue_size +
slouken@6848
   252
         _this->gl_config.accum_alpha_size) > 0) {
slouken@6848
   253
        attr[i++] = NSOpenGLPFAAccumSize;
slouken@6848
   254
        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;
slouken@6848
   255
    }
slouken@6848
   256
slouken@6848
   257
    if (_this->gl_config.multisamplebuffers) {
slouken@6848
   258
        attr[i++] = NSOpenGLPFASampleBuffers;
slouken@6848
   259
        attr[i++] = _this->gl_config.multisamplebuffers;
slouken@6848
   260
    }
alexey@6832
   261
slouken@6848
   262
    if (_this->gl_config.multisamplesamples) {
slouken@6848
   263
        attr[i++] = NSOpenGLPFASamples;
slouken@6848
   264
        attr[i++] = _this->gl_config.multisamplesamples;
slouken@6848
   265
        attr[i++] = NSOpenGLPFANoRecovery;
slouken@6848
   266
    }
slouken@6848
   267
slouken@6848
   268
    if (_this->gl_config.accelerated >= 0) {
slouken@6848
   269
        if (_this->gl_config.accelerated) {
slouken@6848
   270
            attr[i++] = NSOpenGLPFAAccelerated;
slouken@6848
   271
        } else {
slouken@6848
   272
            attr[i++] = NSOpenGLPFARendererID;
slouken@6848
   273
            attr[i++] = kCGLRendererGenericFloatID;
alexey@6832
   274
        }
slouken@6848
   275
    }
slouken@6848
   276
slouken@6848
   277
    attr[i++] = NSOpenGLPFAScreenMask;
slouken@6848
   278
    attr[i++] = CGDisplayIDToOpenGLDisplayMask(displaydata->display);
slouken@6848
   279
    attr[i] = 0;
slouken@6848
   280
slouken@6848
   281
    fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr];
slouken@6848
   282
    if (fmt == nil) {
slouken@8601
   283
        SDL_SetError("Failed creating OpenGL pixel format");
slouken@6848
   284
        return NULL;
slouken@6848
   285
    }
slouken@6848
   286
flibitijibibo@7152
   287
    if (_this->gl_config.share_with_current_context) {
slouken@7412
   288
        share_context = (NSOpenGLContext*)SDL_GL_GetCurrentContext();
flibitijibibo@7152
   289
    }
flibitijibibo@7152
   290
jorgen@7594
   291
    context = [[SDLOpenGLContext alloc] initWithFormat:fmt shareContext:share_context];
slouken@6848
   292
slouken@6848
   293
    [fmt release];
slouken@6848
   294
slouken@6848
   295
    if (context == nil) {
slouken@8601
   296
        SDL_SetError("Failed creating OpenGL context");
slouken@6848
   297
        return NULL;
slouken@6848
   298
    }
slouken@6848
   299
slouken@2178
   300
    if ( Cocoa_GL_MakeCurrent(_this, window, context) < 0 ) {
slouken@2178
   301
        Cocoa_GL_DeleteContext(_this, context);
slouken@8601
   302
        SDL_SetError("Failed making OpenGL context current");
icculus@8276
   303
        return NULL;
icculus@8276
   304
    }
icculus@8276
   305
slouken@8604
   306
    if (_this->gl_config.major_version < 3 &&
slouken@8604
   307
        _this->gl_config.profile_mask == 0 &&
slouken@8604
   308
        _this->gl_config.flags == 0) {
slouken@8604
   309
        /* This is a legacy profile, so to match other backends, we're done. */
slouken@8604
   310
    } else {
slouken@8604
   311
        const GLubyte *(APIENTRY * glGetStringFunc)(GLenum);
slouken@8601
   312
slouken@8604
   313
        glGetStringFunc = (const GLubyte *(APIENTRY *)(GLenum)) SDL_GL_GetProcAddress("glGetString");
slouken@8604
   314
        if (!glGetStringFunc) {
slouken@8604
   315
            Cocoa_GL_DeleteContext(_this, context);
slouken@8604
   316
            SDL_SetError ("Failed getting OpenGL glGetString entry point");
slouken@8604
   317
            return NULL;
slouken@8604
   318
        }
icculus@8278
   319
slouken@8604
   320
        glversion = (const char *)glGetStringFunc(GL_VERSION);
slouken@8604
   321
        if (glversion == NULL) {
slouken@8604
   322
            Cocoa_GL_DeleteContext(_this, context);
slouken@8604
   323
            SDL_SetError ("Failed getting OpenGL context version");
slouken@8604
   324
            return NULL;
slouken@8604
   325
        }
slouken@8604
   326
slouken@8604
   327
        if (SDL_sscanf(glversion, "%d.%d", &glversion_major, &glversion_minor) != 2) {
slouken@8604
   328
            Cocoa_GL_DeleteContext(_this, context);
slouken@8604
   329
            SDL_SetError ("Failed parsing OpenGL context version");
slouken@8604
   330
            return NULL;
slouken@8604
   331
        }
slouken@2178
   332
slouken@8604
   333
        if ((glversion_major < _this->gl_config.major_version) ||
slouken@8604
   334
           ((glversion_major == _this->gl_config.major_version) && (glversion_minor < _this->gl_config.minor_version))) {
slouken@8604
   335
            Cocoa_GL_DeleteContext(_this, context);
slouken@8604
   336
            SDL_SetError ("Failed creating OpenGL context at version requested");
slouken@8604
   337
            return NULL;
slouken@8604
   338
        }
slouken@8604
   339
slouken@8604
   340
        /* In the future we'll want to do this, but to match other platforms
slouken@8604
   341
           we'll leave the OpenGL version the way it is for now
slouken@8604
   342
         */
slouken@8604
   343
        /*_this->gl_config.major_version = glversion_major;*/
slouken@8604
   344
        /*_this->gl_config.minor_version = glversion_minor;*/
icculus@8276
   345
    }
slouken@2178
   346
    return context;
slime73@9587
   347
}}
slouken@1936
   348
slouken@1936
   349
int
slouken@1936
   350
Cocoa_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
slime73@9587
   351
{ @autoreleasepool
slouken@1936
   352
{
slouken@6848
   353
    if (context) {
jorgen@7594
   354
        SDLOpenGLContext *nscontext = (SDLOpenGLContext *)context;
jorgen@7595
   355
        [nscontext setWindow:window];
jorgen@7594
   356
        [nscontext updateIfNeeded];
slouken@6848
   357
        [nscontext makeCurrentContext];
slouken@6848
   358
    } else {
slouken@6848
   359
        [NSOpenGLContext clearCurrentContext];
slouken@1936
   360
    }
slouken@1936
   361
slouken@1936
   362
    return 0;
slime73@9587
   363
}}
slouken@1936
   364
urkle@7746
   365
void
urkle@7746
   366
Cocoa_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
urkle@7746
   367
{
urkle@7746
   368
    SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
urkle@7746
   369
    NSView *contentView = [windata->nswindow contentView];
urkle@7746
   370
    NSRect viewport = [contentView bounds];
urkle@7746
   371
icculus@12338
   372
    if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
icculus@12338
   373
        /* This gives us the correct viewport for a Retina-enabled view, only
icculus@12338
   374
         * supported on 10.7+. */
icculus@12338
   375
        if ([contentView respondsToSelector:@selector(convertRectToBacking:)]) {
icculus@12338
   376
            viewport = [contentView convertRectToBacking:viewport];
icculus@12338
   377
        }
urkle@7746
   378
    }
urkle@7746
   379
urkle@7746
   380
    if (w) {
urkle@7746
   381
        *w = viewport.size.width;
urkle@7746
   382
    }
urkle@7746
   383
urkle@7746
   384
    if (h) {
urkle@7746
   385
        *h = viewport.size.height;
urkle@7746
   386
    }
urkle@7746
   387
}
urkle@7746
   388
slouken@1936
   389
int
slouken@1936
   390
Cocoa_GL_SetSwapInterval(_THIS, int interval)
slime73@9587
   391
{ @autoreleasepool
slouken@1936
   392
{
icculus@12840
   393
    NSOpenGLContext *nscontext;
icculus@12840
   394
    GLint value;
slouken@1936
   395
    int status;
slouken@1936
   396
icculus@12840
   397
    if (interval < 0) {  /* no extension for this on Mac OS X at the moment. */
icculus@12840
   398
        return SDL_SetError("Late swap tearing currently unsupported");
icculus@12840
   399
    }
icculus@12840
   400
icculus@12840
   401
    nscontext = (NSOpenGLContext*)SDL_GL_GetCurrentContext();
icculus@12840
   402
    if (nscontext != nil) {
icculus@12840
   403
        value = interval;
icculus@12840
   404
        [nscontext setValues:&value forParameter:NSOpenGLCPSwapInterval];
icculus@12840
   405
        status = 0;
icculus@12477
   406
    } else {
icculus@12840
   407
        status = SDL_SetError("No current OpenGL context");
slouken@1936
   408
    }
slouken@1936
   409
slouken@1936
   410
    return status;
slime73@9587
   411
}}
slouken@1936
   412
slouken@1936
   413
int
slouken@1936
   414
Cocoa_GL_GetSwapInterval(_THIS)
slime73@9587
   415
{ @autoreleasepool
slouken@1936
   416
{
icculus@12840
   417
    NSOpenGLContext *nscontext;
icculus@12840
   418
    GLint value;
icculus@12840
   419
    int status = 0;
icculus@12840
   420
icculus@12840
   421
    nscontext = (NSOpenGLContext*)SDL_GL_GetCurrentContext();
icculus@12840
   422
    if (nscontext != nil) {
icculus@12840
   423
        [nscontext getValues:&value forParameter:NSOpenGLCPSwapInterval];
icculus@12840
   424
        status = (int)value;
icculus@12840
   425
    }
icculus@12840
   426
icculus@12840
   427
    return status;
slime73@9587
   428
}}
slouken@1936
   429
slouken@10690
   430
int
slouken@1936
   431
Cocoa_GL_SwapWindow(_THIS, SDL_Window * window)
slime73@9587
   432
{ @autoreleasepool
slouken@1936
   433
{
slouken@7738
   434
    SDLOpenGLContext* nscontext = (SDLOpenGLContext*)SDL_GL_GetCurrentContext();
icculus@12343
   435
    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
icculus@12343
   436
icculus@12343
   437
    /* on 10.14 ("Mojave") and later, this deadlocks if two contexts in two
icculus@12343
   438
       threads try to swap at the same time, so put a mutex around it. */
icculus@12343
   439
    SDL_LockMutex(videodata->swaplock);
slouken@7408
   440
    [nscontext flushBuffer];
jorgen@7594
   441
    [nscontext updateIfNeeded];
icculus@12343
   442
    SDL_UnlockMutex(videodata->swaplock);
slouken@10690
   443
    return 0;
slime73@9587
   444
}}
slouken@1936
   445
slouken@1936
   446
void
slouken@1936
   447
Cocoa_GL_DeleteContext(_THIS, SDL_GLContext context)
slime73@9587
   448
{ @autoreleasepool
slouken@1936
   449
{
jorgen@7595
   450
    SDLOpenGLContext *nscontext = (SDLOpenGLContext *)context;
slouken@1936
   451
jorgen@7595
   452
    [nscontext setWindow:NULL];
slouken@6848
   453
    [nscontext release];
slime73@9587
   454
}}
slouken@1936
   455
icculus@12863
   456
/* We still support OpenGL as long as Apple offers it, deprecated or not, so disable deprecation warnings about it. */
icculus@12863
   457
#ifdef __clang__
icculus@12863
   458
#pragma clang diagnostic pop
icculus@12863
   459
#endif
icculus@12863
   460
slouken@1952
   461
#endif /* SDL_VIDEO_OPENGL_CGL */
slouken@1936
   462
slouken@1936
   463
/* vi: set ts=4 sw=4 expandtab: */