From 6687ece1d56e7ef1fe332d40f75db91826847849 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 1 Mar 2014 16:37:30 -0500 Subject: [PATCH] WinRT: cleaned up some hard-to-read SDL_DisplayMode management code --- src/core/winrt/SDL_winrtapp_direct3d.cpp | 54 ++++++++++++++---------- src/video/winrt/SDL_winrtvideo.cpp | 28 ++++++------ 2 files changed, 45 insertions(+), 37 deletions(-) diff --git a/src/core/winrt/SDL_winrtapp_direct3d.cpp b/src/core/winrt/SDL_winrtapp_direct3d.cpp index a649432d2f0a5..d484300665f39 100644 --- a/src/core/winrt/SDL_winrtapp_direct3d.cpp +++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp @@ -157,31 +157,39 @@ WINRT_ProcessWindowSizeChange() // 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); - return; - } - WINRT_GlobalSDLVideoDevice->displays[0].current_mode = resizedDisplayMode; + } + + // 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; } - WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0] = resizedDisplayMode; + 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; + } + + // 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 @@ WINRT_ProcessWindowSizeChange() 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 @@ WINRT_ProcessWindowSizeChange() // 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 @@ WINRT_ProcessWindowSizeChange() // 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; } } diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index 66993916c2411..d5f4679609e8a 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -154,9 +154,6 @@ WINRT_CalcDisplayModeUsingNativeWindow(SDL_DisplayMode * mode) 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 @@ WINRT_CalcDisplayModeUsingNativeWindow(SDL_DisplayMode * mode) 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 @@ WINRT_CalcDisplayModeUsingNativeWindow(SDL_DisplayMode * mode) 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 @@ WINRT_InitModes(_THIS) 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;