WinRT: cleaned up some hard-to-read SDL_DisplayMode management code
authorDavid Ludwig <dludwig@pobox.com>
Sat, 01 Mar 2014 16:37:30 -0500
changeset 8579ee7126c459d0
parent 8578 6517b6aca713
child 8580 2754762c0860
WinRT: cleaned up some hard-to-read SDL_DisplayMode management code
src/core/winrt/SDL_winrtapp_direct3d.cpp
src/video/winrt/SDL_winrtvideo.cpp
     1.1 --- a/src/core/winrt/SDL_winrtapp_direct3d.cpp	Sat Mar 01 16:08:16 2014 -0500
     1.2 +++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp	Sat Mar 01 16:37:30 2014 -0500
     1.3 @@ -157,31 +157,39 @@
     1.4      // window-resize event as it appeared the SDL window didn't change
     1.5      // size, and the Direct3D 11.1 renderer wouldn't resize its swap
     1.6      // chain.
     1.7 -    SDL_DisplayMode resizedDisplayMode;
     1.8 -    if (WINRT_CalcDisplayModeUsingNativeWindow(&resizedDisplayMode) != 0) {
     1.9 -        return;
    1.10 -    }
    1.11 -    
    1.12 -    if (resizedDisplayMode.w == 0 || resizedDisplayMode.h == 0) {
    1.13 -        if (resizedDisplayMode.driverdata) {
    1.14 -            SDL_free(resizedDisplayMode.driverdata);
    1.15 -        }
    1.16 +    SDL_DisplayMode newDisplayMode;
    1.17 +    if (WINRT_CalcDisplayModeUsingNativeWindow(&newDisplayMode) != 0) {
    1.18          return;
    1.19      }
    1.20  
    1.21 +    // Make note of the old display mode, and it's old driverdata.
    1.22      SDL_DisplayMode oldDisplayMode;
    1.23      SDL_zero(oldDisplayMode);
    1.24      if (WINRT_GlobalSDLVideoDevice) {
    1.25          oldDisplayMode = WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode;
    1.26 -        if (WINRT_DuplicateDisplayMode(&(WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode), &resizedDisplayMode) != 0) {
    1.27 -            SDL_free(resizedDisplayMode.driverdata);
    1.28 +    }
    1.29 +
    1.30 +    // Setup the new display mode in the appropriate spots.
    1.31 +    if (WINRT_GlobalSDLVideoDevice) {
    1.32 +        // Make a full copy of the display mode for display_modes[0],
    1.33 +        // one with with a separately malloced 'driverdata' field.
    1.34 +        // SDL_VideoQuit(), if called, will attempt to free the driverdata
    1.35 +        // fields in 'desktop_mode' and each entry in the 'display_modes'
    1.36 +        // array.
    1.37 +        if (WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata) {
    1.38 +            // Free the previous mode's memory
    1.39 +            SDL_free(WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata);
    1.40 +            WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata = NULL;
    1.41 +        }
    1.42 +        if (WINRT_DuplicateDisplayMode(&(WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0]), &newDisplayMode) != 0) {
    1.43 +            // Uh oh, something went wrong.  A malloc call probably failed.
    1.44 +            SDL_free(newDisplayMode.driverdata);
    1.45              return;
    1.46          }
    1.47 -        WINRT_GlobalSDLVideoDevice->displays[0].current_mode = resizedDisplayMode;
    1.48 -        if (WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata) {
    1.49 -            SDL_free(WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata);
    1.50 -        }
    1.51 -        WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0] = resizedDisplayMode;
    1.52 +
    1.53 +        // Install 'newDisplayMode' into 'current_mode' and 'desktop_mode'.
    1.54 +        WINRT_GlobalSDLVideoDevice->displays[0].current_mode = newDisplayMode;
    1.55 +        WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode = newDisplayMode;
    1.56      }
    1.57  
    1.58      if (WINRT_GlobalSDLWindow) {
    1.59 @@ -189,8 +197,8 @@
    1.60          SDL_SendWindowEvent(
    1.61              WINRT_GlobalSDLWindow,
    1.62              SDL_WINDOWEVENT_RESIZED,
    1.63 -            resizedDisplayMode.w,
    1.64 -            resizedDisplayMode.h);
    1.65 +            newDisplayMode.w,
    1.66 +            newDisplayMode.h);
    1.67  
    1.68  #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
    1.69          // HACK: On Windows Phone, make sure that orientation changes from
    1.70 @@ -198,7 +206,7 @@
    1.71          // or vice-versa on either of those two, lead to the Direct3D renderer
    1.72          // getting updated.
    1.73          const DisplayOrientations oldOrientation = ((SDL_DisplayModeData *)oldDisplayMode.driverdata)->currentOrientation;
    1.74 -        const DisplayOrientations newOrientation = ((SDL_DisplayModeData *)resizedDisplayMode.driverdata)->currentOrientation;
    1.75 +        const DisplayOrientations newOrientation = ((SDL_DisplayModeData *)newDisplayMode.driverdata)->currentOrientation;
    1.76  
    1.77          if ((oldOrientation == DisplayOrientations::Landscape && newOrientation == DisplayOrientations::LandscapeFlipped) ||
    1.78              (oldOrientation == DisplayOrientations::LandscapeFlipped && newOrientation == DisplayOrientations::Landscape) ||
    1.79 @@ -213,21 +221,23 @@
    1.80              // Make sure that the display/window size really didn't change.  If
    1.81              // it did, then a SDL_WINDOWEVENT_SIZE_CHANGED event got sent, and
    1.82              // the Direct3D 11.1 renderer picked it up, presumably.
    1.83 -            if (oldDisplayMode.w == resizedDisplayMode.w &&
    1.84 -                oldDisplayMode.h == resizedDisplayMode.h)
    1.85 +            if (oldDisplayMode.w == newDisplayMode.w &&
    1.86 +                oldDisplayMode.h == newDisplayMode.h)
    1.87              {
    1.88                  SDL_SendWindowEvent(
    1.89                      WINRT_GlobalSDLWindow,
    1.90                      SDL_WINDOWEVENT_SIZE_CHANGED,
    1.91 -                    resizedDisplayMode.w,
    1.92 -                    resizedDisplayMode.h);
    1.93 +                    newDisplayMode.w,
    1.94 +                    newDisplayMode.h);
    1.95              }
    1.96          }
    1.97  #endif
    1.98      }
    1.99      
   1.100 +    // Finally, free the 'driverdata' field of the old 'desktop_mode'.
   1.101      if (oldDisplayMode.driverdata) {
   1.102          SDL_free(oldDisplayMode.driverdata);
   1.103 +        oldDisplayMode.driverdata = NULL;
   1.104      }
   1.105  }
   1.106  
     2.1 --- a/src/video/winrt/SDL_winrtvideo.cpp	Sat Mar 01 16:08:16 2014 -0500
     2.2 +++ b/src/video/winrt/SDL_winrtvideo.cpp	Sat Mar 01 16:37:30 2014 -0500
     2.3 @@ -154,9 +154,6 @@
     2.4  
     2.5      using namespace Windows::Graphics::Display;
     2.6  
     2.7 -    // Initialize the mode to all zeros:
     2.8 -    SDL_zerop(mode);
     2.9 -
    2.10      // Go no further if a native window cannot be accessed.  This can happen,
    2.11      // for example, if this function is called from certain threads, such as
    2.12      // the SDL/XAML thread.
    2.13 @@ -164,6 +161,16 @@
    2.14          return SDL_SetError("SDL/WinRT display modes cannot be calculated outside of the main thread, such as in SDL's XAML thread");
    2.15      }
    2.16  
    2.17 +    // Calculate the display size given the window size, taking into account
    2.18 +    // the current display's DPI:
    2.19 +    const float currentDPI = Windows::Graphics::Display::DisplayProperties::LogicalDpi; 
    2.20 +    const float dipsPerInch = 96.0f;
    2.21 +    const int w = (int) ((CoreWindow::GetForCurrentThread()->Bounds.Width * currentDPI) / dipsPerInch);
    2.22 +    const int h = (int) ((CoreWindow::GetForCurrentThread()->Bounds.Height * currentDPI) / dipsPerInch);
    2.23 +    if (w == 0 || w == h) {
    2.24 +        return SDL_SetError("Unable to calculate the WinRT window/display's size");
    2.25 +    }
    2.26 +
    2.27      // Create a driverdata field:
    2.28      driverdata = (SDL_DisplayModeData *) SDL_malloc(sizeof(*driverdata));
    2.29      if (!driverdata) {
    2.30 @@ -172,18 +179,14 @@
    2.31      SDL_zerop(driverdata);
    2.32  
    2.33      // Fill in most fields:
    2.34 +    SDL_zerop(mode);
    2.35      mode->format = SDL_PIXELFORMAT_RGB888;
    2.36      mode->refresh_rate = 0;  // TODO, WinRT: see if refresh rate data is available, or relevant (for WinRT apps)
    2.37 +    mode->w = w;
    2.38 +    mode->h = h;
    2.39      mode->driverdata = driverdata;
    2.40      driverdata->currentOrientation = DisplayProperties::CurrentOrientation;
    2.41  
    2.42 -    // Calculate the display size given the window size, taking into account
    2.43 -    // the current display's DPI:
    2.44 -    const float currentDPI = Windows::Graphics::Display::DisplayProperties::LogicalDpi; 
    2.45 -    const float dipsPerInch = 96.0f;
    2.46 -    mode->w = (int) ((CoreWindow::GetForCurrentThread()->Bounds.Width * currentDPI) / dipsPerInch);
    2.47 -    mode->h = (int) ((CoreWindow::GetForCurrentThread()->Bounds.Height * currentDPI) / dipsPerInch);
    2.48 -
    2.49  #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
    2.50      // On Windows Phone, the native window's size is always in portrait,
    2.51      // regardless of the device's orientation.  This is in contrast to
    2.52 @@ -231,11 +234,6 @@
    2.53      if (WINRT_CalcDisplayModeUsingNativeWindow(&mode) != 0) {
    2.54          return -1;	// If WINRT_CalcDisplayModeUsingNativeWindow fails, it'll already have set the SDL error
    2.55      }
    2.56 -    
    2.57 -    if (mode.w == 0 || mode.h == 0) {
    2.58 -        SDL_free(mode.driverdata);
    2.59 -        return SDL_SetError("Unable to calculate the WinRT window/display's size");
    2.60 -    }
    2.61  
    2.62      if (WINRT_DuplicateDisplayMode(&desktop_mode, &mode) != 0) {
    2.63          return -1;