Patch cleanup, reenable Patch Glops

bug:19597454

Change-Id: If12b95e83588b81a553210cd8c2437c6c771073a
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
index f94dc38..711b11c 100644
--- a/libs/hwui/GlopBuilder.cpp
+++ b/libs/hwui/GlopBuilder.cpp
@@ -198,7 +198,7 @@
     mOutGlop->mesh.vertices = {
             mCaches.patchCache.getMeshBuffer(),
             VertexAttribFlags::kTextureCoord,
-            (void*)patch.offset, (void*)patch.textureOffset, nullptr,
+            (void*)patch.positionOffset, (void*)patch.textureOffset, nullptr,
             kTextureVertexStride };
     mOutGlop->mesh.elementCount = patch.indexCount;
     return *this;
@@ -518,6 +518,7 @@
     }
 
     mOutGlop->transform.modelView.loadTranslate(offsetX, offsetY, 0.0f);
+    mOutGlop->bounds = source;
     mOutGlop->bounds.translate(offsetX, offsetY);
     return *this;
 }
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 76a42c0..7fd115f 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -2329,7 +2329,7 @@
     Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap);
     if (!texture) return;
 
-    if (false) {
+    if (USE_GLOPS) {
         // 9 patches are built for stretching - always filter
         int textureFillFlags = static_cast<int>(TextureFillFlags::kForceFilter);
         if (bitmap->colorType() == kAlpha_8_SkColorType) {
@@ -2384,7 +2384,7 @@
         ignoreTransform = true;
     }
     drawIndexedTextureMesh(left, top, right, bottom, texture->id, paint,
-            texture->blend, (GLvoid*) mesh->offset, (GLvoid*) mesh->textureOffset,
+            texture->blend, (GLvoid*) mesh->positionOffset, (GLvoid*) mesh->textureOffset,
             GL_TRIANGLES, mesh->indexCount, false, ignoreTransform,
             mCaches.patchCache.getMeshBuffer(), kModelViewMode_Translate, !mesh->hasEmptyQuads);
 
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp
index ce51e04..f673c6a 100644
--- a/libs/hwui/Patch.cpp
+++ b/libs/hwui/Patch.cpp
@@ -24,6 +24,7 @@
 #include "Patch.h"
 #include "Properties.h"
 #include "UvMapper.h"
+#include "utils/MathUtils.h"
 
 namespace android {
 namespace uirenderer {
@@ -36,19 +37,11 @@
     return verticesCount * sizeof(TextureVertex);
 }
 
-TextureVertex* Patch::createMesh(const float bitmapWidth, const float bitmapHeight,
-        float width, float height, const Res_png_9patch* patch) {
-    UvMapper mapper;
-    return createMesh(bitmapWidth, bitmapHeight, width, height, mapper, patch);
-}
-
-TextureVertex* Patch::createMesh(const float bitmapWidth, const float bitmapHeight,
-        float width, float height, const UvMapper& mapper, const Res_png_9patch* patch) {
-    if (vertices) return vertices.get();
+Patch::Patch(const float bitmapWidth, const float bitmapHeight,
+        float width, float height, const UvMapper& mapper, const Res_png_9patch* patch)
+        : mColors(patch->getColors()) {
 
     int8_t emptyQuads = 0;
-    mColors = patch->getColors();
-
     const int8_t numColors = patch->numColors;
     if (uint8_t(numColors) < sizeof(uint32_t) * 4) {
         for (int8_t i = 0; i < numColors; i++) {
@@ -64,7 +57,7 @@
     uint32_t yCount = patch->numYDivs;
 
     uint32_t maxVertices = ((xCount + 1) * (yCount + 1) - emptyQuads) * 4;
-    if (maxVertices == 0) return nullptr;
+    if (maxVertices == 0) return;
 
     vertices.reset(new TextureVertex[maxVertices]);
     TextureVertex* vertex = vertices.get();
@@ -151,8 +144,6 @@
         memcpy(reducedVertices.get(), vertices.get(), verticesCount * sizeof(TextureVertex));
         vertices = std::move(reducedVertices);
     }
-
-    return vertices.get();
 }
 
 void Patch::generateRow(const int32_t* xDivs, uint32_t xCount, TextureVertex*& vertex,
@@ -200,10 +191,10 @@
     const uint32_t oldQuadCount = quadCount;
     quadCount++;
 
-    if (x1 < 0.0f) x1 = 0.0f;
-    if (x2 < 0.0f) x2 = 0.0f;
-    if (y1 < 0.0f) y1 = 0.0f;
-    if (y2 < 0.0f) y2 = 0.0f;
+    x1 = MathUtils::max(x1, 0.0f);
+    x2 = MathUtils::max(x2, 0.0f);
+    y1 = MathUtils::max(y1, 0.0f);
+    y2 = MathUtils::max(y2, 0.0f);
 
     // Skip degenerate and transparent (empty) quads
     if ((mColors[oldQuadCount] == 0) || x1 >= x2 || y1 >= y2) {
diff --git a/libs/hwui/Patch.h b/libs/hwui/Patch.h
index 9afb41d..b63bd24 100644
--- a/libs/hwui/Patch.h
+++ b/libs/hwui/Patch.h
@@ -39,7 +39,9 @@
 
 class Patch {
 public:
-    Patch() {}
+    Patch(const float bitmapWidth, const float bitmapHeight,
+            float width, float height,
+            const UvMapper& mapper, const Res_png_9patch* patch);
 
     /**
      * Returns the size of this patch's mesh in bytes.
@@ -52,15 +54,9 @@
     bool hasEmptyQuads = false;
     Vector<Rect> quads;
 
-    Rect bounds;
-    GLintptr offset = 0;
+    GLintptr positionOffset = 0;
     GLintptr textureOffset = 0;
 
-    TextureVertex* createMesh(const float bitmapWidth, const float bitmapHeight,
-            float width, float height, const Res_png_9patch* patch);
-    TextureVertex* createMesh(const float bitmapWidth, const float bitmapHeight,
-            float width, float height, const UvMapper& mapper, const Res_png_9patch* patch);
-
 private:
     void generateRow(const int32_t* xDivs, uint32_t xCount, TextureVertex*& vertex,
             float y1, float y2, float v1, float v2, float stretchX, float rescaleX,
@@ -68,7 +64,7 @@
     void generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, float y2,
             float u1, float v1, float u2, float v2, uint32_t& quadCount);
 
-    const uint32_t* mColors = nullptr;
+    const uint32_t* mColors;
     UvMapper mUvMapper;
 }; // struct Patch
 
diff --git a/libs/hwui/PatchCache.cpp b/libs/hwui/PatchCache.cpp
index af403b4..2765262 100644
--- a/libs/hwui/PatchCache.cpp
+++ b/libs/hwui/PatchCache.cpp
@@ -162,7 +162,7 @@
 
         // Release the patch and mark the space in the free list
         Patch* patch = pair.getSecond();
-        BufferBlock* block = new BufferBlock(patch->offset, patch->getSize());
+        BufferBlock* block = new BufferBlock(patch->positionOffset, patch->getSize());
         block->next = mFreeBlocks;
         mFreeBlocks = block;
 
@@ -190,7 +190,7 @@
  * Sets the mesh's offsets and copies its associated vertices into
  * the mesh buffer (VBO).
  */
-void PatchCache::setupMesh(Patch* newMesh, TextureVertex* vertices) {
+void PatchCache::setupMesh(Patch* newMesh) {
     // This call ensures the VBO exists and that it is bound
     init();
 
@@ -223,9 +223,9 @@
     }
 
     // Copy the 9patch mesh in the VBO
-    newMesh->offset = (GLintptr) (block->offset);
-    newMesh->textureOffset = newMesh->offset + kMeshTextureOffset;
-    glBufferSubData(GL_ARRAY_BUFFER, newMesh->offset, size, vertices);
+    newMesh->positionOffset = (GLintptr) (block->offset);
+    newMesh->textureOffset = newMesh->positionOffset + kMeshTextureOffset;
+    glBufferSubData(GL_ARRAY_BUFFER, newMesh->positionOffset, size, newMesh->vertices.get());
 
     // Remove the block since we've used it entirely
     if (block->size == size) {
@@ -244,6 +244,8 @@
     mSize += size;
 }
 
+static const UvMapper sIdentity;
+
 const Patch* PatchCache::get(const AssetAtlas::Entry* entry,
         const uint32_t bitmapWidth, const uint32_t bitmapHeight,
         const float pixelWidth, const float pixelHeight, const Res_png_9patch* patch) {
@@ -252,20 +254,12 @@
     const Patch* mesh = mCache.get(description);
 
     if (!mesh) {
-        Patch* newMesh = new Patch();
-        TextureVertex* vertices;
+        const UvMapper& mapper = entry ? entry->uvMapper : sIdentity;
+        Patch* newMesh = new Patch(bitmapWidth, bitmapHeight,
+                pixelWidth, pixelHeight, mapper, patch);
 
-        if (entry) {
-            // An atlas entry has a UV mapper
-            vertices = newMesh->createMesh(bitmapWidth, bitmapHeight,
-                    pixelWidth, pixelHeight, entry->uvMapper, patch);
-        } else {
-            vertices = newMesh->createMesh(bitmapWidth, bitmapHeight,
-                    pixelWidth, pixelHeight, patch);
-        }
-
-        if (vertices) {
-            setupMesh(newMesh, vertices);
+        if (newMesh->vertices) {
+            setupMesh(newMesh);
         }
 
 #if DEBUG_PATCHES
@@ -284,7 +278,7 @@
     String8 dump;
     BufferBlock* block = mFreeBlocks;
     while (block) {
-        dump.appendFormat("->(%d, %d)", block->offset, block->size);
+        dump.appendFormat("->(%d, %d)", block->positionOffset, block->size);
         block = block->next;
     }
     ALOGD("%s: Free blocks%s", prefix, dump.string());
diff --git a/libs/hwui/PatchCache.h b/libs/hwui/PatchCache.h
index e038720..387f79a 100644
--- a/libs/hwui/PatchCache.h
+++ b/libs/hwui/PatchCache.h
@@ -160,7 +160,7 @@
     void clearCache();
     void createVertexBuffer();
 
-    void setupMesh(Patch* newMesh, TextureVertex* vertices);
+    void setupMesh(Patch* newMesh);
 
     void remove(Vector<patch_pair_t>& patchesToRemove, Res_png_9patch* patch);
 
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index 1716cf0..c82082f 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -252,6 +252,13 @@
         bottom = fmaxf(bottom, y);
     }
 
+    void expandToCoverRect(float otherLeft, float otherTop, float otherRight, float otherBottom) {
+        left = fminf(left, otherLeft);
+        top = fminf(top, otherTop);
+        right = fmaxf(right, otherRight);
+        bottom = fmaxf(bottom, otherBottom);
+    }
+
     SkRect toSkRect() const {
         return SkRect::MakeLTRB(left, top, right, bottom);
     }