From 2a47c14e2a6f152496b43104bc785c488583fd59 Mon Sep 17 00:00:00 2001
From: Chet Haase <chet@google.com>
Date: Wed, 14 Dec 2011 15:22:56 -0800
Subject: Fix issues from recent glyph caching change

There were 2 issues remaining after a recent change to support
glyph caching from multiple textures:
- memory in the GPU for all textures was being allocated automatically.
This is now lazy, being allocated only when those textures are first
needed.
- filtering (applied when a rendered object is transformed) was ignoring
the new multiple-texture structure. Filtering should be applied correctly
whenever we change textures.

Change-Id: I5c8eb8d46c73cd01782a353fc79b11cacc2146ab
---
 libs/hwui/FontRenderer.cpp | 50 ++++++++++++++++++++++++++++------------------
 libs/hwui/FontRenderer.h   | 10 ++++++----
 2 files changed, 37 insertions(+), 23 deletions(-)

(limited to 'libs')

diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 3c6a952..34245b0 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -348,6 +348,8 @@ FontRenderer::FontRenderer() {
     mCacheTexture256 = NULL;
     mCacheTexture512 = NULL;
 
+    mLinearFiltering = false;
+
     mIndexBufferID = 0;
 
     mSmallCacheWidth = DEFAULT_TEXT_CACHE_WIDTH;
@@ -412,11 +414,23 @@ void FontRenderer::flushAllAndInvalidate() {
     }
 }
 
-uint8_t* FontRenderer::allocateTextureMemory(int width, int height) {
-    uint8_t* textureMemory = new uint8_t[width * height];
-    memset(textureMemory, 0, width * height * sizeof(uint8_t));
+void FontRenderer::allocateTextureMemory(CacheTexture *cacheTexture) {
+    int width = cacheTexture->mWidth;
+    int height = cacheTexture->mHeight;
+    cacheTexture->mTexture = new uint8_t[width * height];
+    memset(cacheTexture->mTexture, 0, width * height * sizeof(uint8_t));
+    glBindTexture(GL_TEXTURE_2D, cacheTexture->mTextureId);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    // Initialize texture dimensions
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0,
+            GL_ALPHA, GL_UNSIGNED_BYTE, 0);
+
+    const GLenum filtering = cacheTexture->mLinearFiltering ? GL_LINEAR : GL_NEAREST;
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
 
-    return textureMemory;
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 }
 
 void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph,
@@ -475,7 +489,7 @@ void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyp
     CacheTexture *cacheTexture = cacheLine->mCacheTexture;
     if (cacheTexture->mTexture == NULL) {
         // Large-glyph texture memory is allocated only as needed
-        cacheTexture->mTexture = allocateTextureMemory(cacheTexture->mWidth, cacheTexture->mHeight);
+        allocateTextureMemory(cacheTexture);
     }
     uint8_t* cacheBuffer = cacheTexture->mTexture;
     uint8_t* bitmapBuffer = (uint8_t*) glyph.fImage;
@@ -492,23 +506,15 @@ void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyp
 }
 
 CacheTexture* FontRenderer::createCacheTexture(int width, int height, bool allocate) {
-    uint8_t* textureMemory = allocate ? allocateTextureMemory(width, height) : NULL;
     GLuint textureId;
     glGenTextures(1, &textureId);
-    glBindTexture(GL_TEXTURE_2D, textureId);
-    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-    // Initialize texture dimensions
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0,
-            GL_ALPHA, GL_UNSIGNED_BYTE, 0);
-
-    mLinearFiltering = false;
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    uint8_t* textureMemory = NULL;
 
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
-    return new CacheTexture(textureMemory, textureId, width, height);
+    CacheTexture* cacheTexture = new CacheTexture(textureMemory, textureId, width, height);
+    if (allocate) {
+        allocateTextureMemory(cacheTexture);
+    }
+    return cacheTexture;
 }
 
 void FontRenderer::initTextTexture() {
@@ -641,6 +647,12 @@ void FontRenderer::checkTextureUpdate() {
     }
 
     glBindTexture(GL_TEXTURE_2D, mCurrentCacheTexture->mTextureId);
+    if (mLinearFiltering != mCurrentCacheTexture->mLinearFiltering) {
+        const GLenum filtering = mLinearFiltering ? GL_LINEAR : GL_NEAREST;
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
+        mCurrentCacheTexture->mLinearFiltering = mLinearFiltering;
+    }
     mLastCacheTexture = mCurrentCacheTexture;
 
     mUploadTexture = false;
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index b34fdfa..9f32747 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -59,7 +59,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) {}
+        mTexture(texture), mTextureId(textureId), mWidth(width), mHeight(height),
+        mLinearFiltering(false) {}
     ~CacheTexture() {
         if (mTexture != NULL) {
             delete[] mTexture;
@@ -73,6 +74,7 @@ public:
     GLuint mTextureId;
     uint16_t mWidth;
     uint16_t mHeight;
+    bool mLinearFiltering;
 };
 
 class CacheTextureLine {
@@ -249,7 +251,8 @@ public:
 
     GLuint getTexture(bool linearFiltering = false) {
         checkInit();
-        if (linearFiltering != mLinearFiltering) {
+        if (linearFiltering != mCurrentCacheTexture->mLinearFiltering) {
+            mCurrentCacheTexture->mLinearFiltering = linearFiltering;
             mLinearFiltering = linearFiltering;
             const GLenum filtering = linearFiltering ? GL_LINEAR : GL_NEAREST;
 
@@ -282,7 +285,7 @@ protected:
 
     const uint8_t* mGammaTable;
 
-    uint8_t* allocateTextureMemory(int width, int height);
+    void allocateTextureMemory(CacheTexture* cacheTexture);
     void initTextTexture();
     CacheTexture *createCacheTexture(int width, int height, bool allocate);
     void cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph,
@@ -318,7 +321,6 @@ protected:
     CacheTexture* mCacheTexture256;
     CacheTexture* mCacheTexture512;
 
-
     void checkTextureUpdate();
     bool mUploadTexture;
 
-- 
cgit v1.1