summaryrefslogtreecommitdiffstats
path: root/libs/hwui
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2013-06-06 14:02:54 -0700
committerRomain Guy <romainguy@google.com>2013-06-06 16:26:51 -0700
commitbe1b127c7bec252e0c6ab0e06ed6babed07d496f (patch)
treeeaab57886d7cd44e10da155d3dc6188a30b2b17b /libs/hwui
parentf69913056b8c6000ff0306573a97971702e8d35a (diff)
downloadframeworks_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.cpp22
-rw-r--r--libs/hwui/Caches.h13
-rw-r--r--libs/hwui/Dither.cpp2
-rw-r--r--libs/hwui/GradientCache.cpp2
-rw-r--r--libs/hwui/Image.cpp2
-rw-r--r--libs/hwui/Layer.cpp2
-rw-r--r--libs/hwui/LayerRenderer.cpp2
-rw-r--r--libs/hwui/PathCache.cpp2
-rw-r--r--libs/hwui/TextDropShadowCache.cpp2
-rw-r--r--libs/hwui/Texture.cpp4
-rw-r--r--libs/hwui/Texture.h7
-rw-r--r--libs/hwui/TextureCache.cpp2
-rw-r--r--libs/hwui/font/CacheTexture.cpp2
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;