Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7c2bacf6 authored by Romain Guy's avatar Romain Guy Committed by Android (Google) Code Review
Browse files

Merge "Don't render degenerate triangles in 9patches. Bug #3251983"

parents 4b2970c1 a5ef39a2
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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
+3 −4
Original line number Diff line number Diff line
@@ -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);
    }
}

+0 −7
Original line number Diff line number Diff line
@@ -44,13 +44,6 @@
namespace android {
namespace uirenderer {

///////////////////////////////////////////////////////////////////////////////
// Defines
///////////////////////////////////////////////////////////////////////////////

// If turned on, layers drawn inside FBOs are optimized with regions
#define RENDER_LAYERS_AS_REGIONS 0

///////////////////////////////////////////////////////////////////////////////
// Renderer
///////////////////////////////////////////////////////////////////////////////
+45 −20
Original line number Diff line number Diff line
@@ -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,6 +177,7 @@ void Patch::updateVertices(const float bitmapWidth, const float bitmapHeight,
    generateRow(vertex, y1, bottom - top, v1, 1.0f, stretchX, right - left,
            bitmapWidth, quadCount);

    if (verticesCount > 0) {
        Caches::getInstance().bindMeshBuffer(meshBuffer);
        if (!mUploaded) {
            glBufferData(GL_ARRAY_BUFFER, sizeof(TextureVertex) * verticesCount,
@@ -178,6 +189,9 @@ void Patch::updateVertices(const float bitmapWidth, const float bitmapHeight,
        }
    }

    PATCH_LOGD("    patch: new vertices count = %d", verticesCount);
}

void Patch::generateRow(TextureVertex*& vertex, float y1, float y2, float v1, float v2,
        float stretchX, float width, float bitmapWidth, uint32_t& quadCount) {
    float previousStepX = 0.0f;
@@ -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
+7 −3
Original line number Diff line number Diff line
@@ -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,
Loading