Optimize 9patch rendering.

This change detects empty quads in 9patches and removes them from
the mesh to avoid unnecessary blending.

Change-Id: I4500566fb4cb6845d64dcb59b522c0be7a0ec704
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp
index ca0a0b1..560decf 100644
--- a/libs/hwui/Patch.cpp
+++ b/libs/hwui/Patch.cpp
@@ -18,6 +18,8 @@
 
 #include <cmath>
 
+#include <utils/Log.h>
+
 #include "Patch.h"
 
 namespace android {
@@ -27,9 +29,9 @@
 // Constructors/destructor
 ///////////////////////////////////////////////////////////////////////////////
 
-Patch::Patch(const uint32_t xCount, const uint32_t yCount) {
+Patch::Patch(const uint32_t xCount, const uint32_t yCount, const int8_t emptyQuads) {
     // 2 triangles per patch, 3 vertices per triangle
-    verticesCount = (xCount + 1) * (yCount + 1) * 2 * 3;
+    verticesCount = ((xCount + 1) * (yCount + 1) - emptyQuads) * 2 * 3;
     vertices = new TextureVertex[verticesCount];
 }
 
@@ -43,7 +45,8 @@
 
 void Patch::updateVertices(const float bitmapWidth, const float bitmapHeight,
         float left, float top, float right, float bottom,
-        const int32_t* xDivs, const int32_t* yDivs, const uint32_t width, const uint32_t height) {
+        const int32_t* xDivs, const int32_t* yDivs,
+        const uint32_t width, const uint32_t height, const uint32_t colorKey) {
     const uint32_t xStretchCount = (width + 1) >> 1;
     const uint32_t yStretchCount = (height + 1) >> 1;
 
@@ -75,6 +78,7 @@
     }
 
     TextureVertex* vertex = vertices;
+    uint32_t quadCount = 0;
 
     float previousStepY = 0.0f;
 
@@ -94,7 +98,7 @@
         float v2 = fmax(0.0f, stepY - 0.5f) / bitmapHeight;
 
         generateRow(vertex, y1, y2, v1, v2, xDivs, width, stretchX,
-                right - left, bitmapWidth);
+                right - left, bitmapWidth, quadCount, colorKey);
 
         y1 = y2;
         v1 = (stepY + 0.5f) / bitmapHeight;
@@ -103,11 +107,12 @@
     }
 
     generateRow(vertex, y1, bottom - top, v1, 1.0f, xDivs, width, stretchX,
-            right - left, bitmapWidth);
+            right - left, bitmapWidth, quadCount, colorKey);
 }
 
 inline void Patch::generateRow(TextureVertex*& vertex, float y1, float y2, float v1, float v2,
-        const int32_t xDivs[], uint32_t xCount, float stretchX, float width, float bitmapWidth) {
+        const int32_t xDivs[], uint32_t xCount, float stretchX, float width, float bitmapWidth,
+        uint32_t& quadCount, const uint32_t colorKey) {
     float previousStepX = 0.0f;
 
     float x1 = 0.0f;
@@ -126,7 +131,7 @@
         }
         float u2 = fmax(0.0f, stepX - 0.5f) / bitmapWidth;
 
-        generateQuad(vertex, x1, y1, x2, y2, u1, v1, u2, v2);
+        generateQuad(vertex, x1, y1, x2, y2, u1, v1, u2, v2, quadCount, colorKey);
 
         x1 = x2;
         u1 = (stepX + 0.5f) / bitmapWidth;
@@ -134,11 +139,15 @@
         previousStepX = stepX;
     }
 
-    generateQuad(vertex, x1, y1, width, y2, u1, v1, 1.0f, v2);
+    generateQuad(vertex, x1, y1, width, y2, u1, v1, 1.0f, v2, quadCount, colorKey);
 }
 
 inline void Patch::generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, float y2,
-            float u1, float v1, float u2, float v2) {
+            float u1, float v1, float u2, float v2, uint32_t& quadCount, const uint32_t colorKey) {
+    if (((colorKey >> quadCount++) & 0x1) == 1) {
+        return;
+    }
+
     // Left triangle
     TextureVertex::set(vertex++, x1, y1, u1, v1);
     TextureVertex::set(vertex++, x2, y1, u2, v1);