Ensure all getDepthStencil and getRenderTarget calls consistently handle references to the underlying d3d surfaces
Trac #20875
Signed-off-by: Nicolas Capens
git-svn-id: http://angleproject.googlecode.com/svn/trunk@1114 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libEGL/Surface.cpp b/src/libEGL/Surface.cpp
index 07ad3cf..ca2ceea 100644
--- a/src/libEGL/Surface.cpp
+++ b/src/libEGL/Surface.cpp
@@ -565,6 +565,8 @@
return mPostSubBufferSupported;
}
+// Increments refcount on surface.
+// caller must Release() the returned surface
IDirect3DSurface9 *Surface::getRenderTarget()
{
if (mRenderTarget)
@@ -575,6 +577,8 @@
return mRenderTarget;
}
+// Increments refcount on surface.
+// caller must Release() the returned surface
IDirect3DSurface9 *Surface::getDepthStencil()
{
if (mDepthStencil)
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 78cee50..b395130 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -1893,6 +1893,11 @@
mDepthStencilInitialized = true;
}
+ if (depthStencil)
+ {
+ depthStencil->Release();
+ }
+
if (!mRenderTargetDescInitialized || renderTargetChanged)
{
IDirect3DSurface9 *renderTarget = framebufferObject->getRenderTarget();
@@ -2458,6 +2463,7 @@
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ renderTarget->Release();
return error(GL_OUT_OF_MEMORY);
}
}
@@ -2745,6 +2751,7 @@
D3DSURFACE_DESC desc;
depthStencil->GetDesc(&desc);
+ depthStencil->Release();
unsigned int stencilSize = dx2es::GetStencilSize(desc.Format);
stencilUnmasked = (0x1 << stencilSize) - 1;
@@ -4055,7 +4062,13 @@
if (blitDepthStencil)
{
- HRESULT result = mDevice->StretchRect(readFramebuffer->getDepthStencil(), NULL, drawFramebuffer->getDepthStencil(), NULL, D3DTEXF_NONE);
+ IDirect3DSurface9* readDepthStencil = readFramebuffer->getDepthStencil();
+ IDirect3DSurface9* drawDepthStencil = drawFramebuffer->getDepthStencil();
+
+ HRESULT result = mDevice->StretchRect(readDepthStencil, NULL, drawDepthStencil, NULL, D3DTEXF_NONE);
+
+ readDepthStencil->Release();
+ drawDepthStencil->Release();
if (FAILED(result))
{
diff --git a/src/libGLESv2/Framebuffer.cpp b/src/libGLESv2/Framebuffer.cpp
index 0f3969b..1277c06 100644
--- a/src/libGLESv2/Framebuffer.cpp
+++ b/src/libGLESv2/Framebuffer.cpp
@@ -128,6 +128,8 @@
return 0;
}
+// Increments refcount on surface.
+// caller must Release() the returned surface
IDirect3DSurface9 *Framebuffer::getRenderTarget()
{
Renderbuffer *colorbuffer = mColorbufferPointer.get();
@@ -140,6 +142,8 @@
return NULL;
}
+// Increments refcount on surface.
+// caller must Release() the returned surface
IDirect3DSurface9 *Framebuffer::getDepthStencil()
{
Renderbuffer *depthstencilbuffer = mDepthbufferPointer.get();
diff --git a/src/libGLESv2/Renderbuffer.cpp b/src/libGLESv2/Renderbuffer.cpp
index f251b55..f5abd9d 100644
--- a/src/libGLESv2/Renderbuffer.cpp
+++ b/src/libGLESv2/Renderbuffer.cpp
@@ -87,11 +87,15 @@
mTexture2D->releaseProxy(proxy);
}
+// Increments refcount on surface.
+// caller must Release() the returned surface
IDirect3DSurface9 *RenderbufferTexture2D::getRenderTarget()
{
return mTexture2D->getRenderTarget(mTarget);
}
+// Increments refcount on surface.
+// caller must Release() the returned surface
IDirect3DSurface9 *RenderbufferTexture2D::getDepthStencil()
{
return NULL;
@@ -151,11 +155,15 @@
mTextureCubeMap->releaseProxy(proxy);
}
+// Increments refcount on surface.
+// caller must Release() the returned surface
IDirect3DSurface9 *RenderbufferTextureCubeMap::getRenderTarget()
{
return mTextureCubeMap->getRenderTarget(mTarget);
}
+// Increments refcount on surface.
+// caller must Release() the returned surface
IDirect3DSurface9 *RenderbufferTextureCubeMap::getDepthStencil()
{
return NULL;
@@ -220,11 +228,15 @@
RefCountObject::release();
}
+// Increments refcount on surface.
+// caller must Release() the returned surface
IDirect3DSurface9 *Renderbuffer::getRenderTarget()
{
return mInstance->getRenderTarget();
}
+// Increments refcount on surface.
+// caller must Release() the returned surface
IDirect3DSurface9 *Renderbuffer::getDepthStencil()
{
return mInstance->getDepthStencil();
@@ -311,11 +323,15 @@
{
}
+// Increments refcount on surface.
+// caller must Release() the returned surface
IDirect3DSurface9 *RenderbufferStorage::getRenderTarget()
{
return NULL;
}
+// Increments refcount on surface.
+// caller must Release() the returned surface
IDirect3DSurface9 *RenderbufferStorage::getDepthStencil()
{
return NULL;
@@ -424,6 +440,8 @@
}
}
+// Increments refcount on surface.
+// caller must Release() the returned surface
IDirect3DSurface9 *Colorbuffer::getRenderTarget()
{
if (mRenderTarget)
@@ -496,8 +514,15 @@
}
}
+// Increments refcount on surface.
+// caller must Release() the returned surface
IDirect3DSurface9 *DepthStencilbuffer::getDepthStencil()
{
+ if (mDepthStencil)
+ {
+ mDepthStencil->AddRef();
+ }
+
return mDepthStencil;
}
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index 267b696..683ccc5 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -1725,6 +1725,8 @@
}
}
+// Increments refcount on surface.
+// caller must Release() the returned surface
IDirect3DSurface9 *TextureStorage2D::getSurfaceLevel(int level)
{
IDirect3DSurface9 *surface = NULL;
@@ -2269,8 +2271,8 @@
if (!copyToRenderTarget(dest, source, mTexStorage->isManaged()))
{
delete newTexStorage;
- source->Release();
- dest->Release();
+ if (source) source->Release();
+ if (dest) dest->Release();
return error(GL_OUT_OF_MEMORY);
}
@@ -2358,6 +2360,8 @@
return mColorbufferProxy;
}
+// Increments refcount on surface.
+// caller must Release() the returned surface
IDirect3DSurface9 *Texture2D::getRenderTarget(GLenum target)
{
ASSERT(target == GL_TEXTURE_2D);
@@ -2417,6 +2421,8 @@
}
}
+// Increments refcount on surface.
+// caller must Release() the returned surface
IDirect3DSurface9 *TextureStorageCubeMap::getCubeMapSurface(GLenum faceTarget, int level)
{
IDirect3DSurface9 *surface = NULL;
@@ -2802,8 +2808,8 @@
if (!copyToRenderTarget(dest, source, mTexStorage->isManaged()))
{
delete newTexStorage;
- source->Release();
- dest->Release();
+ if (source) source->Release();
+ if (dest) dest->Release();
return error(GL_OUT_OF_MEMORY);
}
@@ -3098,6 +3104,8 @@
return mFaceProxies[face];
}
+// Increments refcount on surface.
+// caller must Release() the returned surface
IDirect3DSurface9 *TextureCubeMap::getRenderTarget(GLenum target)
{
ASSERT(IsCubemapTextureTarget(target));