mirror of
				https://github.com/Ryujinx/SDL.git
				synced 2025-11-04 15:34:58 +00:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									33f81a0da5
								
							
						
					
					
						commit
						0a879d63bd
					
				| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue