Fixed rendering-alignment issues on WinPhone 8.1, when the device was rotated If a Windows Phone 8.1 device was rotated to anything but Portrait mode, the Direct3D 11 renderer's output wouldn't get aligned correctly with the screen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
diff --git a/src/core/winrt/SDL_winrtapp_direct3d.cpp b/src/core/winrt/SDL_winrtapp_direct3d.cpp
index 3a9f597..d17171b 100644
--- a/src/core/winrt/SDL_winrtapp_direct3d.cpp
+++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp
@@ -229,36 +229,30 @@ WINRT_ProcessWindowSizeChange()
}
if (WINRT_GlobalSDLWindow) {
- // Send a window-resize event to the rest of SDL, and to apps:
- SDL_SendWindowEvent(
- WINRT_GlobalSDLWindow,
- SDL_WINDOWEVENT_RESIZED,
- newDisplayMode.w,
- newDisplayMode.h);
-
+ // If the window size changed, send a resize event to SDL and its host app:
+ int window_w = 0;
+ int window_h = 0;
+ SDL_GetWindowSize(WINRT_GlobalSDLWindow, &window_w, &window_h);
+ if ((window_w != newDisplayMode.w) || (window_h != newDisplayMode.h)) {
+ SDL_SendWindowEvent(
+ WINRT_GlobalSDLWindow,
+ SDL_WINDOWEVENT_RESIZED,
+ newDisplayMode.w,
+ newDisplayMode.h);
+ } else {
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
- // HACK: On Windows Phone, make sure that orientation changes from
- // Landscape to LandscapeFlipped, Portrait to PortraitFlipped,
- // 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 *)newDisplayMode.driverdata)->currentOrientation;
-
- if ((oldOrientation == DisplayOrientations::Landscape && newOrientation == DisplayOrientations::LandscapeFlipped) ||
- (oldOrientation == DisplayOrientations::LandscapeFlipped && newOrientation == DisplayOrientations::Landscape) ||
- (oldOrientation == DisplayOrientations::Portrait && newOrientation == DisplayOrientations::PortraitFlipped) ||
- (oldOrientation == DisplayOrientations::PortraitFlipped && newOrientation == DisplayOrientations::Portrait))
- {
- // One of the reasons this event is getting sent out is because SDL
- // will ignore requests to send out SDL_WINDOWEVENT_RESIZED events
- // if and when the event size doesn't change (and the Direct3D 11.1
- // renderer doesn't get the memo).
+ // HACK: Make sure that orientation changes
+ // lead to the Direct3D renderer's viewport getting updated:
//
- // 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 == newDisplayMode.w &&
- oldDisplayMode.h == newDisplayMode.h)
+ // For some reason, this doesn't seem to need to be done on Windows 8.x,
+ // even when going from Landscape to LandscapeFlipped. It only seems to
+ // be needed on Windows Phone, at least when I tested on my devices.
+ // I'm not currently sure why this is, but it seems to work fine. -- David L.
+ //
+ // TODO, WinRT: do more extensive research into why orientation changes on Win 8.x don't need D3D changes, or if they might, in some cases
+ const DisplayOrientations oldOrientation = ((SDL_DisplayModeData *)oldDisplayMode.driverdata)->currentOrientation;
+ const DisplayOrientations newOrientation = ((SDL_DisplayModeData *)newDisplayMode.driverdata)->currentOrientation;
+ if (oldOrientation != newOrientation)
{
SDL_SendWindowEvent(
WINRT_GlobalSDLWindow,
@@ -266,8 +260,8 @@ WINRT_ProcessWindowSizeChange()
newDisplayMode.w,
newDisplayMode.h);
}
- }
#endif
+ }
}
// Finally, free the 'driverdata' field of the old 'desktop_mode'.
@@ -309,26 +303,21 @@ void SDL_WinRTApp::OnOrientationChanged(Object^ sender)
if (window) {
SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, CoreWindow Size={%f,%f}\n",
__FUNCTION__,
- (int)DisplayProperties::CurrentOrientation,
- (int)DisplayProperties::NativeOrientation,
- (int)DisplayProperties::AutoRotationPreferences,
+ WINRT_DISPLAY_PROPERTY(CurrentOrientation),
+ WINRT_DISPLAY_PROPERTY(NativeOrientation),
+ WINRT_DISPLAY_PROPERTY(AutoRotationPreferences),
window->Bounds.Width,
window->Bounds.Height);
} else {
SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d\n",
__FUNCTION__,
- (int)DisplayProperties::CurrentOrientation,
- (int)DisplayProperties::NativeOrientation,
- (int)DisplayProperties::AutoRotationPreferences);
+ WINRT_DISPLAY_PROPERTY(CurrentOrientation),
+ WINRT_DISPLAY_PROPERTY(NativeOrientation),
+ WINRT_DISPLAY_PROPERTY(AutoRotationPreferences));
}
#endif
-#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
- // On Windows Phone, treat an orientation change as a change in window size.
- // The native window's size doesn't seem to change, however SDL will simulate
- // a window size change.
WINRT_ProcessWindowSizeChange();
-#endif
}
void SDL_WinRTApp::SetWindow(CoreWindow^ window)
@@ -336,9 +325,9 @@ void SDL_WinRTApp::SetWindow(CoreWindow^ window)
#if LOG_WINDOW_EVENTS==1
SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, window Size={%f,%f}\n",
__FUNCTION__,
- (int)DisplayProperties::CurrentOrientation,
- (int)DisplayProperties::NativeOrientation,
- (int)DisplayProperties::AutoRotationPreferences,
+ WINRT_DISPLAY_PROPERTY(CurrentOrientation),
+ WINRT_DISPLAY_PROPERTY(NativeOrientation),
+ WINRT_DISPLAY_PROPERTY(AutoRotationPreferences),
window->Bounds.Width,
window->Bounds.Height);
#endif
@@ -540,9 +529,9 @@ void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEven
SDL_Log("%s, size={%f,%f}, current orientation=%d, native orientation=%d, auto rot. pref=%d, WINRT_GlobalSDLWindow?=%s\n",
__FUNCTION__,
args->Size.Width, args->Size.Height,
- (int)DisplayProperties::CurrentOrientation,
- (int)DisplayProperties::NativeOrientation,
- (int)DisplayProperties::AutoRotationPreferences,
+ WINRT_DISPLAY_PROPERTY(CurrentOrientation),
+ WINRT_DISPLAY_PROPERTY(NativeOrientation),
+ WINRT_DISPLAY_PROPERTY(AutoRotationPreferences),
(WINRT_GlobalSDLWindow ? "yes" : "no"));
#endif
diff --git a/src/render/direct3d11/SDL_render_d3d11.c b/src/render/direct3d11/SDL_render_d3d11.c
index 1e2b099..2f1164b 100644
--- a/src/render/direct3d11/SDL_render_d3d11.c
+++ b/src/render/direct3d11/SDL_render_d3d11.c
@@ -29,6 +29,7 @@
#include "SDL_syswm.h"
#include "../SDL_sysrender.h"
#include "../SDL_d3dmath.h"
+/* #include "SDL_log.h" */
#include <d3d11_1.h>
@@ -1390,6 +1391,7 @@ D3D11_CreateSwapChain(SDL_Renderer * renderer, int w, int h)
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
swapChainDesc.Scaling = DXGI_SCALING_STRETCH; /* On phone, only stretch and aspect-ratio stretch scaling are allowed. */
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; /* On phone, no swap effects are supported. */
+ /* TODO, WinRT: see if Win 8.x DXGI_SWAP_CHAIN_DESC1 settings are available on Windows Phone 8.1, and if there's any advantage to having them on */
#else
if (usingXAML) {
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
@@ -1484,6 +1486,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
*/
SDL_GetWindowSize(renderer->window, &w, &h);
data->rotation = D3D11_GetCurrentRotation();
+ /* SDL_Log("%s: windowSize={%d,%d}, orientation=%d\n", __FUNCTION__, w, h, (int)data->rotation); */
if (D3D11_IsDisplayRotated90Degrees(data->rotation)) {
int tmp = w;
w = h;
@@ -1521,11 +1524,21 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
}
#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
- /* Set the proper rotation for the swap chain, and generate the
- * 3D matrix transformation for rendering to the rotated swap chain.
+ /* Set the proper rotation for the swap chain.
*
* To note, the call for this, IDXGISwapChain1::SetRotation, is not necessary
- * on Windows Phone, nor is it supported there. It's only needed in Windows 8/RT.
+ * on Windows Phone 8.0, nor is it supported there.
+ *
+ * IDXGISwapChain1::SetRotation does seem to be available on Windows Phone 8.1,
+ * however I've yet to find a way to make it work. It might have something to
+ * do with IDXGISwapChain::ResizeBuffers appearing to not being available on
+ * Windows Phone 8.1 (it wasn't on Windows Phone 8.0), but I'm not 100% sure of this.
+ * The call doesn't appear to be entirely necessary though, and is a performance-related
+ * call, at least according to the following page on MSDN:
+ * http://code.msdn.microsoft.com/windowsapps/DXGI-swap-chain-rotation-21d13d71
+ * -- David L.
+ *
+ * TODO, WinRT: reexamine the docs for IDXGISwapChain1::SetRotation, see if might be available, usable, and prudent-to-call on WinPhone 8.1
*/
if (data->swapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL) {
result = IDXGISwapChain1_SetRotation(data->swapChain, data->rotation);
@@ -2144,6 +2157,7 @@ D3D11_UpdateViewport(SDL_Renderer * renderer)
* SDL_CreateRenderer is calling it, and will call it again later
* with a non-empty viewport.
*/
+ /* SDL_Log("%s, no viewport was set!\n", __FUNCTION__); */
return 0;
}
@@ -2223,6 +2237,7 @@ D3D11_UpdateViewport(SDL_Renderer * renderer)
viewport.Height = orientationAlignedViewport.h;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
+ /* SDL_Log("%s: D3D viewport = {%f,%f,%f,%f}\n", __FUNCTION__, viewport.TopLeftX, viewport.TopLeftY, viewport.Width, viewport.Height); */
ID3D11DeviceContext_RSSetViewports(data->d3dContext, 1, &viewport);
return 0;
diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp
index 6c6fce0..0443b99 100644
--- a/src/video/winrt/SDL_winrtvideo.cpp
+++ b/src/video/winrt/SDL_winrtvideo.cpp
@@ -53,6 +53,7 @@ extern "C" {
#include "SDL_winrtmouse_c.h"
#include "SDL_main.h"
#include "SDL_system.h"
+//#include "SDL_log.h"
/* Initialization/Query functions */
@@ -174,6 +175,14 @@ 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");
}
+ //SDL_Log("%s, size={%f,%f}, current orientation=%d, native orientation=%d, auto rot. pref=%d, DPI = %f\n",
+ // __FUNCTION__,
+ // CoreWindow::GetForCurrentThread()->Bounds.Width, CoreWindow::GetForCurrentThread()->Bounds.Height,
+ // WINRT_DISPLAY_PROPERTY(CurrentOrientation),
+ // WINRT_DISPLAY_PROPERTY(NativeOrientation),
+ // WINRT_DISPLAY_PROPERTY(AutoRotationPreferences),
+ // WINRT_DISPLAY_PROPERTY(LogicalDpi));
+
// Calculate the display size given the window size, taking into account
// the current display's DPI:
#if NTDDI_VERSION > NTDDI_WIN8
@@ -208,10 +217,10 @@ WINRT_CalcDisplayModeUsingNativeWindow(SDL_DisplayMode * mode)
driverdata->currentOrientation = DisplayProperties::CurrentOrientation;
#endif
-#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
- // On Windows Phone, the native window's size is always in portrait,
+#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) && (NTDDI_VERSION == NTDDI_WIN8)
+ // On Windows Phone 8.0, the native window's size is always in portrait,
// regardless of the device's orientation. This is in contrast to
- // Windows 8/RT, which will resize the native window as the device's
+ // Windows 8.x/RT and Windows Phone 8.1, which will resize the native window as the device's
// orientation changes. In order to compensate for this behavior,
// on Windows Phone, the mode's width and height will be swapped when
// the device is in a landscape (non-portrait) mode.
diff --git a/src/video/winrt/SDL_winrtvideo_cpp.h b/src/video/winrt/SDL_winrtvideo_cpp.h
index a90f043..e327280 100644
--- a/src/video/winrt/SDL_winrtvideo_cpp.h
+++ b/src/video/winrt/SDL_winrtvideo_cpp.h
@@ -70,6 +70,13 @@ typedef struct
#ifdef __cplusplus_winrt
+/* A convenience macro to get a WinRT display property */
+#if NTDDI_VERSION > NTDDI_WIN8
+#define WINRT_DISPLAY_PROPERTY(NAME) (Windows::Graphics::Display::DisplayInformation::GetForCurrentView()->NAME)
+#else
+#define WINRT_DISPLAY_PROPERTY(NAME) (Windows::Graphics::Display::DisplayProperties::NAME)
+#endif
+
/* Internal window data */
struct SDL_WindowData
{