Cleanup 9patch mesh matching code
Bug #7970966
The bug described in #7970966 should normally never happen but just in
case, change the detection code to be more robust.
Change-Id: I7040a6087590e34abe8803cb8f83f051d77f3944
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp
index 902c82f..e490151 100644
--- a/libs/hwui/Patch.cpp
+++ b/libs/hwui/Patch.cpp
@@ -37,7 +37,7 @@
// 2 triangles per patch, 3 vertices per triangle
uint32_t maxVertices = ((xCount + 1) * (yCount + 1) - emptyQuads) * 2 * 3;
mVertices = new TextureVertex[maxVertices];
- mUploaded = false;
+ mAllocatedVerticesCount = 0;
verticesCount = 0;
hasEmptyQuads = emptyQuads > 0;
@@ -68,38 +68,37 @@
memcpy(mYDivs, yDivs, mYCount * sizeof(int32_t));
}
-void Patch::copy(const int32_t* yDivs) {
- memcpy(mYDivs, yDivs, mYCount * sizeof(int32_t));
-}
-
void Patch::updateColorKey(const uint32_t colorKey) {
mColorKey = colorKey;
}
-bool Patch::matches(const int32_t* xDivs, const int32_t* yDivs, const uint32_t colorKey) {
+bool Patch::matches(const int32_t* xDivs, const int32_t* yDivs,
+ const uint32_t colorKey, const int8_t emptyQuads) {
+
+ bool matches = true;
+
+ if (mEmptyQuads != emptyQuads) {
+ mEmptyQuads = emptyQuads;
+ hasEmptyQuads = emptyQuads > 0;
+ matches = false;
+ }
+
if (mColorKey != colorKey) {
updateColorKey(colorKey);
- copy(xDivs, yDivs);
- return false;
+ matches = false;
}
- for (uint32_t i = 0; i < mXCount; i++) {
- if (mXDivs[i] != xDivs[i]) {
- // The Y divs may or may not match, copy everything
- copy(xDivs, yDivs);
- return false;
- }
+ if (memcmp(mXDivs, xDivs, mXCount * sizeof(int32_t))) {
+ memcpy(mXDivs, xDivs, mXCount * sizeof(int32_t));
+ matches = false;
}
- for (uint32_t i = 0; i < mYCount; i++) {
- if (mYDivs[i] != yDivs[i]) {
- // We know all the X divs match, copy only Y divs
- copy(yDivs);
- return false;
- }
+ if (memcmp(mYDivs, yDivs, mYCount * sizeof(int32_t))) {
+ memcpy(mYDivs, yDivs, mYCount * sizeof(int32_t));
+ matches = false;
}
- return true;
+ return matches;
}
///////////////////////////////////////////////////////////////////////////////
@@ -203,10 +202,10 @@
if (verticesCount > 0) {
Caches& caches = Caches::getInstance();
caches.bindMeshBuffer(meshBuffer);
- if (!mUploaded) {
+ if (mAllocatedVerticesCount < verticesCount) {
glBufferData(GL_ARRAY_BUFFER, sizeof(TextureVertex) * verticesCount,
mVertices, GL_DYNAMIC_DRAW);
- mUploaded = true;
+ mAllocatedVerticesCount = verticesCount;
} else {
glBufferSubData(GL_ARRAY_BUFFER, 0,
sizeof(TextureVertex) * verticesCount, mVertices);
diff --git a/libs/hwui/Patch.h b/libs/hwui/Patch.h
index 0518d91..cab0e54 100644
--- a/libs/hwui/Patch.h
+++ b/libs/hwui/Patch.h
@@ -45,7 +45,7 @@
* indices to render the vertices.
*/
struct Patch {
- Patch(const uint32_t xCount, const uint32_t yCount, const int8_t emptyQuads = 0);
+ Patch(const uint32_t xCount, const uint32_t yCount, const int8_t emptyQuads);
~Patch();
void updateVertices(const float bitmapWidth, const float bitmapHeight,
@@ -53,7 +53,8 @@
void updateColorKey(const uint32_t colorKey);
void copy(const int32_t* xDivs, const int32_t* yDivs);
- bool matches(const int32_t* xDivs, const int32_t* yDivs, const uint32_t colorKey);
+ bool matches(const int32_t* xDivs, const int32_t* yDivs,
+ const uint32_t colorKey, const int8_t emptyQuads);
GLuint meshBuffer;
uint32_t verticesCount;
@@ -62,7 +63,7 @@
private:
TextureVertex* mVertices;
- bool mUploaded;
+ uint32_t mAllocatedVerticesCount;
int32_t* mXDivs;
int32_t* mYDivs;
@@ -72,8 +73,6 @@
uint32_t mYCount;
int8_t mEmptyQuads;
- void copy(const int32_t* yDivs);
-
void generateRow(TextureVertex*& vertex, float y1, float y2,
float v1, float v2, float stretchX, float rescaleX,
float width, float bitmapWidth, uint32_t& quadCount);
diff --git a/libs/hwui/PatchCache.cpp b/libs/hwui/PatchCache.cpp
index 9702c3d..8ee8f5c 100644
--- a/libs/hwui/PatchCache.cpp
+++ b/libs/hwui/PatchCache.cpp
@@ -97,7 +97,7 @@
}
mCache.add(description, mesh);
- } else if (!mesh->matches(xDivs, yDivs, colorKey)) {
+ } else if (!mesh->matches(xDivs, yDivs, colorKey, transparentQuads)) {
PATCH_LOGD("Patch mesh does not match, refreshing vertices");
mesh->updateVertices(bitmapWidth, bitmapHeight, 0.0f, 0.0f, pixelWidth, pixelHeight);
}
diff --git a/tests/HwAccelerationTest/res/drawable/patch.9.png b/tests/HwAccelerationTest/res/drawable/patch.9.png
deleted file mode 100644
index e3b3639..0000000
--- a/tests/HwAccelerationTest/res/drawable/patch.9.png
+++ /dev/null
Binary files differ