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));