Apply bilinear filtering on text only when necessary.

Change-Id: Ic903f4b5d30e9c92528c6291941896efe4729ee3
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 5485113..8389e56 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -437,8 +437,9 @@
     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, mCacheWidth, mCacheHeight, 0,
             GL_ALPHA, GL_UNSIGNED_BYTE, 0);
 
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    mLinearFiltering = false;
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index 4fb8f8d..f10efad 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -156,8 +156,16 @@
     DropShadow renderDropShadow(SkPaint* paint, const char *text, uint32_t startIndex,
             uint32_t len, int numGlyphs, uint32_t radius);
 
-    GLuint getTexture() {
+    GLuint getTexture(bool linearFiltering = false) {
         checkInit();
+        if (linearFiltering != mLinearFiltering) {
+            mLinearFiltering = linearFiltering;
+            const GLenum filtering = linearFiltering ? GL_LINEAR : GL_NEAREST;
+
+            glBindTexture(GL_TEXTURE_2D, mTextureId);
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
+        }
         return mTextureId;
     }
 
@@ -252,6 +260,8 @@
 
     bool mInitialized;
 
+    bool mLinearFiltering;
+
     void computeGaussianWeights(float* weights, int32_t radius);
     void horizontalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
             int32_t width, int32_t height);
diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp
index c698b5a..219fd5e 100644
--- a/libs/hwui/Matrix.cpp
+++ b/libs/hwui/Matrix.cpp
@@ -53,6 +53,15 @@
     mSimpleMatrix = true;
 }
 
+#define EPSILON 0.00001f
+#define almost(u, v) (fabs((u) - (v)) < EPSILON)
+
+bool Matrix4::changesBounds() {
+    return !(almost(data[0], 1.0f) && almost(data[1], 0.0f) && almost(data[2], 0.0f) &&
+             almost(data[4], 0.0f) && almost(data[5], 1.0f) && almost(data[6], 0.0f) &&
+             almost(data[8], 0.0f) && almost(data[9], 0.0f) && almost(data[10], 1.0f));
+}
+
 void Matrix4::load(const float* v) {
     memcpy(data, v, sizeof(data));
     mSimpleMatrix = false;
diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h
index 0608efe..fe81159 100644
--- a/libs/hwui/Matrix.h
+++ b/libs/hwui/Matrix.h
@@ -103,6 +103,8 @@
         multiply(u);
     }
 
+    bool changesBounds();
+
     void copyTo(float* v) const;
     void copyTo(SkMatrix& v) const;
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 0810fb8..81d36e9 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -767,8 +767,10 @@
     GLuint textureUnit = 0;
     glActiveTexture(gTextureUnits[textureUnit]);
 
-    setupTextureAlpha8(fontRenderer.getTexture(), 0, 0, textureUnit, x, y, r, g, b, a,
-            mode, false, true);
+    // Assume that the modelView matrix does not force scales, rotates, etc.
+    const bool linearFilter = mSnapshot->transform->changesBounds();
+    setupTextureAlpha8(fontRenderer.getTexture(linearFilter), 0, 0, textureUnit,
+            x, y, r, g, b, a, mode, false, true);
 
     const Rect& clip = mSnapshot->getLocalClip();
     clearLayerRegions();