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() ...@@ -153,6 +153,29 @@ bool Surface::resetSwapChain()
return true; 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) bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
{ {
ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0); ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
...@@ -306,9 +329,17 @@ bool Surface::checkForOutOfDateSwapChain() ...@@ -306,9 +329,17 @@ bool Surface::checkForOutOfDateSwapChain()
int clientHeight = client.bottom - client.top; int clientHeight = client.bottom - client.top;
bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight(); bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
if (sizeDirty || mSwapIntervalDirty) if (mSwapIntervalDirty)
{ {
resetSwapChain(clientWidth, clientHeight); resetSwapChain(clientWidth, clientHeight);
}
else if (sizeDirty)
{
resizeSwapChain(clientWidth, clientHeight);
}
if (mSwapIntervalDirty || sizeDirty)
{
if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this) if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
{ {
glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this); glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this);
...@@ -316,6 +347,7 @@ bool Surface::checkForOutOfDateSwapChain() ...@@ -316,6 +347,7 @@ bool Surface::checkForOutOfDateSwapChain()
return true; return true;
} }
return false; return false;
} }
......
...@@ -75,6 +75,7 @@ private: ...@@ -75,6 +75,7 @@ private:
void subclassWindow(); void subclassWindow();
void unsubclassWindow(); void unsubclassWindow();
bool resizeSwapChain(int backbufferWidth, int backbufferHeight);
bool resetSwapChain(int backbufferWidth, int backbufferHeight); bool resetSwapChain(int backbufferWidth, int backbufferHeight);
bool swapRect(EGLint x, EGLint y, EGLint width, EGLint height); bool swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
......
...@@ -31,6 +31,7 @@ class SwapChain ...@@ -31,6 +31,7 @@ class SwapChain
virtual ~SwapChain() {}; virtual ~SwapChain() {};
virtual EGLint resize(EGLint backbufferWidth, EGLint backbufferSize) = 0;
virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval) = 0; virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval) = 0;
virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height) = 0; virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height) = 0;
......
...@@ -363,6 +363,66 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei ...@@ -363,6 +363,66 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
return EGL_SUCCESS; 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) EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)
{ {
ID3D11Device *device = mRenderer->getDevice(); ID3D11Device *device = mRenderer->getDevice();
......
...@@ -25,6 +25,7 @@ class SwapChain11 : public SwapChain ...@@ -25,6 +25,7 @@ class SwapChain11 : public SwapChain
GLenum backBufferFormat, GLenum depthBufferFormat); GLenum backBufferFormat, GLenum depthBufferFormat);
virtual ~SwapChain11(); virtual ~SwapChain11();
EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight);
virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval); virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval);
virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height); virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
......
...@@ -30,6 +30,7 @@ SwapChain9::SwapChain9(Renderer9 *renderer, HWND window, HANDLE shareHandle, ...@@ -30,6 +30,7 @@ SwapChain9::SwapChain9(Renderer9 *renderer, HWND window, HANDLE shareHandle,
mOffscreenTexture = NULL; mOffscreenTexture = NULL;
mWidth = -1; mWidth = -1;
mHeight = -1; mHeight = -1;
mSwapInterval = -1;
} }
SwapChain9::~SwapChain9() SwapChain9::~SwapChain9()
...@@ -88,6 +89,12 @@ static DWORD convertInterval(EGLint interval) ...@@ -88,6 +89,12 @@ static DWORD convertInterval(EGLint interval)
return D3DPRESENT_INTERVAL_DEFAULT; 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) EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)
{ {
IDirect3DDevice9 *device = mRenderer->getDevice(); IDirect3DDevice9 *device = mRenderer->getDevice();
...@@ -264,6 +271,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI ...@@ -264,6 +271,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
mWidth = backbufferWidth; mWidth = backbufferWidth;
mHeight = backbufferHeight; mHeight = backbufferHeight;
mSwapInterval = swapInterval;
return EGL_SUCCESS; return EGL_SUCCESS;
} }
......
...@@ -25,6 +25,7 @@ class SwapChain9 : public SwapChain ...@@ -25,6 +25,7 @@ class SwapChain9 : public SwapChain
GLenum backBufferFormat, GLenum depthBufferFormat); GLenum backBufferFormat, GLenum depthBufferFormat);
virtual ~SwapChain9(); virtual ~SwapChain9();
EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight);
virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval); virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval);
virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height); virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
...@@ -42,6 +43,7 @@ class SwapChain9 : public SwapChain ...@@ -42,6 +43,7 @@ class SwapChain9 : public SwapChain
Renderer9 *mRenderer; Renderer9 *mRenderer;
EGLint mHeight; EGLint mHeight;
EGLint mWidth; EGLint mWidth;
EGLint mSwapInterval;
IDirect3DSwapChain9 *mSwapChain; IDirect3DSwapChain9 *mSwapChain;
IDirect3DSurface9 *mBackBuffer; 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