diff options
author | Romain Guy <romainguy@google.com> | 2013-06-06 14:02:54 -0700 |
---|---|---|
committer | Romain Guy <romainguy@google.com> | 2013-06-06 16:26:51 -0700 |
commit | be1b127c7bec252e0c6ab0e06ed6babed07d496f (patch) | |
tree | eaab57886d7cd44e10da155d3dc6188a30b2b17b /libs/hwui | |
parent | f69913056b8c6000ff0306573a97971702e8d35a (diff) | |
download | frameworks_base-be1b127c7bec252e0c6ab0e06ed6babed07d496f.zip frameworks_base-be1b127c7bec252e0c6ab0e06ed6babed07d496f.tar.gz frameworks_base-be1b127c7bec252e0c6ab0e06ed6babed07d496f.tar.bz2 |
Assume a texture is unbound after deleting it
Bug #9316260
The GL specification indicates that deleting a bound texture has
the side effect of binding the default texture (name=0). This change
replaces all calls to glDeleteTextures() by Caches::deleteTexture()
to properly keep track of texture bindings.
Change-Id: Ifbc60ef433e0f9776a668dd5bd5f0adbc65a77a0
Diffstat (limited to 'libs/hwui')
-rw-r--r-- | libs/hwui/Caches.cpp | 22 | ||||
-rw-r--r-- | libs/hwui/Caches.h | 13 | ||||
-rw-r--r-- | libs/hwui/Dither.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/GradientCache.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/Image.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/Layer.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/LayerRenderer.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/PathCache.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/TextDropShadowCache.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/Texture.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/Texture.h | 7 | ||||
-rw-r--r-- | libs/hwui/TextureCache.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/font/CacheTexture.cpp | 2 |
13 files changed, 53 insertions, 11 deletions
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index 23b5d76..74aeddb 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -508,6 +508,28 @@ void Caches::bindTexture(GLenum target, GLuint texture) { } } +void Caches::deleteTexture(GLuint texture) { + // When glDeleteTextures() is called on a currently bound texture, + // OpenGL ES specifies that the texture is then considered unbound + // Consider the following series of calls: + // + // glGenTextures -> creates texture name 2 + // glBindTexture(2) + // glDeleteTextures(2) -> 2 is now unbound + // glGenTextures -> can return 2 again + // + // If we don't call glBindTexture(2) after the second glGenTextures + // call, any texture operation will be performed on the default + // texture (name=0) + + for (int i = 0; i < REQUIRED_TEXTURE_UNITS_COUNT; i++) { + if (mBoundTextures[i] == texture) { + mBoundTextures[i] = 0; + } + } + glDeleteTextures(1, &texture); +} + void Caches::resetBoundTextures() { memset(mBoundTextures, 0, REQUIRED_TEXTURE_UNITS_COUNT * sizeof(GLuint)); } diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index bd31ec3..bdde8fb 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -226,15 +226,26 @@ public: /** * Binds the specified texture as a GL_TEXTURE_2D texture. + * All texture bindings must be performed with this method or + * bindTexture(GLenum, GLuint). */ void bindTexture(GLuint texture); /** - * Binds the specified texture.. + * Binds the specified texture with the specified render target. + * All texture bindings must be performed with this method or + * bindTexture(GLuint). */ void bindTexture(GLenum target, GLuint texture); /** + * Deletes the specified texture and clears it from the cache + * of bound textures. + * All textures must be deleted using this method. + */ + void deleteTexture(GLuint texture); + + /** * Signals that the cache of bound textures should be cleared. * Other users of the context may have altered which textures are bound. */ diff --git a/libs/hwui/Dither.cpp b/libs/hwui/Dither.cpp index 4dc85e0..649a7bc 100644 --- a/libs/hwui/Dither.cpp +++ b/libs/hwui/Dither.cpp @@ -77,7 +77,7 @@ void Dither::bindDitherTexture() { void Dither::clear() { if (mInitialized) { - glDeleteTextures(1, &mDitherTexture); + mCaches->deleteTexture(mDitherTexture); mInitialized = false; } } diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp index 1ed04fa..1815bff 100644 --- a/libs/hwui/GradientCache.cpp +++ b/libs/hwui/GradientCache.cpp @@ -120,7 +120,7 @@ void GradientCache::operator()(GradientCacheEntry& shader, Texture*& texture) { const uint32_t size = texture->width * texture->height * bytesPerPixel(); mSize -= size; - glDeleteTextures(1, &texture->id); + texture->deleteTexture(); delete texture; } } diff --git a/libs/hwui/Image.cpp b/libs/hwui/Image.cpp index 77c2300..edf3930 100644 --- a/libs/hwui/Image.cpp +++ b/libs/hwui/Image.cpp @@ -54,7 +54,7 @@ Image::~Image() { eglDestroyImageKHR(eglGetDisplay(EGL_DEFAULT_DISPLAY), mImage); mImage = EGL_NO_IMAGE_KHR; - glDeleteTextures(1, &mTexture); + Caches::getInstance().deleteTexture(mTexture); mTexture = 0; } } diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp index 60c38ba..134f452 100644 --- a/libs/hwui/Layer.cpp +++ b/libs/hwui/Layer.cpp @@ -167,7 +167,7 @@ void Layer::generateTexture() { void Layer::deleteTexture() { if (texture.id) { - glDeleteTextures(1, &texture.id); + texture.deleteTexture(); texture.id = 0; } } diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp index 987daae..79e0b0c 100644 --- a/libs/hwui/LayerRenderer.cpp +++ b/libs/hwui/LayerRenderer.cpp @@ -498,7 +498,7 @@ error: glBindFramebuffer(GL_FRAMEBUFFER, previousFbo); layer->setAlpha(alpha, mode); layer->setFbo(previousLayerFbo); - glDeleteTextures(1, &texture); + caches.deleteTexture(texture); caches.fboCache.put(fbo); glViewport(previousViewport[0], previousViewport[1], previousViewport[2], previousViewport[3]); diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp index 3f6485c..3ab40da 100644 --- a/libs/hwui/PathCache.cpp +++ b/libs/hwui/PathCache.cpp @@ -223,7 +223,7 @@ void PathCache::removeTexture(PathTexture* texture) { } if (texture->id) { - glDeleteTextures(1, &texture->id); + Caches::getInstance().deleteTexture(texture->id); } delete texture; } diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp index 3b6cb91..0b2c130 100644 --- a/libs/hwui/TextDropShadowCache.cpp +++ b/libs/hwui/TextDropShadowCache.cpp @@ -155,7 +155,7 @@ void TextDropShadowCache::operator()(ShadowText& text, ShadowTexture*& texture) ALOGD("Shadow texture deleted, size = %d", texture->bitmapSize); } - glDeleteTextures(1, &texture->id); + texture->deleteTexture(); delete texture; } } diff --git a/libs/hwui/Texture.cpp b/libs/hwui/Texture.cpp index e06227c..7923ce7 100644 --- a/libs/hwui/Texture.cpp +++ b/libs/hwui/Texture.cpp @@ -76,5 +76,9 @@ void Texture::setFilterMinMag(GLenum min, GLenum mag, bool bindTexture, bool for } } +void Texture::deleteTexture() const { + mCaches.deleteTexture(id); +} + }; // namespace uirenderer }; // namespace android diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h index d249741..d48ec59 100644 --- a/libs/hwui/Texture.h +++ b/libs/hwui/Texture.h @@ -52,6 +52,11 @@ public: bool force = false, GLenum renderTarget = GL_TEXTURE_2D); /** + * Convenience method to call glDeleteTextures() on this texture's id. + */ + void deleteTexture() const; + + /** * Name of the texture. */ GLuint id; @@ -113,7 +118,7 @@ public: AutoTexture(const Texture* texture): mTexture(texture) { } ~AutoTexture() { if (mTexture && mTexture->cleanup) { - glDeleteTextures(1, &mTexture->id); + mTexture->deleteTexture(); delete mTexture; } } diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp index 7f5b80f..a63cac6 100644 --- a/libs/hwui/TextureCache.cpp +++ b/libs/hwui/TextureCache.cpp @@ -112,7 +112,7 @@ void TextureCache::operator()(SkBitmap*& bitmap, Texture*& texture) { if (mDebugEnabled) { ALOGD("Texture deleted, size = %d", texture->bitmapSize); } - glDeleteTextures(1, &texture->id); + texture->deleteTexture(); delete texture; } } diff --git a/libs/hwui/font/CacheTexture.cpp b/libs/hwui/font/CacheTexture.cpp index 2d58338..5f15724 100644 --- a/libs/hwui/font/CacheTexture.cpp +++ b/libs/hwui/font/CacheTexture.cpp @@ -156,7 +156,7 @@ void CacheTexture::releaseTexture() { mTexture = NULL; } if (mTextureId) { - glDeleteTextures(1, &mTextureId); + mCaches.deleteTexture(mTextureId); mTextureId = 0; } mDirty = false; |