Mac OS X: Try to save the GL context between fullscreen/windowed toggles. SDL-1.2
authorRyan C. Gordon <icculus@icculus.org>
Sun, 06 Nov 2011 16:51:51 -0500
branchSDL-1.2
changeset 60586144843db128
parent 6057 d0b7c45e982e
child 6059 a04171d6fa11
Mac OS X: Try to save the GL context between fullscreen/windowed toggles.
src/video/quartz/SDL_QuartzVideo.m
     1.1 --- a/src/video/quartz/SDL_QuartzVideo.m	Sun Nov 06 16:34:32 2011 -0500
     1.2 +++ b/src/video/quartz/SDL_QuartzVideo.m	Sun Nov 06 16:51:51 2011 -0500
     1.3 @@ -87,7 +87,7 @@
     1.4  
     1.5  static SDL_Rect**   QZ_ListModes        (_THIS, SDL_PixelFormat *format,
     1.6                                           Uint32 flags);
     1.7 -static void         QZ_UnsetVideoMode   (_THIS, BOOL to_desktop);
     1.8 +static void         QZ_UnsetVideoMode   (_THIS, BOOL to_desktop, BOOL save_gl);
     1.9  
    1.10  static SDL_Surface* QZ_SetVideoMode     (_THIS, SDL_Surface *current,
    1.11                                           int width, int height, int bpp,
    1.12 @@ -535,7 +535,7 @@
    1.13      return QZ_SetDisplayMode(this, save_mode);
    1.14  }
    1.15  
    1.16 -static void QZ_UnsetVideoMode (_THIS, BOOL to_desktop)
    1.17 +static void QZ_UnsetVideoMode (_THIS, BOOL to_desktop, BOOL save_gl)
    1.18  {
    1.19      /* Reset values that may change between switches */
    1.20      this->info.blit_fill  = 0;
    1.21 @@ -579,8 +579,10 @@
    1.22              Do this first to avoid trash on the display before fade
    1.23          */
    1.24          if ( mode_flags & SDL_OPENGL ) {
    1.25 -        
    1.26 -            QZ_TearDownOpenGL (this);
    1.27 +            if (!save_gl) {
    1.28 +                QZ_TearDownOpenGL (this);
    1.29 +            }
    1.30 +
    1.31              #ifdef __powerpc__  /* we only use this for pre-10.3 compatibility. */
    1.32              CGLSetFullScreen (NULL);
    1.33              #endif
    1.34 @@ -617,8 +619,11 @@
    1.35          window_view = nil;
    1.36  
    1.37          /* Release the OpenGL context */
    1.38 -        if ( mode_flags & SDL_OPENGL )
    1.39 -            QZ_TearDownOpenGL (this);
    1.40 +        if ( mode_flags & SDL_OPENGL ) {
    1.41 +            if (!save_gl) {
    1.42 +                QZ_TearDownOpenGL (this);
    1.43 +            }
    1.44 +        }
    1.45      }
    1.46  
    1.47      /* Signal successful teardown */
    1.48 @@ -671,7 +676,8 @@
    1.49  }
    1.50  
    1.51  static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int width,
    1.52 -                                           int height, int bpp, Uint32 flags)
    1.53 +                                           int height, int bpp, Uint32 flags,
    1.54 +                                           const BOOL save_gl)
    1.55  {
    1.56      const BOOL isLion = IS_LION_OR_LATER(this);
    1.57      NSRect screen_rect;
    1.58 @@ -693,7 +699,7 @@
    1.59      
    1.60      /* Destroy any previous mode */
    1.61      if (video_set == SDL_TRUE)
    1.62 -        QZ_UnsetVideoMode (this, FALSE);
    1.63 +        QZ_UnsetVideoMode (this, FALSE, save_gl);
    1.64  
    1.65      /* Sorry, QuickDraw was ripped out. */
    1.66      if (getenv("SDL_NSWindowPointer") || getenv("SDL_NSQuickDrawViewPointer")) {
    1.67 @@ -810,8 +816,10 @@
    1.68      /* Setup OpenGL for a fullscreen context */
    1.69      if (flags & SDL_OPENGL) {
    1.70  
    1.71 -        if ( ! QZ_SetupOpenGL (this, bpp, flags) ) {
    1.72 -            goto ERR_NO_GL;
    1.73 +        if ( ! save_gl ) {
    1.74 +            if ( ! QZ_SetupOpenGL (this, bpp, flags) ) {
    1.75 +                goto ERR_NO_GL;
    1.76 +            }
    1.77          }
    1.78  
    1.79          /* Initialize the NSView and add it to our window.  The presence of a valid window and
    1.80 @@ -942,7 +950,8 @@
    1.81  }
    1.82  
    1.83  static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width,
    1.84 -                                         int height, int *bpp, Uint32 flags)
    1.85 +                                         int height, int *bpp, Uint32 flags,
    1.86 +                                         const BOOL save_gl)
    1.87  {
    1.88      unsigned int style;
    1.89      NSRect contentRect;
    1.90 @@ -970,12 +979,12 @@
    1.91              if (CGAcquireDisplayFadeReservation (5, &fade_token) == kCGErrorSuccess) {
    1.92                  CGDisplayFade (fade_token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, TRUE);
    1.93              }
    1.94 -            QZ_UnsetVideoMode (this, TRUE);
    1.95 +            QZ_UnsetVideoMode (this, TRUE, save_gl);
    1.96          }
    1.97          else if ( ((mode_flags ^ flags) & (SDL_NOFRAME|SDL_RESIZABLE)) ||
    1.98                    (mode_flags & SDL_OPENGL) || 
    1.99                    (flags & SDL_OPENGL) ) {
   1.100 -            QZ_UnsetVideoMode (this, TRUE);
   1.101 +            QZ_UnsetVideoMode (this, TRUE, save_gl);
   1.102          }
   1.103      }
   1.104      
   1.105 @@ -1048,12 +1057,14 @@
   1.106      /* For OpenGL, we bind the context to a subview */
   1.107      if ( flags & SDL_OPENGL ) {
   1.108  
   1.109 -        if ( ! QZ_SetupOpenGL (this, *bpp, flags) ) {
   1.110 -            if (fade_token != kCGDisplayFadeReservationInvalidToken) {
   1.111 -                CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
   1.112 -                CGReleaseDisplayFadeReservation (fade_token);
   1.113 +        if ( ! save_gl ) {
   1.114 +            if ( ! QZ_SetupOpenGL (this, *bpp, flags) ) {
   1.115 +                if (fade_token != kCGDisplayFadeReservationInvalidToken) {
   1.116 +                    CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
   1.117 +                    CGReleaseDisplayFadeReservation (fade_token);
   1.118 +                }
   1.119 +                return NULL;
   1.120              }
   1.121 -            return NULL;
   1.122          }
   1.123  
   1.124          window_view = [ [ NSView alloc ] initWithFrame:contentRect ];
   1.125 @@ -1109,44 +1120,13 @@
   1.126      return current;
   1.127  }
   1.128  
   1.129 -static SDL_Surface* QZ_SetVideoMode (_THIS, SDL_Surface *current, int width,
   1.130 -                                     int height, int bpp, Uint32 flags)
   1.131 +
   1.132 +static SDL_Surface* QZ_SetVideoModeInternal (_THIS, SDL_Surface *current,
   1.133 +                                             int width, int height, int bpp,
   1.134 +                                             Uint32 flags, BOOL save_gl)
   1.135  {
   1.136      const BOOL isLion = IS_LION_OR_LATER(this);
   1.137  
   1.138 -    /* Don't throw away the GL context if we can just resize the current one. */
   1.139 -    if ( (video_set == SDL_TRUE) && ((flags & SDL_OPENGL) == (current->flags & SDL_OPENGL)) && (bpp == current->format->BitsPerPixel) ) {
   1.140 -        const NSRect contentRect = NSMakeRect (0, 0, width, height);
   1.141 -        if (flags & SDL_FULLSCREEN) {
   1.142 -            /* if these fail, we'll try the old way, of tearing everything down. */
   1.143 -            const void *newmode = QZ_BestMode(this, bpp, width, height);
   1.144 -            if ( newmode != NULL ) {
   1.145 -                if ( QZ_SetDisplayMode(this, newmode) != CGDisplayNoErr ) {
   1.146 -                    QZ_ReleaseDisplayMode(this, newmode);
   1.147 -                } else {
   1.148 -                    QZ_ReleaseDisplayMode(this, mode);  /* NULL is okay. */
   1.149 -                    mode = newmode;
   1.150 -                    current->w = width;
   1.151 -                    current->h = height;
   1.152 -                    [ qz_window setContentSize:contentRect.size ];
   1.153 -                    [ window_view setFrameSize:contentRect.size ];
   1.154 -                    [ gl_context update ];
   1.155 -                    return current;
   1.156 -                }
   1.157 -            }
   1.158 -        } else {
   1.159 -            QZ_RestoreDisplayMode(this);
   1.160 -            QZ_ReleaseDisplayMode(this, mode);  /* NULL is okay. */
   1.161 -            mode = NULL;
   1.162 -            current->w = width;
   1.163 -            current->h = height;
   1.164 -            [ qz_window setContentSize:contentRect.size ];
   1.165 -            [ window_view setFrameSize:contentRect.size ];
   1.166 -            [ gl_context update ];
   1.167 -            return current;
   1.168 -        }
   1.169 -    }
   1.170 -
   1.171      current->flags = 0;
   1.172      current->pixels = NULL;
   1.173  
   1.174 @@ -1155,7 +1135,7 @@
   1.175          if ( isLion ) {
   1.176              bpp = 32;
   1.177          }
   1.178 -        current = QZ_SetVideoFullScreen (this, current, width, height, bpp, flags );
   1.179 +        current = QZ_SetVideoFullScreen (this, current, width, height, bpp, flags, save_gl );
   1.180          if (current == NULL)
   1.181              return NULL;
   1.182      }
   1.183 @@ -1163,7 +1143,7 @@
   1.184      else {
   1.185          /* Force bpp to 32 */
   1.186          bpp = 32;
   1.187 -        current = QZ_SetVideoWindowed (this, current, width, height, &bpp, flags);
   1.188 +        current = QZ_SetVideoWindowed (this, current, width, height, &bpp, flags, save_gl );
   1.189          if (current == NULL)
   1.190              return NULL;
   1.191      }
   1.192 @@ -1224,6 +1204,29 @@
   1.193      return current;
   1.194  }
   1.195  
   1.196 +static SDL_Surface* QZ_SetVideoMode(_THIS, SDL_Surface *current,
   1.197 +                                    int width, int height, int bpp,
   1.198 +                                    Uint32 flags)
   1.199 +{
   1.200 +    /* Don't throw away the GL context if we can just resize the current one. */
   1.201 +    const BOOL save_gl = ( (video_set == SDL_TRUE) && ((flags & SDL_OPENGL) == (current->flags & SDL_OPENGL)) && (bpp == current->format->BitsPerPixel) );
   1.202 +    NSOpenGLContext *glctx = gl_context;
   1.203 +    SDL_Surface* retval = NULL;
   1.204 +
   1.205 +    if (save_gl) {
   1.206 +        [glctx retain];  /* just so we don't lose this when killing old views, etc */
   1.207 +    }
   1.208 +
   1.209 +    retval = QZ_SetVideoModeInternal (this, current, width, height, bpp, flags, save_gl);
   1.210 +
   1.211 +    if (save_gl) {
   1.212 +        [glctx release];  /* something else should own this now, or we legitimately release it. */
   1.213 +    }
   1.214 +
   1.215 +    return retval;
   1.216 +}
   1.217 +
   1.218 +
   1.219  static int QZ_ToggleFullScreen (_THIS, int on)
   1.220  {
   1.221      return 0;
   1.222 @@ -1529,14 +1532,14 @@
   1.223          if (CGAcquireDisplayFadeReservation (5, &fade_token) == kCGErrorSuccess) {
   1.224              CGDisplayFade (fade_token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, TRUE);
   1.225          }
   1.226 -        QZ_UnsetVideoMode (this, TRUE);
   1.227 +        QZ_UnsetVideoMode (this, TRUE, FALSE);
   1.228          if (fade_token != kCGDisplayFadeReservationInvalidToken) {
   1.229              CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
   1.230              CGReleaseDisplayFadeReservation (fade_token);
   1.231          }
   1.232      }
   1.233      else
   1.234 -        QZ_UnsetVideoMode (this, TRUE);
   1.235 +        QZ_UnsetVideoMode (this, TRUE, FALSE);
   1.236  
   1.237  #if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070)
   1.238      if (!IS_LION_OR_LATER(this)) {