From d624070755d8214702293d3c30c9b1537e2ae290 Mon Sep 17 00:00:00 2001 From: Michael Niksa Date: Tue, 2 Jul 2019 12:51:28 -0700 Subject: [PATCH] Stop crash on window snap by preventing torn device resources state (#1768) * Stop crash on window snap by preventing torn device resources state when quick on-the-fly resizing operations happen. #1572 (cherry picked from commit d8485079cd8d676cea7dd4400a5233d31ea49829) --- src/renderer/dx/DxRenderer.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/renderer/dx/DxRenderer.cpp b/src/renderer/dx/DxRenderer.cpp index 77968b9af..3bf47478a 100644 --- a/src/renderer/dx/DxRenderer.cpp +++ b/src/renderer/dx/DxRenderer.cpp @@ -690,10 +690,24 @@ void DxEngine::_InvalidOr(RECT rc) noexcept else if (_displaySizePixels.cy != clientSize.cy || _displaySizePixels.cx != clientSize.cx) { + // OK, we're going to play a dangerous game here for the sake of optimizing resize + // First, set up a complete clear of all device resources if something goes terribly wrong. + auto resetDeviceResourcesOnFailure = wil::scope_exit([&] { + _ReleaseDeviceResources(); + }); + + // Now let go of a few of the device resources that get in the way of resizing buffers in the swap chain _dxgiSurface.Reset(); _d2dRenderTarget.Reset(); - _dxgiSwapChain->ResizeBuffers(2, clientSize.cx, clientSize.cy, DXGI_FORMAT_B8G8R8A8_UNORM, 0); + + // Change the buffer size and recreate the render target (and surface) + RETURN_IF_FAILED(_dxgiSwapChain->ResizeBuffers(2, clientSize.cx, clientSize.cy, DXGI_FORMAT_B8G8R8A8_UNORM, 0)); RETURN_IF_FAILED(_PrepareRenderTarget()); + + // OK we made it past the parts that can cause errors. We can release our failure handler. + resetDeviceResourcesOnFailure.release(); + + // And persist the new size. _displaySizePixels = clientSize; }