Add support for resizing the window without recreating the swap chain in D3D11.

TRAC #22406 Signed-off-by: Geoff Lang Signed-off-by: Shannon Woods Author: Jamie Madill git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1872 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 07765506
......@@ -153,6 +153,29 @@ bool Surface::resetSwapChain()
return true;
}
bool Surface::resizeSwapChain(int backbufferWidth, int backbufferHeight)
{
ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
ASSERT(mSwapChain);
EGLint status = mSwapChain->resize(backbufferWidth, backbufferHeight);
if (status == EGL_CONTEXT_LOST)
{
mDisplay->notifyDeviceLost();
return false;
}
else if (status != EGL_SUCCESS)
{
return error(status, false);
}
mWidth = backbufferWidth;
mHeight = backbufferHeight;
return true;
}
bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
{
ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
......@@ -306,9 +329,17 @@ bool Surface::checkForOutOfDateSwapChain()
int clientHeight = client.bottom - client.top;
bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
if (sizeDirty || mSwapIntervalDirty)
if (mSwapIntervalDirty)
{
resetSwapChain(clientWidth, clientHeight);
}
else if (sizeDirty)
{
resizeSwapChain(clientWidth, clientHeight);
}
if (mSwapIntervalDirty || sizeDirty)
{
if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
{
glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this);
......@@ -316,6 +347,7 @@ bool Surface::checkForOutOfDateSwapChain()
return true;
}
return false;
}
......
......@@ -75,6 +75,7 @@ private:
void subclassWindow();
void unsubclassWindow();
bool resizeSwapChain(int backbufferWidth, int backbufferHeight);
bool resetSwapChain(int backbufferWidth, int backbufferHeight);
bool swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
......
......@@ -31,6 +31,7 @@ class SwapChain
virtual ~SwapChain() {};
virtual EGLint resize(EGLint backbufferWidth, EGLint backbufferSize) = 0;
virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval) = 0;
virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height) = 0;
......
......@@ -363,6 +363,66 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
return EGL_SUCCESS;
}
EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
{
ID3D11Device *device = mRenderer->getDevice();
if (device == NULL)
{
return EGL_BAD_ACCESS;
}
// Can only call resize if we have already created our swap buffer and resources
ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView);
if (mBackBufferTexture)
{
mBackBufferTexture->Release();
mBackBufferTexture = NULL;
}
if (mBackBufferRTView)
{
mBackBufferRTView->Release();
mBackBufferRTView = NULL;
}
// Resize swap chain
DXGI_FORMAT backbufferDXGIFormat = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
HRESULT result = mSwapChain->ResizeBuffers(2, backbufferWidth, backbufferHeight, backbufferDXGIFormat, 0);
if (FAILED(result))
{
ERR("Error resizing swap chain buffers: 0x%08X", result);
release();
if (d3d11::isDeviceLostError(result))
{
return EGL_CONTEXT_LOST;
}
else
{
return EGL_BAD_ALLOC;
}
}
result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture);
ASSERT(SUCCEEDED(result));
if (SUCCEEDED(result))
{
d3d11::SetDebugName(mBackBufferTexture, "Back buffer texture");
}
result = device->CreateRenderTargetView(mBackBufferTexture, NULL, &mBackBufferRTView);
ASSERT(SUCCEEDED(result));
if (SUCCEEDED(result))
{
d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target");
}
return resetOffscreenTexture(backbufferWidth, backbufferHeight);
}
EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)
{
ID3D11Device *device = mRenderer->getDevice();
......
......@@ -25,6 +25,7 @@ class SwapChain11 : public SwapChain
GLenum backBufferFormat, GLenum depthBufferFormat);
virtual ~SwapChain11();
EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight);
virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval);
virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
......
......@@ -30,6 +30,7 @@ SwapChain9::SwapChain9(Renderer9 *renderer, HWND window, HANDLE shareHandle,
mOffscreenTexture = NULL;
mWidth = -1;
mHeight = -1;
mSwapInterval = -1;
}
SwapChain9::~SwapChain9()
......@@ -88,6 +89,12 @@ static DWORD convertInterval(EGLint interval)
return D3DPRESENT_INTERVAL_DEFAULT;
}
EGLint SwapChain9::resize(int backbufferWidth, int backbufferHeight)
{
// D3D9 does not support resizing swap chains without recreating them
return reset(backbufferWidth, backbufferHeight, mSwapInterval);
}
EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)
{
IDirect3DDevice9 *device = mRenderer->getDevice();
......@@ -264,6 +271,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
mWidth = backbufferWidth;
mHeight = backbufferHeight;
mSwapInterval = swapInterval;
return EGL_SUCCESS;
}
......
......@@ -25,6 +25,7 @@ class SwapChain9 : public SwapChain
GLenum backBufferFormat, GLenum depthBufferFormat);
virtual ~SwapChain9();
EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight);
virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval);
virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
......@@ -42,6 +43,7 @@ class SwapChain9 : public SwapChain
Renderer9 *mRenderer;
EGLint mHeight;
EGLint mWidth;
EGLint mSwapInterval;
IDirect3DSwapChain9 *mSwapChain;
IDirect3DSurface9 *mBackBuffer;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment