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 8579 ee7126c459d0
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
--- a/src/core/winrt/SDL_winrtapp_direct3d.cpp	Sat Mar 01 16:08:16 2014 -0500
+++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp	Sat Mar 01 16:37:30 2014 -0500
@@ -157,31 +157,39 @@
     // window-resize event as it appeared the SDL window didn't change
     // size, and the Direct3D 11.1 renderer wouldn't resize its swap
     // chain.
-    SDL_DisplayMode resizedDisplayMode;
-    if (WINRT_CalcDisplayModeUsingNativeWindow(&resizedDisplayMode) != 0) {
-        return;
-    }
-    
-    if (resizedDisplayMode.w == 0 || resizedDisplayMode.h == 0) {
-        if (resizedDisplayMode.driverdata) {
-            SDL_free(resizedDisplayMode.driverdata);
-        }
+    SDL_DisplayMode newDisplayMode;
+    if (WINRT_CalcDisplayModeUsingNativeWindow(&newDisplayMode) != 0) {
         return;
     }
 
+    // Make note of the old display mode, and it's old driverdata.
     SDL_DisplayMode oldDisplayMode;
     SDL_zero(oldDisplayMode);
     if (WINRT_GlobalSDLVideoDevice) {
         oldDisplayMode = WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode;
-        if (WINRT_DuplicateDisplayMode(&(WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode), &resizedDisplayMode) != 0) {
-            SDL_free(resizedDisplayMode.driverdata);
+    }
+
+    // Setup the new display mode in the appropriate spots.
+    if (WINRT_GlobalSDLVideoDevice) {
+        // Make a full copy of the display mode for display_modes[0],
+        // one with with a separately malloced 'driverdata' field.
+        // SDL_VideoQuit(), if called, will attempt to free the driverdata
+        // fields in 'desktop_mode' and each entry in the 'display_modes'
+        // array.
+        if (WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata) {
+            // Free the previous mode's memory
+            SDL_free(WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata);
+            WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata = NULL;
+        }
+        if (WINRT_DuplicateDisplayMode(&(WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0]), &newDisplayMode) != 0) {
+            // Uh oh, something went wrong.  A malloc call probably failed.
+            SDL_free(newDisplayMode.driverdata);
             return;
         }
-        WINRT_GlobalSDLVideoDevice->displays[0].current_mode = resizedDisplayMode;
-        if (WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata) {
-            SDL_free(WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata);
-        }
-        WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0] = resizedDisplayMode;
+
+        // Install 'newDisplayMode' into 'current_mode' and 'desktop_mode'.
+        WINRT_GlobalSDLVideoDevice->displays[0].current_mode = newDisplayMode;
+        WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode = newDisplayMode;
     }
 
     if (WINRT_GlobalSDLWindow) {
@@ -189,8 +197,8 @@
         SDL_SendWindowEvent(
             WINRT_GlobalSDLWindow,
             SDL_WINDOWEVENT_RESIZED,
-            resizedDisplayMode.w,
-            resizedDisplayMode.h);
+            newDisplayMode.w,
+            newDisplayMode.h);
 
 #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
         // HACK: On Windows Phone, make sure that orientation changes from
@@ -198,7 +206,7 @@
         // or vice-versa on either of those two, lead to the Direct3D renderer
         // getting updated.
         const DisplayOrientations oldOrientation = ((SDL_DisplayModeData *)oldDisplayMode.driverdata)->currentOrientation;
-        const DisplayOrientations newOrientation = ((SDL_DisplayModeData *)resizedDisplayMode.driverdata)->currentOrientation;
+        const DisplayOrientations newOrientation = ((SDL_DisplayModeData *)newDisplayMode.driverdata)->currentOrientation;
 
         if ((oldOrientation == DisplayOrientations::Landscape && newOrientation == DisplayOrientations::LandscapeFlipped) ||
             (oldOrientation == DisplayOrientations::LandscapeFlipped && newOrientation == DisplayOrientations::Landscape) ||
@@ -213,21 +221,23 @@
             // Make sure that the display/window size really didn't change.  If
             // it did, then a SDL_WINDOWEVENT_SIZE_CHANGED event got sent, and
             // the Direct3D 11.1 renderer picked it up, presumably.
-            if (oldDisplayMode.w == resizedDisplayMode.w &&
-                oldDisplayMode.h == resizedDisplayMode.h)
+            if (oldDisplayMode.w == newDisplayMode.w &&
+                oldDisplayMode.h == newDisplayMode.h)
             {
                 SDL_SendWindowEvent(
                     WINRT_GlobalSDLWindow,
                     SDL_WINDOWEVENT_SIZE_CHANGED,
-                    resizedDisplayMode.w,
-                    resizedDisplayMode.h);
+                    newDisplayMode.w,
+                    newDisplayMode.h);
             }
         }
 #endif
     }
     
+    // Finally, free the 'driverdata' field of the old 'desktop_mode'.
     if (oldDisplayMode.driverdata) {
         SDL_free(oldDisplayMode.driverdata);
+        oldDisplayMode.driverdata = NULL;
     }
 }
 
--- a/src/video/winrt/SDL_winrtvideo.cpp	Sat Mar 01 16:08:16 2014 -0500
+++ b/src/video/winrt/SDL_winrtvideo.cpp	Sat Mar 01 16:37:30 2014 -0500
@@ -154,9 +154,6 @@
 
     using namespace Windows::Graphics::Display;
 
-    // Initialize the mode to all zeros:
-    SDL_zerop(mode);
-
     // Go no further if a native window cannot be accessed.  This can happen,
     // for example, if this function is called from certain threads, such as
     // the SDL/XAML thread.
@@ -164,6 +161,16 @@
         return SDL_SetError("SDL/WinRT display modes cannot be calculated outside of the main thread, such as in SDL's XAML thread");
     }
 
+    // Calculate the display size given the window size, taking into account
+    // the current display's DPI:
+    const float currentDPI = Windows::Graphics::Display::DisplayProperties::LogicalDpi; 
+    const float dipsPerInch = 96.0f;
+    const int w = (int) ((CoreWindow::GetForCurrentThread()->Bounds.Width * currentDPI) / dipsPerInch);
+    const int h = (int) ((CoreWindow::GetForCurrentThread()->Bounds.Height * currentDPI) / dipsPerInch);
+    if (w == 0 || w == h) {
+        return SDL_SetError("Unable to calculate the WinRT window/display's size");
+    }
+
     // Create a driverdata field:
     driverdata = (SDL_DisplayModeData *) SDL_malloc(sizeof(*driverdata));
     if (!driverdata) {
@@ -172,18 +179,14 @@
     SDL_zerop(driverdata);
 
     // Fill in most fields:
+    SDL_zerop(mode);
     mode->format = SDL_PIXELFORMAT_RGB888;
     mode->refresh_rate = 0;  // TODO, WinRT: see if refresh rate data is available, or relevant (for WinRT apps)
+    mode->w = w;
+    mode->h = h;
     mode->driverdata = driverdata;
     driverdata->currentOrientation = DisplayProperties::CurrentOrientation;
 
-    // Calculate the display size given the window size, taking into account
-    // the current display's DPI:
-    const float currentDPI = Windows::Graphics::Display::DisplayProperties::LogicalDpi; 
-    const float dipsPerInch = 96.0f;
-    mode->w = (int) ((CoreWindow::GetForCurrentThread()->Bounds.Width * currentDPI) / dipsPerInch);
-    mode->h = (int) ((CoreWindow::GetForCurrentThread()->Bounds.Height * currentDPI) / dipsPerInch);
-
 #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
     // On Windows Phone, the native window's size is always in portrait,
     // regardless of the device's orientation.  This is in contrast to
@@ -231,11 +234,6 @@
     if (WINRT_CalcDisplayModeUsingNativeWindow(&mode) != 0) {
         return -1;	// If WINRT_CalcDisplayModeUsingNativeWindow fails, it'll already have set the SDL error
     }
-    
-    if (mode.w == 0 || mode.h == 0) {
-        SDL_free(mode.driverdata);
-        return SDL_SetError("Unable to calculate the WinRT window/display's size");
-    }
 
     if (WINRT_DuplicateDisplayMode(&desktop_mode, &mode) != 0) {
         return -1;