Mac no longer loses OpenGL context when window is hidden.
authorJørgen P. Tjernø <jorgen@valvesoftware.com>
Mon, 22 Apr 2013 12:07:16 -0700
changeset 7085152cc7ddfa57
parent 7084 9d43403e9fc5
child 7086 141ffce8bb59
Mac no longer loses OpenGL context when window is hidden.

This fixes an issue that would arise when you minimize / order out an
OpenGL window on Mac, where the window would lose it's window device.
Without a window device, you cannot render to the window.

It does so by making two changes:
- Windows are no longer "oneShot" (which caused their window device to
get destroyed when they're minified or ordered out)
- Windows are no longer "deferred" (which caused the OS to defer
window device creation until the window is shown, which meant that
we couldn't properly makeCurrent to it)

Thanks to http://www.mikeash.com/pyblog/nsopenglcontext-and-one-shot.html
src/video/cocoa/SDL_cocoaopengl.m
src/video/cocoa/SDL_cocoawindow.m
     1.1 --- a/src/video/cocoa/SDL_cocoaopengl.m	Mon Apr 22 12:07:13 2013 -0700
     1.2 +++ b/src/video/cocoa/SDL_cocoaopengl.m	Mon Apr 22 12:07:16 2013 -0700
     1.3 @@ -238,16 +238,14 @@
     1.4          SDL_WindowData *windowdata = (SDL_WindowData *)window->driverdata;
     1.5          NSOpenGLContext *nscontext = (NSOpenGLContext *)context;
     1.6  
     1.7 -        if (window->flags & SDL_WINDOW_SHOWN) {
     1.8  #ifndef FULLSCREEN_TOGGLEABLE
     1.9 -            if (window->flags & SDL_WINDOW_FULLSCREEN) {
    1.10 -                [nscontext setFullScreen];
    1.11 -            } else
    1.12 +        if (window->flags & SDL_WINDOW_FULLSCREEN) {
    1.13 +            [nscontext setFullScreen];
    1.14 +        } else
    1.15  #endif
    1.16 -            {
    1.17 -                [nscontext setView:[windowdata->nswindow contentView]];
    1.18 -                [nscontext update];
    1.19 -            }
    1.20 +        {
    1.21 +            [nscontext setView:[windowdata->nswindow contentView]];
    1.22 +            [nscontext update];
    1.23          }
    1.24          [nscontext makeCurrentContext];
    1.25      } else {
    1.26 @@ -310,10 +308,7 @@
    1.27      pool = [[NSAutoreleasePool alloc] init];
    1.28  
    1.29      /* FIXME: Do we need to get the context for the window? */
    1.30 -    nscontext = [NSOpenGLContext currentContext];
    1.31 -    if (nscontext != nil) {
    1.32 -        [nscontext flushBuffer];
    1.33 -    }
    1.34 +    [[NSOpenGLContext currentContext] flushBuffer];
    1.35  
    1.36      [pool release];
    1.37  }
     2.1 --- a/src/video/cocoa/SDL_cocoawindow.m	Mon Apr 22 12:07:13 2013 -0700
     2.2 +++ b/src/video/cocoa/SDL_cocoawindow.m	Mon Apr 22 12:07:16 2013 -0700
     2.3 @@ -591,6 +591,11 @@
     2.4          SDL_SetKeyboardFocus(data->window);
     2.5      }
     2.6  
     2.7 +    /* Prevents the window's "window device" from being destroyed when it is
     2.8 +     * hidden. See http://www.mikeash.com/pyblog/nsopenglcontext-and-one-shot.html
     2.9 +     */
    2.10 +    [nswindow setOneShot:NO];
    2.11 +
    2.12      /* All done! */
    2.13      [pool release];
    2.14      window->driverdata = data;
    2.15 @@ -633,7 +638,7 @@
    2.16              rect.origin.y -= screenRect.origin.y;
    2.17          }
    2.18      }
    2.19 -    nswindow = [[SDLWindow alloc] initWithContentRect:rect styleMask:style backing:NSBackingStoreBuffered defer:YES screen:screen];
    2.20 +    nswindow = [[SDLWindow alloc] initWithContentRect:rect styleMask:style backing:NSBackingStoreBuffered defer:NO screen:screen];
    2.21  
    2.22      // Create a default view for this window
    2.23      rect = [nswindow contentRectForFrameRect:[nswindow frame]];
    2.24 @@ -856,8 +861,10 @@
    2.25      }
    2.26  
    2.27      [data->listener close];
    2.28 -    data->nswindow = [[SDLWindow alloc] initWithContentRect:[[nswindow contentView] frame] styleMask:style backing:NSBackingStoreBuffered defer:YES screen:[nswindow screen]];
    2.29 +    data->nswindow = [[SDLWindow alloc] initWithContentRect:[[nswindow contentView] frame] styleMask:style backing:NSBackingStoreBuffered defer:NO screen:[nswindow screen]];
    2.30      [data->nswindow setContentView:[nswindow contentView]];
    2.31 +    /* See comment in SetupWindowData. */
    2.32 +    [data->nswindow setOneShot:NO];
    2.33      [data->listener listen:data];
    2.34  
    2.35      [nswindow close];