Refactor storage management in TextureCube.
TRAC #23976
Signed-off-by: Geoff Lang
Signed-off-by: Shannon Woods
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index 1a56b27..558410c 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -1275,27 +1275,51 @@
return GetDepthBits(getInternalFormat(target, level), mRenderer->getCurrentClientVersion()) > 0;
}
-// Constructs a native texture resource from the texture images, or returns an existing one
void TextureCubeMap::initializeStorage(bool renderTarget)
{
+ // Only initialize the first time this texture is used as a render target or shader resource
+ if (mTexStorage)
+ {
+ return;
+ }
+
+ // do not attempt to create storage for nonexistant data
+ if (!isFaceLevelComplete(0, 0))
+ {
+ return;
+ }
+
+ bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage));
+
+ setCompleteTexStorage(createCompleteStorage(createRenderTarget));
+ ASSERT(mTexStorage);
+
+ // flush image data to the storage
+ updateStorage();
+}
+
+rx::TextureStorageInterfaceCube *TextureCubeMap::createCompleteStorage(bool renderTarget) const
+{
GLsizei size = getBaseLevelWidth();
- if (!(size > 0))
- return; // do not attempt to create native textures for nonexistant data
+ ASSERT(size > 0);
- GLint levels = creationLevels(size);
- GLenum internalformat = getBaseLevelInternalFormat();
+ // use existing storage level count, when previously specified by TexStorage*D
+ GLint levels = (mTexStorage ? mTexStorage->levelCount() : creationLevels(size));
- delete mTexStorage;
- mTexStorage = new rx::TextureStorageInterfaceCube(mRenderer, levels, internalformat, IsRenderTargetUsage(mUsage), size);
+ return new rx::TextureStorageInterfaceCube(mRenderer, levels, getBaseLevelInternalFormat(), renderTarget, size);
+}
- if (mTexStorage->isManaged())
+void TextureCubeMap::setCompleteTexStorage(rx::TextureStorageInterfaceCube *newCompleteTexStorage)
+{
+ SafeDelete(mTexStorage);
+ mTexStorage = newCompleteTexStorage;
+
+ if (mTexStorage && mTexStorage->isManaged())
{
- int levels = levelCount();
-
for (int faceIndex = 0; faceIndex < 6; faceIndex++)
{
- for (int level = 0; level < levels; level++)
+ for (int level = 0; level < mTexStorage->levelCount(); level++)
{
mImageArray[faceIndex][level]->setManagedSurface(mTexStorage, faceIndex, level);
}
@@ -1334,35 +1358,25 @@
bool TextureCubeMap::ensureRenderTarget()
{
- if (mTexStorage && mTexStorage->isRenderTarget())
+ initializeStorage(true);
+
+ if (getBaseLevelWidth() > 0)
{
- return true;
- }
-
- rx::TextureStorageInterfaceCube *newTexStorage = NULL;
-
- if (getBaseLevelWidth() != 0)
- {
- GLsizei size = getBaseLevelWidth();
- GLint levels = mTexStorage != NULL ? mTexStorage->levelCount() : creationLevels(size);
- GLenum internalformat = getBaseLevelInternalFormat();
-
- newTexStorage = new rx::TextureStorageInterfaceCube(mRenderer, levels, internalformat, true, size);
-
- if (mTexStorage != NULL)
+ ASSERT(mTexStorage);
+ if (!mTexStorage->isRenderTarget())
{
- if (!mRenderer->copyToRenderTarget(newTexStorage, mTexStorage))
+ rx::TextureStorageInterfaceCube *newRenderTargetStorage = createCompleteStorage(true);
+
+ if (!mRenderer->copyToRenderTarget(newRenderTargetStorage, mTexStorage))
{
- delete newTexStorage;
+ delete newRenderTargetStorage;
return gl::error(GL_OUT_OF_MEMORY, false);
}
+
+ setCompleteTexStorage(newRenderTargetStorage);
}
}
- delete mTexStorage;
- mTexStorage = newTexStorage;
-
- mDirtyImages = true;
return (mTexStorage && mTexStorage->isRenderTarget());
}
@@ -1500,10 +1514,6 @@
void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size)
{
- delete mTexStorage;
- mTexStorage = new rx::TextureStorageInterfaceCube(mRenderer, levels, internalformat, IsRenderTargetUsage(mUsage), size);
- mImmutable = true;
-
for (int level = 0; level < levels; level++)
{
GLsizei mipSize = std::max(1, size >> level);
@@ -1521,18 +1531,9 @@
}
}
- if (mTexStorage->isManaged())
- {
- int levels = levelCount();
+ mImmutable = true;
- for (int faceIndex = 0; faceIndex < 6; faceIndex++)
- {
- for (int level = 0; level < levels; level++)
- {
- mImageArray[faceIndex][level]->setManagedSurface(mTexStorage, faceIndex, level);
- }
- }
- }
+ setCompleteTexStorage(new rx::TextureStorageInterfaceCube(mRenderer, levels, internalformat, IsRenderTargetUsage(mUsage), size));
}
void TextureCubeMap::generateMipmaps()
diff --git a/src/libGLESv2/Texture.h b/src/libGLESv2/Texture.h
index 24a630f..b5ff6bb 100644
--- a/src/libGLESv2/Texture.h
+++ b/src/libGLESv2/Texture.h
@@ -267,6 +267,9 @@
DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
virtual void initializeStorage(bool renderTarget);
+ rx::TextureStorageInterfaceCube *createCompleteStorage(bool renderTarget) const;
+ void setCompleteTexStorage(rx::TextureStorageInterfaceCube *newCompleteTexStorage);
+
virtual void updateStorage();
virtual bool ensureRenderTarget();
virtual rx::TextureStorageInterface *getStorage(bool renderTarget);