diff options
author | Romain Guy <romainguy@android.com> | 2010-12-03 16:48:20 -0800 |
---|---|---|
committer | Romain Guy <romainguy@android.com> | 2010-12-03 16:48:20 -0800 |
commit | a5ef39a21683189e5906c9f252b997f0508e350d (patch) | |
tree | f87616c7a443f8e8d19d40654036653252bf65e4 /libs | |
parent | d8591020ec5940aa9ac738593a460a8df8cd560a (diff) | |
download | frameworks_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.h | 3 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 7 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.h | 7 | ||||
-rw-r--r-- | libs/hwui/Patch.cpp | 65 | ||||
-rw-r--r-- | libs/hwui/Patch.h | 10 | ||||
-rw-r--r-- | libs/hwui/Properties.h | 3 |
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. */ |