Forget the name of a texture after freeing
Bug #6408362
FontRenderer allocates large font textures when more room is needed
to store all the glyphs used by an application. Thse large textures
are the first to be freed when memory needs to be reclaimed by the
system. When freeing a texture, the renderer would however not set
the texture name to an invalid name, leading future allocations to
be performed on the same texture name. That name could have by then
be recycled by the driver and returned by a call to glGenTexture
and used to create an entirely different texture. This would cause
the font renderer to point to the wrong texture, thus leading to
the "corruptions."
Change-Id: I8a1e80e5b79e8f21d1baf5320c090df4f2066cd4
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index b7d09db..a0bf8e3 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -555,6 +555,7 @@
glDeleteTextures(1, &cacheTexture->mTextureId);
delete[] cacheTexture->mTexture;
cacheTexture->mTexture = NULL;
+ cacheTexture->mTextureId = 0;
}
}
@@ -589,7 +590,13 @@
int height = cacheTexture->mHeight;
cacheTexture->mTexture = new uint8_t[width * height];
+#if DEBUG_FONT_RENDERER
memset(cacheTexture->mTexture, 0, width * height * sizeof(uint8_t));
+#endif
+
+ if (!cacheTexture->mTextureId) {
+ glGenTextures(1, &cacheTexture->mTextureId);
+ }
glBindTexture(GL_TEXTURE_2D, cacheTexture->mTextureId);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@@ -680,11 +687,8 @@
}
CacheTexture* FontRenderer::createCacheTexture(int width, int height, bool allocate) {
- GLuint textureId;
- glGenTextures(1, &textureId);
-
uint8_t* textureMemory = NULL;
- CacheTexture* cacheTexture = new CacheTexture(textureMemory, textureId, width, height);
+ CacheTexture* cacheTexture = new CacheTexture(textureMemory, width, height);
if (allocate) {
allocateTextureMemory(cacheTexture);
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index 4de4af2..2ab680e 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -62,8 +62,8 @@
class CacheTexture {
public:
CacheTexture() { }
- CacheTexture(uint8_t* texture, GLuint textureId, uint16_t width, uint16_t height) :
- mTexture(texture), mTextureId(textureId), mWidth(width), mHeight(height),
+ CacheTexture(uint8_t* texture, uint16_t width, uint16_t height) :
+ mTexture(texture), mTextureId(0), mWidth(width), mHeight(height),
mLinearFiltering(false) { }
~CacheTexture() {
if (mTexture) {