Preserve the D3D11 offscreen texture contents when the swap chain is reset (ie from window resize).
TRAC #21929
Signed-off-by: Nicolas Capens
Signed-off-by: Shannon Woods
Author: Jamie Madill
git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1860 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/renderer/SwapChain11.cpp b/src/libGLESv2/renderer/SwapChain11.cpp
index 71b9ca0..f0f1f28 100644
--- a/src/libGLESv2/renderer/SwapChain11.cpp
+++ b/src/libGLESv2/renderer/SwapChain11.cpp
@@ -136,22 +136,15 @@
}
}
-EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHeight)
+void SwapChain11::releaseOffscreenTexture()
{
- ID3D11Device *device = mRenderer->getDevice();
-
- if (device == NULL)
- {
- return EGL_BAD_ACCESS;
- }
-
if (mOffscreenTexture)
{
mOffscreenTexture->Release();
mOffscreenTexture = NULL;
}
- if (mOffscreenRTView) // TODO: Preserve the render target content
+ if (mOffscreenRTView)
{
mOffscreenRTView->Release();
mOffscreenRTView = NULL;
@@ -174,6 +167,28 @@
mDepthStencilDSView->Release();
mDepthStencilDSView = NULL;
}
+}
+
+EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHeight)
+{
+ ID3D11Device *device = mRenderer->getDevice();
+
+ ASSERT(device != NULL);
+
+ // D3D11 does not allow zero size textures
+ ASSERT(backbufferWidth >= 1);
+ ASSERT(backbufferHeight >= 1);
+
+ // Preserve the render target content
+ ID3D11Texture2D *previousOffscreenTexture = mOffscreenTexture;
+ if (previousOffscreenTexture)
+ {
+ previousOffscreenTexture->AddRef();
+ }
+ const int previousWidth = mWidth;
+ const int previousHeight = mHeight;
+
+ releaseOffscreenTexture();
// If the app passed in a share handle, open the resource
// See EGL_ANGLE_d3d_share_handle_client_buffer
@@ -323,6 +338,28 @@
mWidth = backbufferWidth;
mHeight = backbufferHeight;
+ if (previousOffscreenTexture != NULL)
+ {
+ D3D11_BOX sourceBox = {0};
+ sourceBox.left = 0;
+ sourceBox.right = std::min(previousWidth, mWidth);
+ sourceBox.top = std::max(previousHeight - mHeight, 0);
+ sourceBox.bottom = previousHeight;
+ sourceBox.front = 0;
+ sourceBox.back = 1;
+
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ const int yoffset = std::max(mHeight - previousHeight, 0);
+ deviceContext->CopySubresourceRegion(mOffscreenTexture, 0, 0, yoffset, 0, previousOffscreenTexture, 0, &sourceBox);
+
+ previousOffscreenTexture->Release();
+
+ if (mSwapChain)
+ {
+ swapRect(0, 0, mWidth, mHeight);
+ }
+ }
+
return EGL_SUCCESS;
}