summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorRomain Guy <romainguy@android.com>2010-12-03 16:48:20 -0800
committerRomain Guy <romainguy@android.com>2010-12-03 16:48:20 -0800
commita5ef39a21683189e5906c9f252b997f0508e350d (patch)
treef87616c7a443f8e8d19d40654036653252bf65e4 /libs
parentd8591020ec5940aa9ac738593a460a8df8cd560a (diff)
downloadframeworks_base-a5ef39a21683189e5906c9f252b997f0508e350d.zip
frameworks_base-a5ef39a21683189e5906c9f252b997f0508e350d.tar.gz
frameworks_base-a5ef39a21683189e5906c9f252b997f0508e350d.tar.bz2
Don't render degenerate triangles in 9patches.
Bug #3251983 Change-Id: Ib0b38a7b8111542372f4c4c106b6321c26fe4ad4
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/Debug.h3
-rw-r--r--libs/hwui/OpenGLRenderer.cpp7
-rw-r--r--libs/hwui/OpenGLRenderer.h7
-rw-r--r--libs/hwui/Patch.cpp65
-rw-r--r--libs/hwui/Patch.h10
-rw-r--r--libs/hwui/Properties.h3
6 files changed, 61 insertions, 34 deletions
diff --git a/libs/hwui/Debug.h b/libs/hwui/Debug.h
index feaba25..ddbfa5e 100644
--- a/libs/hwui/Debug.h
+++ b/libs/hwui/Debug.h
@@ -34,6 +34,9 @@
// Turn on to display debug infor about 9patch objects
#define DEBUG_PATCHES 0
+// Turn on to display vertex and tex coords data about 9patch objects
+// This flag requires DEBUG_PATCHES to be turned on
+#define DEBUG_PATCHES_VERTICES 0
// Turn on to display debug info about paths
#define DEBUG_PATHS 0
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 60343e0..f3e5b16 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -936,7 +936,8 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int
const Patch* mesh = mCaches.patchCache.get(bitmap->width(), bitmap->height(),
right - left, bottom - top, xDivs, yDivs, colors, width, height, numColors);
- if (mesh) {
+ if (mesh && mesh->verticesCount > 0) {
+#if RENDER_LAYERS_AS_REGIONS
// Mark the current layer dirty where we are going to draw the patch
if ((mSnapshot->flags & Snapshot::kFlagFboTarget) &&
mSnapshot->region && mesh->hasEmptyQuads) {
@@ -947,14 +948,12 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int
*mSnapshot->transform);
}
}
+#endif
drawTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f,
mode, texture->blend, (GLvoid*) 0, (GLvoid*) gMeshTextureOffset,
GL_TRIANGLES, mesh->verticesCount, false, false, mesh->meshBuffer,
true, !mesh->hasEmptyQuads);
- } else {
- PATCH_LOGD("Invisible 9patch, ignoring (%.2f, %.2f, %.2f, %.2f)",
- left, top, right, bottom);
}
}
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 94d96a5..a942dde 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -45,13 +45,6 @@ namespace android {
namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
-// Defines
-///////////////////////////////////////////////////////////////////////////////
-
-// If turned on, layers drawn inside FBOs are optimized with regions
-#define RENDER_LAYERS_AS_REGIONS 0
-
-///////////////////////////////////////////////////////////////////////////////
// Renderer
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp
index ebffd34..17b1d86 100644
--- a/libs/hwui/Patch.cpp
+++ b/libs/hwui/Patch.cpp
@@ -22,6 +22,7 @@
#include "Patch.h"
#include "Caches.h"
+#include "Properties.h"
namespace android {
namespace uirenderer {
@@ -31,19 +32,22 @@ namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
Patch::Patch(const uint32_t xCount, const uint32_t yCount, const int8_t emptyQuads):
- mXCount(xCount), mYCount(yCount) {
+ mXCount(xCount), mYCount(yCount), mEmptyQuads(emptyQuads) {
+ // Initialized with the maximum number of vertices we will need
// 2 triangles per patch, 3 vertices per triangle
- verticesCount = ((xCount + 1) * (yCount + 1) - emptyQuads) * 2 * 3;
- mVertices = new TextureVertex[verticesCount];
- hasEmptyQuads = emptyQuads > 0;
+ const int maxVertices = ((xCount + 1) * (yCount + 1) - emptyQuads) * 2 * 3;
+ mVertices = new TextureVertex[maxVertices];
mUploaded = false;
+ verticesCount = 0;
+ hasEmptyQuads = emptyQuads > 0;
+
mColorKey = 0;
mXDivs = new int32_t[mXCount];
mYDivs = new int32_t[mYCount];
- PATCH_LOGD(" patch: xCount = %d, yCount = %d, emptyQuads = %d, vertices = %d",
- xCount, yCount, emptyQuads, verticesCount);
+ PATCH_LOGD(" patch: xCount = %d, yCount = %d, emptyQuads = %d, max vertices = %d",
+ xCount, yCount, emptyQuads, maxVertices);
glGenBuffers(1, &meshBuffer);
}
@@ -104,7 +108,13 @@ bool Patch::matches(const int32_t* xDivs, const int32_t* yDivs, const uint32_t c
void Patch::updateVertices(const float bitmapWidth, const float bitmapHeight,
float left, float top, float right, float bottom) {
+#if RENDER_LAYERS_AS_REGIONS
if (hasEmptyQuads) quads.clear();
+#endif
+
+ // Reset the vertices count here, we will count exactly how many
+ // vertices we actually need when generating the quads
+ verticesCount = 0;
const uint32_t xStretchCount = (mXCount + 1) >> 1;
const uint32_t yStretchCount = (mYCount + 1) >> 1;
@@ -167,15 +177,19 @@ void Patch::updateVertices(const float bitmapWidth, const float bitmapHeight,
generateRow(vertex, y1, bottom - top, v1, 1.0f, stretchX, right - left,
bitmapWidth, quadCount);
- Caches::getInstance().bindMeshBuffer(meshBuffer);
- if (!mUploaded) {
- glBufferData(GL_ARRAY_BUFFER, sizeof(TextureVertex) * verticesCount,
- mVertices, GL_DYNAMIC_DRAW);
- mUploaded = true;
- } else {
- glBufferSubData(GL_ARRAY_BUFFER, 0,
- sizeof(TextureVertex) * verticesCount, mVertices);
+ if (verticesCount > 0) {
+ Caches::getInstance().bindMeshBuffer(meshBuffer);
+ if (!mUploaded) {
+ glBufferData(GL_ARRAY_BUFFER, sizeof(TextureVertex) * verticesCount,
+ mVertices, GL_DYNAMIC_DRAW);
+ mUploaded = true;
+ } else {
+ glBufferSubData(GL_ARRAY_BUFFER, 0,
+ sizeof(TextureVertex) * verticesCount, mVertices);
+ }
}
+
+ PATCH_LOGD(" patch: new vertices count = %d", verticesCount);
}
void Patch::generateRow(TextureVertex*& vertex, float y1, float y2, float v1, float v2,
@@ -211,22 +225,24 @@ void Patch::generateRow(TextureVertex*& vertex, float y1, float y2, float v1, fl
void Patch::generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, float y2,
float u1, float v1, float u2, float v2, uint32_t& quadCount) {
- uint32_t oldQuadCount = quadCount;
-
- // Degenerate quads are an artifact of our implementation and should not
- // be taken into account when checking for transparent quads
- if (x2 - x1 > 0.999f && y2 - y1 > 0.999f) {
+ const uint32_t oldQuadCount = quadCount;
+ const bool valid = fabs(x2 - x1) > 0.9999f && fabs(y2 - y1) > 0.9999f;
+ if (valid) {
quadCount++;
}
- if (((mColorKey >> oldQuadCount) & 0x1) == 1) {
+ // Skip degenerate and transparent (empty) quads
+ if (!valid || ((mColorKey >> oldQuadCount) & 0x1) == 1) {
return;
}
+#if RENDER_LAYERS_AS_REGIONS
+ // Record all non empty quads
if (hasEmptyQuads) {
Rect bounds(x1, y1, x2, y2);
quads.add(bounds);
}
+#endif
// Left triangle
TextureVertex::set(vertex++, x1, y1, u1, v1);
@@ -237,6 +253,15 @@ void Patch::generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, f
TextureVertex::set(vertex++, x1, y2, u1, v2);
TextureVertex::set(vertex++, x2, y1, u2, v1);
TextureVertex::set(vertex++, x2, y2, u2, v2);
+
+ // A quad is made of 2 triangles, 6 vertices
+ verticesCount += 6;
+
+#if DEBUG_PATCHES_VERTICES
+ PATCH_LOGD(" quad %d", oldQuadCount);
+ PATCH_LOGD(" left, top = %.2f, %.2f\t\tu1, v1 = %.2f, %.2f", x1, y1, u1, v1);
+ PATCH_LOGD(" right, bottom = %.2f, %.2f\t\tu2, v2 = %.2f, %.2f", x2, y2, u2, v2);
+#endif
}
}; // namespace uirenderer
diff --git a/libs/hwui/Patch.h b/libs/hwui/Patch.h
index 2cb8ecb..16ad86d 100644
--- a/libs/hwui/Patch.h
+++ b/libs/hwui/Patch.h
@@ -51,19 +51,23 @@ struct Patch {
GLuint meshBuffer;
uint32_t verticesCount;
- Vector<Rect> quads;
bool hasEmptyQuads;
+#if RENDER_LAYERS_AS_REGIONS
+ Vector<Rect> quads;
+#endif
private:
TextureVertex* mVertices;
bool mUploaded;
- uint32_t mXCount;
int32_t* mXDivs;
- uint32_t mYCount;
int32_t* mYDivs;
uint32_t mColorKey;
+ uint32_t mXCount;
+ uint32_t mYCount;
+ int8_t mEmptyQuads;
+
void copy(const int32_t* yDivs);
void generateRow(TextureVertex*& vertex, float y1, float y2,
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 96d8b69..ac91769 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -25,6 +25,9 @@
* the OpenGLRenderer.
*/
+// If turned on, layers drawn inside FBOs are optimized with regions
+#define RENDER_LAYERS_AS_REGIONS 0
+
/**
* Debug level for app developers.
*/