Creates new depthstencils for surfaces.

Trac #11396 Creates new depthstencils for new windows when multiple windows exist, repurposes original depthstencil if old windows have all been destroyed. Author: Shannon Woods Signed-off-by: Nicolas Capens Signed-off-by: Daniel Koch git-svn-id: https://angleproject.googlecode.com/svn/trunk@28 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent fe453651
...@@ -22,7 +22,7 @@ namespace egl ...@@ -22,7 +22,7 @@ namespace egl
class Surface class Surface
{ {
public: public:
Surface(IDirect3DDevice9 *device, IDirect3DSwapChain9 *swapChain, EGLint configID); Surface(IDirect3DDevice9 *device, IDirect3DSwapChain9 *swapChain, IDirect3DSurface9* depthStencil, EGLint configID);
~Surface(); ~Surface();
...@@ -33,12 +33,14 @@ class Surface ...@@ -33,12 +33,14 @@ class Surface
EGLint getHeight() const; EGLint getHeight() const;
virtual IDirect3DSurface9 *getRenderTarget(); virtual IDirect3DSurface9 *getRenderTarget();
virtual IDirect3DSurface9 *getDepthStencil();
private: private:
DISALLOW_COPY_AND_ASSIGN(Surface); DISALLOW_COPY_AND_ASSIGN(Surface);
IDirect3DSwapChain9 *const mSwapChain; IDirect3DSwapChain9 *const mSwapChain;
IDirect3DSurface9 *mBackBuffer; IDirect3DSurface9 *mBackBuffer;
IDirect3DSurface9 *mRenderTarget; IDirect3DSurface9 *mRenderTarget;
IDirect3DSurface9 *mDepthStencil;
const EGLint mConfigID; // ID of EGLConfig surface was created with const EGLint mConfigID; // ID of EGLConfig surface was created with
EGLint mHeight; // Height of surface EGLint mHeight; // Height of surface
......
...@@ -235,6 +235,7 @@ egl::Surface *Display::createWindowSurface(HWND window, EGLConfig config) ...@@ -235,6 +235,7 @@ egl::Surface *Display::createWindowSurface(HWND window, EGLConfig config)
presentParameters.Windowed = TRUE; // FIXME presentParameters.Windowed = TRUE; // FIXME
IDirect3DSwapChain9 *swapChain = NULL; IDirect3DSwapChain9 *swapChain = NULL;
IDirect3DSurface9 *depthStencilSurface = NULL;
if (!mDevice) if (!mDevice)
{ {
...@@ -250,25 +251,68 @@ egl::Surface *Display::createWindowSurface(HWND window, EGLConfig config) ...@@ -250,25 +251,68 @@ egl::Surface *Display::createWindowSurface(HWND window, EGLConfig config)
if (mDevice) if (mDevice)
{ {
mDevice->GetSwapChain(0, &swapChain); mDevice->GetSwapChain(0, &swapChain);
mDevice->GetDepthStencilSurface(&depthStencilSurface);
} }
} }
else else
{ {
HRESULT result = mDevice->CreateAdditionalSwapChain(&presentParameters, &swapChain); if (!mSurfaceSet.empty())
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{ {
return error(EGL_BAD_ALLOC, (egl::Surface*)NULL); // if the device already exists, and there are other surfaces/windows currently in use, we need to create
// a separate swap chain for the new draw surface.
HRESULT result = mDevice->CreateAdditionalSwapChain(&presentParameters, &swapChain);
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
ERR("Could not create additional swap chains. Out of memory.");
return error(EGL_BAD_ALLOC, (egl::Surface*)NULL);
}
ASSERT(SUCCEEDED(result));
// CreateAdditionalSwapChain does not automatically generate a depthstencil surface, unlike
// CreateDevice, so we must do so explicitly.
result = mDevice->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight,
presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType,
presentParameters.MultiSampleQuality, FALSE, &depthStencilSurface, NULL);
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
swapChain->Release();
ERR("Could not create depthstencil surface for new swap chain. Out of memory.");
return error(EGL_BAD_ALLOC, (egl::Surface*)NULL);
}
ASSERT(SUCCEEDED(result));
} }
else
{
// if the device already exists, but there are no surfaces in use, then all the surfaces/windows
// have been destroyed, and we should repurpose the originally created depthstencil surface for
// use with the new surface we are creating.
HRESULT result = mDevice->Reset(&presentParameters);
ASSERT(SUCCEEDED(result)); if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
ERR("Could not resent presentation parameters for device. Out of memory.");
return error(EGL_BAD_ALLOC, (egl::Surface*)NULL);
}
ASSERT(SUCCEEDED(result));
if (mDevice)
{
mDevice->GetSwapChain(0, &swapChain);
mDevice->GetDepthStencilSurface(&depthStencilSurface);
}
}
} }
Surface *surface = NULL; Surface *surface = NULL;
if (swapChain) if (swapChain)
{ {
surface = new Surface(mDevice, swapChain, configuration->mConfigID); surface = new Surface(mDevice, swapChain, depthStencilSurface, configuration->mConfigID);
mSurfaceSet.insert(surface); mSurfaceSet.insert(surface);
swapChain->Release(); swapChain->Release();
......
...@@ -15,7 +15,8 @@ ...@@ -15,7 +15,8 @@
namespace egl namespace egl
{ {
Surface::Surface(IDirect3DDevice9 *device, IDirect3DSwapChain9 *swapChain, EGLint configID) : mSwapChain(swapChain), mConfigID(configID) Surface::Surface(IDirect3DDevice9 *device, IDirect3DSwapChain9 *swapChain, IDirect3DSurface9 *depthStencil, EGLint configID)
: mSwapChain(swapChain), mConfigID(configID), mDepthStencil(depthStencil)
{ {
mBackBuffer = NULL; mBackBuffer = NULL;
mRenderTarget = NULL; mRenderTarget = NULL;
...@@ -64,6 +65,11 @@ Surface::~Surface() ...@@ -64,6 +65,11 @@ Surface::~Surface()
{ {
mRenderTarget->Release(); mRenderTarget->Release();
} }
if (mDepthStencil)
{
mDepthStencil->Release();
}
} }
HWND Surface::getWindowHandle() HWND Surface::getWindowHandle()
...@@ -171,4 +177,14 @@ IDirect3DSurface9 *Surface::getRenderTarget() ...@@ -171,4 +177,14 @@ IDirect3DSurface9 *Surface::getRenderTarget()
return mRenderTarget; return mRenderTarget;
} }
IDirect3DSurface9 *Surface::getDepthStencil()
{
if (mDepthStencil)
{
mDepthStencil->AddRef();
}
return mDepthStencil;
}
} }
...@@ -202,13 +202,12 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface) ...@@ -202,13 +202,12 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
// Wrap the existing Direct3D 9 resources into GL objects and assign them to the '0' names // Wrap the existing Direct3D 9 resources into GL objects and assign them to the '0' names
IDirect3DSurface9 *defaultRenderTarget = surface->getRenderTarget(); IDirect3DSurface9 *defaultRenderTarget = surface->getRenderTarget();
IDirect3DSurface9 *defaultDepthStencil = NULL; IDirect3DSurface9 *depthStencil = surface->getDepthStencil();
device->GetDepthStencilSurface(&defaultDepthStencil);
Framebuffer *framebufferZero = new Framebuffer(); Framebuffer *framebufferZero = new Framebuffer();
Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget); Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
Depthbuffer *depthbufferZero = new Depthbuffer(defaultDepthStencil); Depthbuffer *depthbufferZero = new Depthbuffer(depthStencil);
Stencilbuffer *stencilbufferZero = new Stencilbuffer(defaultDepthStencil); Stencilbuffer *stencilbufferZero = new Stencilbuffer(depthStencil);
setFramebufferZero(framebufferZero); setFramebufferZero(framebufferZero);
setColorbufferZero(colorbufferZero); setColorbufferZero(colorbufferZero);
...@@ -221,9 +220,9 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface) ...@@ -221,9 +220,9 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
defaultRenderTarget->Release(); defaultRenderTarget->Release();
if (defaultDepthStencil) if (depthStencil)
{ {
defaultDepthStencil->Release(); depthStencil->Release();
} }
} }
......
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