diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 63dbfe00b..da45862a9 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -84,6 +84,8 @@ static void D3D11_DestroyRenderer(SDL_Renderer * renderer); /* Direct3D 11.1 Internal Functions */ HRESULT D3D11_CreateDeviceResources(SDL_Renderer * renderer); HRESULT D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer); +HRESULT D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer); +HRESULT D3D11_HandleDeviceLost(SDL_Renderer * renderer); extern "C" { SDL_RenderDriver D3D11_RenderDriver = { @@ -211,6 +213,7 @@ D3D11_ReadShaderContents(const wstring & shaderName, vector & out) return D3D11_ReadFileContents(fileName, out); } +// Create resources that depend on the device. HRESULT D3D11_CreateDeviceResources(SDL_Renderer * renderer) { @@ -425,6 +428,7 @@ D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer * renderer) return *coreWindowPointer; } +// Method to convert a length in device-independent pixels (DIPs) to a length in physical pixels. static float D3D11_ConvertDipsToPixels(float dips) { @@ -433,6 +437,7 @@ D3D11_ConvertDipsToPixels(float dips) } #endif +// Initialize all resources that change when the window's size changes. // WinRT, TODO: get D3D11_CreateWindowSizeDependentResources working on Win32 HRESULT D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) @@ -655,6 +660,57 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) return S_OK; } +HRESULT +D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer) +{ + D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; + HRESULT result = S_OK; + Windows::UI::Core::CoreWindow ^ coreWindow = D3D11_GetCoreWindowFromSDLRenderer(renderer); + + if (coreWindow->Bounds.Width != data->windowSizeInDIPs.x || + coreWindow->Bounds.Height != data->windowSizeInDIPs.y || + data->orientation != DisplayProperties::CurrentOrientation) + { + ID3D11RenderTargetView* nullViews[] = {nullptr}; + data->d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr); + data->renderTargetView = nullptr; + data->d3dContext->Flush(); + result = D3D11_CreateWindowSizeDependentResources(renderer); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__, result); + return result; + } + } + + return S_OK; +} + +HRESULT +D3D11_HandleDeviceLost(SDL_Renderer * renderer) +{ + D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; + HRESULT result = S_OK; + + // Reset these member variables to ensure that UpdateForWindowSizeChange recreates all resources. + data->windowSizeInDIPs.x = 0; + data->windowSizeInDIPs.y = 0; + data->swapChain = nullptr; + + result = D3D11_CreateDeviceResources(renderer); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__, result); + return result; + } + + result = D3D11_UpdateForWindowSizeChange(renderer); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__, result); + return result; + } + + return S_OK; +} + static int D3D11_UpdateViewport(SDL_Renderer * renderer) { @@ -694,15 +750,18 @@ D3D11_RenderPresent(SDL_Renderer * renderer) // If the device was removed either by a disconnect or a driver upgrade, we // must recreate all device resources. + // + // TODO, WinRT: consider throwing an exception if D3D11_RenderPresent fails, especially if there is a way to salvedge debug info from users' machines if (hr == DXGI_ERROR_DEVICE_REMOVED) { - extern void WINRT_HandleDeviceLost(); // TODO, WinRT: move lost-device handling into the Direct3D 11.1 renderer, as appropriate - WINRT_HandleDeviceLost(); + hr = D3D11_HandleDeviceLost(renderer); + if (FAILED(hr)) { + WIN_SetErrorFromHRESULT(__FUNCTION__, hr); + } } else { WIN_SetErrorFromHRESULT(__FUNCTION__, hr); - // TODO, WinRT: consider throwing an exception if D3D11_RenderPresent fails, especially if there is a way to salvedge debug info from users' machines } } diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index aa204aa4d..493d88195 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -33,12 +33,6 @@ static SDL_WinRT_MainFunction SDL_WinRT_main = nullptr; // SDL_CreateWindow(). SDL_WinRTApp ^ SDL_WinRTGlobalApp = nullptr; -// HACK: provide a temporary means for the Direct3D 11.1 renderer to handle lost devices, while refactoring is underway -void WINRT_HandleDeviceLost() -{ - SDL_WinRTGlobalApp->m_renderer->HandleDeviceLost(); -} - using namespace Windows::ApplicationModel; using namespace Windows::ApplicationModel::Core; using namespace Windows::ApplicationModel::Activation; diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index dcc68fd8e..ea831ddce 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -16,9 +16,8 @@ using namespace Windows::UI::Core; using namespace Windows::Foundation; using namespace Windows::Graphics::Display; -extern HRESULT D3D11_CreateDeviceResources(SDL_Renderer * renderer); extern CoreWindow ^ D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer * renderer); -extern HRESULT D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer); +extern HRESULT D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer); // Constructor. SDL_winrtrenderer::SDL_winrtrenderer() : @@ -36,31 +35,6 @@ SDL_winrtrenderer::~SDL_winrtrenderer() } } -// Recreate all device resources and set them back to the current state. -void SDL_winrtrenderer::HandleDeviceLost() -{ - // Reset these member variables to ensure that UpdateForWindowSizeChange recreates all resources. - m_sdlRendererData->windowSizeInDIPs.x = 0; - m_sdlRendererData->windowSizeInDIPs.y = 0; - m_sdlRendererData->swapChain = nullptr; - - // TODO, WinRT: reconnect HandleDeviceLost to SDL_Renderer - CreateDeviceResources(); - UpdateForWindowSizeChange(); -} - -// These are the resources that depend on the device. -void SDL_winrtrenderer::CreateDeviceResources() -{ - DX::ThrowIfFailed(D3D11_CreateDeviceResources(m_sdlRenderer)); -} - -// Allocate all memory resources that change on a window SizeChanged event. -void SDL_winrtrenderer::CreateWindowSizeDependentResources() -{ - DX::ThrowIfFailed(D3D11_CreateWindowSizeDependentResources(m_sdlRenderer)); -} - void SDL_winrtrenderer::ResizeMainTexture(int w, int h) { const int pixelSizeInBytes = 4; @@ -131,17 +105,7 @@ void SDL_winrtrenderer::ResizeMainTexture(int w, int h) // This method is called in the event handler for the SizeChanged event. void SDL_winrtrenderer::UpdateForWindowSizeChange() { - CoreWindow ^ coreWindow = D3D11_GetCoreWindowFromSDLRenderer(m_sdlRenderer); - if (coreWindow->Bounds.Width != m_sdlRendererData->windowSizeInDIPs.x || - coreWindow->Bounds.Height != m_sdlRendererData->windowSizeInDIPs.y || - m_sdlRendererData->orientation != DisplayProperties::CurrentOrientation) - { - ID3D11RenderTargetView* nullViews[] = {nullptr}; - m_sdlRendererData->d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr); - m_sdlRendererData->renderTargetView = nullptr; - m_sdlRendererData->d3dContext->Flush(); - CreateWindowSizeDependentResources(); - } + DX::ThrowIfFailed(D3D11_UpdateForWindowSizeChange(m_sdlRenderer)); } void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numrects) @@ -231,10 +195,3 @@ void SDL_winrtrenderer::Present() { SDL_RenderPresent(m_sdlRenderer); } - -// Method to convert a length in device-independent pixels (DIPs) to a length in physical pixels. -float SDL_winrtrenderer::ConvertDipsToPixels(float dips) -{ - static const float dipsPerInch = 96.0f; - return floor(dips * DisplayProperties::LogicalDpi / dipsPerInch + 0.5f); // Round to nearest integer. -} diff --git a/src/video/windowsrt/SDL_winrtrenderer.h b/src/video/windowsrt/SDL_winrtrenderer.h index 3cab8270d..7d172f8c3 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.h +++ b/src/video/windowsrt/SDL_winrtrenderer.h @@ -16,12 +16,8 @@ internal: public: virtual ~SDL_winrtrenderer(); - virtual void HandleDeviceLost(); - virtual void CreateDeviceResources(); - virtual void CreateWindowSizeDependentResources(); virtual void UpdateForWindowSizeChange(); virtual void Present(); - virtual float ConvertDipsToPixels(float dips); internal: virtual void Render(SDL_Surface * surface, SDL_Rect * rects, int numrects);