Create D3D textures within Storage classes. Fixed render target reference counting.
TRAC #18730
Signed-off-by: Daniel Koch
Author: Nicolas Capens
git-svn-id: https://angleproject.googlecode.com/svn/trunk@853 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Renderbuffer.cpp b/src/libGLESv2/Renderbuffer.cpp
index 74d60f2..fc56db1 100644
--- a/src/libGLESv2/Renderbuffer.cpp
+++ b/src/libGLESv2/Renderbuffer.cpp
@@ -305,6 +305,11 @@
IDirect3DSurface9 *Colorbuffer::getRenderTarget()
{
+ if (mRenderTarget)
+ {
+ mRenderTarget->AddRef();
+ }
+
return mRenderTarget;
}
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index c886745..6591e74 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -1519,9 +1519,23 @@
return mCurrentSerial++;
}
-TextureStorage2D::TextureStorage2D(IDirect3DTexture9 *texture, bool renderable) : TextureStorage(renderable)
+TextureStorage2D::TextureStorage2D(IDirect3DTexture9 *surfaceTexture) : TextureStorage(true)
{
- mTexture = texture;
+ mTexture = surfaceTexture;
+}
+
+TextureStorage2D::TextureStorage2D(int levels, D3DFORMAT format, int width, int height, bool renderable) : TextureStorage(renderable)
+{
+ IDirect3DDevice9 *device = getDevice();
+
+ mTexture = NULL;
+ HRESULT result = device->CreateTexture(width, height, levels, renderable ? D3DUSAGE_RENDERTARGET : 0, format, D3DPOOL_DEFAULT, &mTexture, NULL);
+
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ error(GL_OUT_OF_MEMORY);
+ }
}
TextureStorage2D::~TextureStorage2D()
@@ -1647,7 +1661,7 @@
mImageArray[0].redefine(format, surface->getWidth(), surface->getHeight(), GL_UNSIGNED_BYTE);
delete mTexture;
- mTexture = new TextureStorage2D(surface->getOffscreenTexture(), true);
+ mTexture = new TextureStorage2D(surface->getOffscreenTexture());
mSerial = issueSerial();
mColorbufferProxy.set(NULL);
mDirtyImages = true;
@@ -1763,10 +1777,15 @@
IDirect3DSurface9 *dest = mTexture->getSurfaceLevel(level);
- getBlitter()->copy(source->getRenderTarget(), sourceRect, format, 0, destYOffset, dest);
- dest->Release();
+ if (dest)
+ {
+ getBlitter()->copy(renderTarget, sourceRect, format, 0, destYOffset, dest);
+ dest->Release();
+ }
}
}
+
+ renderTarget->Release();
}
void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
@@ -1810,10 +1829,15 @@
IDirect3DSurface9 *dest = mTexture->getSurfaceLevel(level);
- getBlitter()->copy(source->getRenderTarget(), sourceRect, mImageArray[0].getFormat(), xoffset, destYOffset, dest);
- dest->Release();
+ if (dest)
+ {
+ getBlitter()->copy(renderTarget, sourceRect, mImageArray[0].getFormat(), xoffset, destYOffset, dest);
+ dest->Release();
+ }
}
}
+
+ renderTarget->Release();
}
// Tests for GL texture object completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
@@ -1916,21 +1940,14 @@
// Constructs a Direct3D 9 texture resource from the texture images
void Texture2D::createTexture()
{
- IDirect3DDevice9 *device = getDevice();
+ GLsizei width = mImageArray[0].getWidth();
+ GLsizei height = mImageArray[0].getHeight();
+ GLint levels = creationLevels(width, height);
D3DFORMAT format = mImageArray[0].getD3DFormat();
- GLint levels = creationLevels(mImageArray[0].getWidth(), mImageArray[0].getHeight());
-
- IDirect3DTexture9 *texture = NULL;
- HRESULT result = device->CreateTexture(mImageArray[0].getWidth(), mImageArray[0].getHeight(), levels, 0, format, D3DPOOL_DEFAULT, &texture, NULL);
-
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return error(GL_OUT_OF_MEMORY);
- }
delete mTexture;
- mTexture = new TextureStorage2D(texture, false);
+ mTexture = new TextureStorage2D(levels, format, width, height, false);
+
mSerial = issueSerial();
mColorbufferProxy.set(NULL);
mDirtyImages = true;
@@ -1957,46 +1974,43 @@
if (mImageArray[0].getWidth() != 0 && mImageArray[0].getHeight() != 0)
{
- egl::Display *display = getDisplay();
- IDirect3DDevice9 *device = getDevice();
+ GLsizei width = mImageArray[0].getWidth();
+ GLsizei height = mImageArray[0].getHeight();
+ GLint levels = creationLevels(width, height);
D3DFORMAT format = mImageArray[0].getD3DFormat();
- GLint levels = creationLevels(mImageArray[0].getWidth(), mImageArray[0].getHeight());
- IDirect3DTexture9 *texture2D = NULL;
- HRESULT result = device->CreateTexture(mImageArray[0].getWidth(), mImageArray[0].getHeight(), levels, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &texture2D, NULL);
-
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return error(GL_OUT_OF_MEMORY);
- }
-
- newTexture = new TextureStorage2D(texture2D, true);
+ newTexture = new TextureStorage2D(levels, format, width, height, true);
if (mTexture != NULL)
{
+ egl::Display *display = getDisplay();
+ IDirect3DDevice9 *device = display->getDevice();
+
int levels = levelCount();
for (int i = 0; i < levels; i++)
{
IDirect3DSurface9 *source = mTexture->getSurfaceLevel(i);
IDirect3DSurface9 *dest = newTexture->getSurfaceLevel(i);
- display->endScene();
- result = device->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE);
-
- if (FAILED(result))
+ if (source && dest)
{
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ display->endScene();
+ HRESULT result = device->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE);
- delete newTexture;
- source->Release();
- dest->Release();
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return error(GL_OUT_OF_MEMORY);
+ delete newTexture;
+ source->Release();
+ dest->Release();
+
+ return error(GL_OUT_OF_MEMORY);
+ }
}
- source->Release();
- dest->Release();
+ if (source) source->Release();
+ if (dest) dest->Release();
}
}
}
@@ -2096,14 +2110,21 @@
updateTexture();
- IDirect3DSurface9 *renderTarget = mTexture->getSurfaceLevel(0);
-
- return renderTarget;
+ return mTexture->getSurfaceLevel(0);
}
-TextureStorageCubeMap::TextureStorageCubeMap(IDirect3DCubeTexture9 *texture, bool renderable) : TextureStorage(renderable)
+TextureStorageCubeMap::TextureStorageCubeMap(int levels, D3DFORMAT format, int size, bool renderable) : TextureStorage(renderable)
{
- mTexture = texture;
+ IDirect3DDevice9 *device = getDevice();
+
+ mTexture = NULL;
+ HRESULT result = device->CreateCubeTexture(size, levels, renderable ? D3DUSAGE_RENDERTARGET : 0, format, D3DPOOL_DEFAULT, &mTexture, NULL);
+
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ error(GL_OUT_OF_MEMORY);
+ }
}
TextureStorageCubeMap::~TextureStorageCubeMap()
@@ -2359,21 +2380,13 @@
// Constructs a Direct3D 9 texture resource from the texture images, or returns an existing one
void TextureCubeMap::createTexture()
{
- IDirect3DDevice9 *device = getDevice();
+ GLsizei size = mImageArray[0][0].getWidth();
+ GLint levels = creationLevels(size, 0);
D3DFORMAT format = mImageArray[0][0].getD3DFormat();
- GLint levels = creationLevels(mImageArray[0][0].getWidth(), 0);
-
- IDirect3DCubeTexture9 *texture = NULL;
- HRESULT result = device->CreateCubeTexture(mImageArray[0][0].getWidth(), levels, 0, format, D3DPOOL_DEFAULT, &texture, NULL);
-
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return error(GL_OUT_OF_MEMORY);
- }
delete mTexture;
- mTexture = new TextureStorageCubeMap(texture, false);
+ mTexture = new TextureStorageCubeMap(levels, format, size, false);
+
mSerial = issueSerial();
for(int face = 0; face < 6; face++) mFaceProxies[face].set(NULL);
mDirtyImages = true;
@@ -2402,24 +2415,17 @@
if (mImageArray[0][0].getWidth() != 0)
{
- egl::Display *display = getDisplay();
- IDirect3DDevice9 *device = getDevice();
+ GLsizei size = mImageArray[0][0].getWidth();
+ GLint levels = creationLevels(size, 0);
D3DFORMAT format = mImageArray[0][0].getD3DFormat();
- GLint levels = creationLevels(mImageArray[0][0].getWidth(), 0);
- IDirect3DCubeTexture9 *cubeTexture = NULL;
- HRESULT result = device->CreateCubeTexture(mImageArray[0][0].getWidth(), levels, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &cubeTexture, NULL);
-
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return error(GL_OUT_OF_MEMORY);
- }
-
- newTexture = new TextureStorageCubeMap(cubeTexture, true);
+ newTexture = new TextureStorageCubeMap(levels, format, size, true);
if (mTexture != NULL)
{
+ egl::Display *display = getDisplay();
+ IDirect3DDevice9 *device = display->getDevice();
+
int levels = levelCount();
for (int f = 0; f < 6; f++)
{
@@ -2428,22 +2434,25 @@
IDirect3DSurface9 *source = mTexture->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i);
IDirect3DSurface9 *dest = newTexture->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i);
- display->endScene();
- result = device->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE);
-
- if (FAILED(result))
+ if (source && dest)
{
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ display->endScene();
+ HRESULT result = device->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE);
- delete newTexture;
- source->Release();
- dest->Release();
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return error(GL_OUT_OF_MEMORY);
+ delete newTexture;
+ source->Release();
+ dest->Release();
+
+ return error(GL_OUT_OF_MEMORY);
+ }
}
- source->Release();
- dest->Release();
+ if (source) source->Release();
+ if (dest) dest->Release();
}
}
}
@@ -2537,10 +2546,15 @@
IDirect3DSurface9 *dest = mTexture->getCubeMapSurface(target, level);
- getBlitter()->copy(source->getRenderTarget(), sourceRect, format, 0, destYOffset, dest);
- dest->Release();
+ if (dest)
+ {
+ getBlitter()->copy(renderTarget, sourceRect, format, 0, destYOffset, dest);
+ dest->Release();
+ }
}
}
+
+ renderTarget->Release();
}
void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
@@ -2588,10 +2602,15 @@
IDirect3DSurface9 *dest = mTexture->getCubeMapSurface(target, level);
- getBlitter()->copy(source->getRenderTarget(), sourceRect, mImageArray[0][0].getFormat(), xoffset, destYOffset, dest);
- dest->Release();
+ if (dest)
+ {
+ getBlitter()->copy(renderTarget, sourceRect, mImageArray[0][0].getFormat(), xoffset, destYOffset, dest);
+ dest->Release();
+ }
}
}
+
+ renderTarget->Release();
}
bool TextureCubeMap::isCubeComplete() const
diff --git a/src/libGLESv2/Texture.h b/src/libGLESv2/Texture.h
index 6c6677a..a3a1a0b 100644
--- a/src/libGLESv2/Texture.h
+++ b/src/libGLESv2/Texture.h
@@ -232,7 +232,8 @@
class TextureStorage2D : public TextureStorage
{
public:
- TextureStorage2D(IDirect3DTexture9 *texture, bool renderable);
+ explicit TextureStorage2D(IDirect3DTexture9 *surfaceTexture);
+ TextureStorage2D(int levels, D3DFORMAT format, int width, int height, bool renderable);
virtual ~TextureStorage2D();
@@ -299,7 +300,7 @@
class TextureStorageCubeMap : public TextureStorage
{
public:
- TextureStorageCubeMap(IDirect3DCubeTexture9 *texture, bool renderable);
+ TextureStorageCubeMap(int levels, D3DFORMAT format, int size, bool renderable);
virtual ~TextureStorageCubeMap();