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.
parent
33f81a0da5
commit
0a879d63bd
|
@ -229,36 +229,30 @@ WINRT_ProcessWindowSizeChange()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WINRT_GlobalSDLWindow) {
|
if (WINRT_GlobalSDLWindow) {
|
||||||
// Send a window-resize event to the rest of SDL, and to apps:
|
// 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(
|
SDL_SendWindowEvent(
|
||||||
WINRT_GlobalSDLWindow,
|
WINRT_GlobalSDLWindow,
|
||||||
SDL_WINDOWEVENT_RESIZED,
|
SDL_WINDOWEVENT_RESIZED,
|
||||||
newDisplayMode.w,
|
newDisplayMode.w,
|
||||||
newDisplayMode.h);
|
newDisplayMode.h);
|
||||||
|
} else {
|
||||||
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
|
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
|
||||||
// HACK: On Windows Phone, make sure that orientation changes from
|
// HACK: Make sure that orientation changes
|
||||||
// Landscape to LandscapeFlipped, Portrait to PortraitFlipped,
|
// lead to the Direct3D renderer's viewport getting updated:
|
||||||
// or vice-versa on either of those two, lead to the Direct3D renderer
|
//
|
||||||
// getting updated.
|
// 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 oldOrientation = ((SDL_DisplayModeData *)oldDisplayMode.driverdata)->currentOrientation;
|
||||||
const DisplayOrientations newOrientation = ((SDL_DisplayModeData *)newDisplayMode.driverdata)->currentOrientation;
|
const DisplayOrientations newOrientation = ((SDL_DisplayModeData *)newDisplayMode.driverdata)->currentOrientation;
|
||||||
|
if (oldOrientation != newOrientation)
|
||||||
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).
|
|
||||||
//
|
|
||||||
// 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)
|
|
||||||
{
|
{
|
||||||
SDL_SendWindowEvent(
|
SDL_SendWindowEvent(
|
||||||
WINRT_GlobalSDLWindow,
|
WINRT_GlobalSDLWindow,
|
||||||
|
@ -266,9 +260,9 @@ WINRT_ProcessWindowSizeChange()
|
||||||
newDisplayMode.w,
|
newDisplayMode.w,
|
||||||
newDisplayMode.h);
|
newDisplayMode.h);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Finally, free the 'driverdata' field of the old 'desktop_mode'.
|
// Finally, free the 'driverdata' field of the old 'desktop_mode'.
|
||||||
if (oldDisplayMode.driverdata) {
|
if (oldDisplayMode.driverdata) {
|
||||||
|
@ -309,26 +303,21 @@ void SDL_WinRTApp::OnOrientationChanged(Object^ sender)
|
||||||
if (window) {
|
if (window) {
|
||||||
SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, CoreWindow Size={%f,%f}\n",
|
SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, CoreWindow Size={%f,%f}\n",
|
||||||
__FUNCTION__,
|
__FUNCTION__,
|
||||||
(int)DisplayProperties::CurrentOrientation,
|
WINRT_DISPLAY_PROPERTY(CurrentOrientation),
|
||||||
(int)DisplayProperties::NativeOrientation,
|
WINRT_DISPLAY_PROPERTY(NativeOrientation),
|
||||||
(int)DisplayProperties::AutoRotationPreferences,
|
WINRT_DISPLAY_PROPERTY(AutoRotationPreferences),
|
||||||
window->Bounds.Width,
|
window->Bounds.Width,
|
||||||
window->Bounds.Height);
|
window->Bounds.Height);
|
||||||
} else {
|
} else {
|
||||||
SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d\n",
|
SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d\n",
|
||||||
__FUNCTION__,
|
__FUNCTION__,
|
||||||
(int)DisplayProperties::CurrentOrientation,
|
WINRT_DISPLAY_PROPERTY(CurrentOrientation),
|
||||||
(int)DisplayProperties::NativeOrientation,
|
WINRT_DISPLAY_PROPERTY(NativeOrientation),
|
||||||
(int)DisplayProperties::AutoRotationPreferences);
|
WINRT_DISPLAY_PROPERTY(AutoRotationPreferences));
|
||||||
}
|
}
|
||||||
#endif
|
#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();
|
WINRT_ProcessWindowSizeChange();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL_WinRTApp::SetWindow(CoreWindow^ window)
|
void SDL_WinRTApp::SetWindow(CoreWindow^ window)
|
||||||
|
@ -336,9 +325,9 @@ void SDL_WinRTApp::SetWindow(CoreWindow^ window)
|
||||||
#if LOG_WINDOW_EVENTS==1
|
#if LOG_WINDOW_EVENTS==1
|
||||||
SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, window Size={%f,%f}\n",
|
SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, window Size={%f,%f}\n",
|
||||||
__FUNCTION__,
|
__FUNCTION__,
|
||||||
(int)DisplayProperties::CurrentOrientation,
|
WINRT_DISPLAY_PROPERTY(CurrentOrientation),
|
||||||
(int)DisplayProperties::NativeOrientation,
|
WINRT_DISPLAY_PROPERTY(NativeOrientation),
|
||||||
(int)DisplayProperties::AutoRotationPreferences,
|
WINRT_DISPLAY_PROPERTY(AutoRotationPreferences),
|
||||||
window->Bounds.Width,
|
window->Bounds.Width,
|
||||||
window->Bounds.Height);
|
window->Bounds.Height);
|
||||||
#endif
|
#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",
|
SDL_Log("%s, size={%f,%f}, current orientation=%d, native orientation=%d, auto rot. pref=%d, WINRT_GlobalSDLWindow?=%s\n",
|
||||||
__FUNCTION__,
|
__FUNCTION__,
|
||||||
args->Size.Width, args->Size.Height,
|
args->Size.Width, args->Size.Height,
|
||||||
(int)DisplayProperties::CurrentOrientation,
|
WINRT_DISPLAY_PROPERTY(CurrentOrientation),
|
||||||
(int)DisplayProperties::NativeOrientation,
|
WINRT_DISPLAY_PROPERTY(NativeOrientation),
|
||||||
(int)DisplayProperties::AutoRotationPreferences,
|
WINRT_DISPLAY_PROPERTY(AutoRotationPreferences),
|
||||||
(WINRT_GlobalSDLWindow ? "yes" : "no"));
|
(WINRT_GlobalSDLWindow ? "yes" : "no"));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "SDL_syswm.h"
|
#include "SDL_syswm.h"
|
||||||
#include "../SDL_sysrender.h"
|
#include "../SDL_sysrender.h"
|
||||||
#include "../SDL_d3dmath.h"
|
#include "../SDL_d3dmath.h"
|
||||||
|
/* #include "SDL_log.h" */
|
||||||
|
|
||||||
#include <d3d11_1.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
|
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
|
||||||
swapChainDesc.Scaling = DXGI_SCALING_STRETCH; /* On phone, only stretch and aspect-ratio stretch scaling are allowed. */
|
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. */
|
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
|
#else
|
||||||
if (usingXAML) {
|
if (usingXAML) {
|
||||||
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
|
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
|
||||||
|
@ -1484,6 +1486,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
|
||||||
*/
|
*/
|
||||||
SDL_GetWindowSize(renderer->window, &w, &h);
|
SDL_GetWindowSize(renderer->window, &w, &h);
|
||||||
data->rotation = D3D11_GetCurrentRotation();
|
data->rotation = D3D11_GetCurrentRotation();
|
||||||
|
/* SDL_Log("%s: windowSize={%d,%d}, orientation=%d\n", __FUNCTION__, w, h, (int)data->rotation); */
|
||||||
if (D3D11_IsDisplayRotated90Degrees(data->rotation)) {
|
if (D3D11_IsDisplayRotated90Degrees(data->rotation)) {
|
||||||
int tmp = w;
|
int tmp = w;
|
||||||
w = h;
|
w = h;
|
||||||
|
@ -1521,11 +1524,21 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
|
#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
|
||||||
/* Set the proper rotation for the swap chain, and generate the
|
/* Set the proper rotation for the swap chain.
|
||||||
* 3D matrix transformation for rendering to the rotated swap chain.
|
|
||||||
*
|
*
|
||||||
* To note, the call for this, IDXGISwapChain1::SetRotation, is not necessary
|
* 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) {
|
if (data->swapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL) {
|
||||||
result = IDXGISwapChain1_SetRotation(data->swapChain, data->rotation);
|
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
|
* SDL_CreateRenderer is calling it, and will call it again later
|
||||||
* with a non-empty viewport.
|
* with a non-empty viewport.
|
||||||
*/
|
*/
|
||||||
|
/* SDL_Log("%s, no viewport was set!\n", __FUNCTION__); */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2223,6 +2237,7 @@ D3D11_UpdateViewport(SDL_Renderer * renderer)
|
||||||
viewport.Height = orientationAlignedViewport.h;
|
viewport.Height = orientationAlignedViewport.h;
|
||||||
viewport.MinDepth = 0.0f;
|
viewport.MinDepth = 0.0f;
|
||||||
viewport.MaxDepth = 1.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);
|
ID3D11DeviceContext_RSSetViewports(data->d3dContext, 1, &viewport);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -53,6 +53,7 @@ extern "C" {
|
||||||
#include "SDL_winrtmouse_c.h"
|
#include "SDL_winrtmouse_c.h"
|
||||||
#include "SDL_main.h"
|
#include "SDL_main.h"
|
||||||
#include "SDL_system.h"
|
#include "SDL_system.h"
|
||||||
|
//#include "SDL_log.h"
|
||||||
|
|
||||||
|
|
||||||
/* Initialization/Query functions */
|
/* 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");
|
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
|
// Calculate the display size given the window size, taking into account
|
||||||
// the current display's DPI:
|
// the current display's DPI:
|
||||||
#if NTDDI_VERSION > NTDDI_WIN8
|
#if NTDDI_VERSION > NTDDI_WIN8
|
||||||
|
@ -208,10 +217,10 @@ WINRT_CalcDisplayModeUsingNativeWindow(SDL_DisplayMode * mode)
|
||||||
driverdata->currentOrientation = DisplayProperties::CurrentOrientation;
|
driverdata->currentOrientation = DisplayProperties::CurrentOrientation;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
|
#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) && (NTDDI_VERSION == NTDDI_WIN8)
|
||||||
// On Windows Phone, the native window's size is always in portrait,
|
// 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
|
// 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,
|
// orientation changes. In order to compensate for this behavior,
|
||||||
// on Windows Phone, the mode's width and height will be swapped when
|
// on Windows Phone, the mode's width and height will be swapped when
|
||||||
// the device is in a landscape (non-portrait) mode.
|
// the device is in a landscape (non-portrait) mode.
|
||||||
|
|
|
@ -70,6 +70,13 @@ typedef struct
|
||||||
|
|
||||||
#ifdef __cplusplus_winrt
|
#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 */
|
/* Internal window data */
|
||||||
struct SDL_WindowData
|
struct SDL_WindowData
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue