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

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

Merge "Fix 9patch rendering."

parents 03df1b5d 6820ac8b
Loading
Loading
Loading
Loading
+9 −12
Original line number Diff line number Diff line
@@ -399,7 +399,7 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) {

    drawTextureMesh(rect.left, rect.top, rect.right, rect.bottom, layer->texture,
            1.0f, layer->mode, layer->blend, &mMeshVertices[0].position[0],
            &mMeshVertices[0].texture[0], NULL, 0, true, true);
            &mMeshVertices[0].texture[0], GL_TRIANGLE_STRIP, gMeshCount, true, true);

    resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f);

@@ -574,13 +574,12 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch,
    Patch* mesh = mCaches.patchCache.get(patch);
    mesh->updateVertices(bitmap, left, top, right, bottom,
            &patch->xDivs[0], &patch->yDivs[0], patch->numXDivs, patch->numYDivs);
    mesh->dump();

    // Specify right and bottom as +1.0f from left/top to prevent scaling since the
    // patch mesh already defines the final size
    drawTextureMesh(left, top, left + 1.0f, top + 1.0f, texture->id, alpha / 255.0f,
            mode, texture->blend, &mesh->vertices[0].position[0],
            &mesh->vertices[0].texture[0], mesh->indices, mesh->indicesCount);
            &mesh->vertices[0].texture[0], GL_TRIANGLES, mesh->verticesCount);
}

void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
@@ -956,19 +955,21 @@ void OpenGLRenderer::drawTextureRect(float left, float top, float right, float b
    SkXfermode::Mode mode;
    getAlphaAndMode(paint, &alpha, &mode);

    drawTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f, mode, texture->blend,
            &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0], NULL);
    drawTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f, mode,
            texture->blend, &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0],
            GL_TRIANGLE_STRIP, gMeshCount);
}

void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom,
        GLuint texture, float alpha, SkXfermode::Mode mode, bool blend) {
    drawTextureMesh(left, top, right, bottom, texture, alpha, mode, blend,
            &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0], NULL);
            &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0],
            GL_TRIANGLE_STRIP, gMeshCount);
}

void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float bottom,
        GLuint texture, float alpha, SkXfermode::Mode mode, bool blend,
        GLvoid* vertices, GLvoid* texCoords, GLvoid* indices, GLsizei elementsCount,
        GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
        bool swapSrcDst, bool ignoreTransform) {
    clearLayerRegions();

@@ -1010,11 +1011,7 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b
        mColorFilter->setupProgram(mCaches.currentProgram);
    }

    if (!indices) {
        glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
    } else {
        glDrawElements(GL_TRIANGLES, elementsCount, GL_UNSIGNED_SHORT, indices);
    }
    glDrawArrays(drawMode, 0, elementsCount);
    glDisableVertexAttribArray(texCoordsSlot);
}

+1 −1
Original line number Diff line number Diff line
@@ -229,7 +229,7 @@ private:
     */
    void drawTextureMesh(float left, float top, float right, float bottom, GLuint texture,
            float alpha, SkXfermode::Mode mode, bool blend,
            GLvoid* vertices, GLvoid* texCoords, GLvoid* indices, GLsizei elementsCount = 0,
            GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
            bool swapSrcDst = false, bool ignoreTransform = false);

    /**
+70 −97
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#define LOG_TAG "OpenGLRenderer"

#include <cstring>
#include <cmath>

#include <utils/Log.h>

@@ -29,38 +30,14 @@ namespace uirenderer {
// Constructors/destructor
///////////////////////////////////////////////////////////////////////////////

Patch::Patch(const uint32_t xCount, const uint32_t yCount):
        xCount(xCount + 2), yCount(yCount + 2) {
    verticesCount = (xCount + 2) * (yCount + 2);
    vertices = new TextureVertex[verticesCount];

Patch::Patch(const uint32_t xCount, const uint32_t yCount) {
    // 2 triangles per patch, 3 vertices per triangle
    indicesCount = (xCount + 1) * (yCount + 1) * 2 * 3;
    indices = new uint16_t[indicesCount];

    const uint32_t xNum = xCount + 1;
    const uint32_t yNum = yCount + 1;

    uint16_t* startIndices = indices;
    uint32_t n = 0;
    for (uint32_t y = 0; y < yNum; y++) {
        for (uint32_t x = 0; x < xNum; x++) {
            *startIndices++ = n;
            *startIndices++ = n + 1;
            *startIndices++ = n + xNum + 2;

            *startIndices++ = n;
            *startIndices++ = n + xNum + 2;
            *startIndices++ = n + xNum + 1;

            n += 1;
        }
        n += 1;
    }
    verticesCount = (xCount + 1) * (yCount + 1) * 2 * 3;
    vertices = new TextureVertex[verticesCount];
    memset(vertices, 0, sizeof(TextureVertex) * verticesCount);
}

Patch::~Patch() {
    delete indices;
    delete vertices;
}

@@ -74,10 +51,8 @@ void Patch::updateVertices(const SkBitmap* bitmap, float left, float top, float
    const uint32_t xStretchCount = (width + 1) >> 1;
    const uint32_t yStretchCount = (height + 1) >> 1;

    float xStretch = 0;
    float yStretch = 0;
    float xStretchTex = 0;
    float yStretchTex = 0;
    float stretchX = 0.0f;
    float stretchY = 0.0;

    const float meshWidth = right - left;

@@ -89,9 +64,10 @@ void Patch::updateVertices(const SkBitmap* bitmap, float left, float top, float
        for (uint32_t i = 1; i < width; i += 2) {
            stretchSize += xDivs[i] - xDivs[i - 1];
        }
        xStretchTex = (stretchSize / bitmapWidth) / xStretchCount;
        const float xStretchTex = stretchSize;
        const float fixed = bitmapWidth - stretchSize;
        xStretch = (right - left - fixed) / xStretchCount;
        const float xStretch = right - left - fixed;
        stretchX = xStretch / xStretchTex;
    }

    if (yStretchCount > 0) {
@@ -99,89 +75,86 @@ void Patch::updateVertices(const SkBitmap* bitmap, float left, float top, float
        for (uint32_t i = 1; i < height; i += 2) {
            stretchSize += yDivs[i] - yDivs[i - 1];
        }
        yStretchTex = (stretchSize / bitmapHeight) / yStretchCount;
        const float yStretchTex = stretchSize;
        const float fixed = bitmapHeight - stretchSize;
        yStretch = (bottom - top - fixed) / yStretchCount;
        const float yStretch = bottom - top - fixed;
        stretchY = yStretch / yStretchTex;
    }

    float vy = 0.0f;
    float ty = 0.0f;
    TextureVertex* vertex = vertices;

    generateVertices(vertex, 0.0f, 0.0f, xDivs, width, xStretch, xStretchTex,
            meshWidth, bitmapWidth);
    vertex += width + 2;
    float previousStepY = 0.0f;

    float y1 = 0.0f;
    float v1 = 0.0f;

    for (uint32_t i = 0; i < height; i++) {
        float stepY = yDivs[i];

    for (uint32_t y = 0; y < height; y++) {
        if (y & 1) {
            vy += yStretch;
            ty += yStretchTex;
        float y2 = 0.0f;
        if (i & 1) {
            const float segment = stepY - previousStepY;
            y2 = y1 + segment * stretchY;
        } else {
            const float step = float(yDivs[y]);
            vy += step;
            ty += step / bitmapHeight;
            y2 = y1 + stepY - previousStepY;
        }
        generateVertices(vertex, vy, ty, xDivs, width, xStretch, xStretchTex,
                meshWidth, bitmapWidth);
        vertex += width + 2;
        float v2 = fmax(0.0f, stepY - 0.5f) / bitmapHeight;

        generateRow(vertex, y1, y2, v1, v2, xDivs, width, stretchX,
                right - left, bitmapWidth);

        y1 = y2;
        v1 = (stepY + 0.5f) / bitmapHeight;

        previousStepY = stepY;
    }

    generateVertices(vertex, bottom - top, 1.0f, xDivs, width, xStretch, xStretchTex,
            meshWidth, bitmapWidth);
    generateRow(vertex, y1, bottom - top, v1, 1.0f, xDivs, width, stretchX,
            right - left, bitmapWidth);
}

inline void Patch::generateVertices(TextureVertex* vertex, float y, float v,
        const int32_t xDivs[], uint32_t xCount, float xStretch, float xStretchTex,
        float width, float widthTex) {
    float vx = 0.0f;
    float tx = 0.0f;
inline void Patch::generateRow(TextureVertex*& vertex, float y1, float y2, float v1, float v2,
        const int32_t xDivs[], uint32_t xCount, float stretchX, float width, float bitmapWidth) {
    float previousStepX = 0.0f;

    TextureVertex::set(vertex, vx, y, tx, v);
    vertex++;
    float x1 = 0.0f;
    float u1 = 0.0f;

    for (uint32_t x = 0; x < xCount; x++) {
        if (x & 1) {
            vx += xStretch;
            tx += xStretchTex;
    // Generate the row quad by quad
    for (uint32_t i = 0; i < xCount; i++) {
        float stepX = xDivs[i];

        float x2 = 0.0f;
        if (i & 1) {
            const float segment = stepX - previousStepX;
            x2 = x1 + segment * stretchX;
        } else {
            const float step = float(xDivs[x]);
            vx += step;
            tx += step / widthTex;
            x2 = x1 + stepX - previousStepX;
        }
        float u2 = fmax(0.0f, stepX - 0.5f) / bitmapWidth;

        generateQuad(vertex, x1, y1, x2, y2, u1, v1, u2, v2);

        x1 = x2;
        u1 = (stepX + 0.5f) / bitmapWidth;

        TextureVertex::set(vertex, vx, y, tx, v);
        vertex++;
        previousStepX = stepX;
    }

    TextureVertex::set(vertex, width, y, 1.0f, v);
    vertex++;
    generateQuad(vertex, x1, y1, width, y2, u1, v1, 1.0f, v2);
}

///////////////////////////////////////////////////////////////////////////////
// Debug tools
///////////////////////////////////////////////////////////////////////////////
inline void Patch::generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, float y2,
            float u1, float v1, float u2, float v2) {
    // Left triangle
    TextureVertex::set(vertex++, x1, y1, u1, v1);
    TextureVertex::set(vertex++, x2, y1, u2, v1);
    TextureVertex::set(vertex++, x1, y2, u1, v2);

void Patch::dump() {
    LOGD("Vertices [");
    for (uint32_t y = 0; y < yCount; y++) {
        char buffer[512];
        buffer[0] = '\0';
        uint32_t offset = 0;
        for (uint32_t x = 0; x < xCount; x++) {
            TextureVertex* v = &vertices[y * xCount + x];
            offset += sprintf(&buffer[offset], " (%.4f,%.4f)-(%.4f,%.4f)",
                    v->position[0], v->position[1], v->texture[0], v->texture[1]);
        }
        LOGD("  [%s ]", buffer);
    }
    LOGD("]\nIndices [ ");
    char buffer[4096];
    buffer[0] = '\0';
    uint32_t offset = 0;
    for (uint32_t i = 0; i < indicesCount; i++) {
        offset += sprintf(&buffer[offset], "%d ", indices[i]);
    }
    LOGD("  %s\n]", buffer);
    // Right triangle
    TextureVertex::set(vertex++, x1, y2, u1, v2);
    TextureVertex::set(vertex++, x2, y1, u2, v1);
    TextureVertex::set(vertex++, x2, y2, u2, v2);
}

}; // namespace uirenderer
+5 −10
Original line number Diff line number Diff line
@@ -62,21 +62,16 @@ struct Patch {
    void updateVertices(const SkBitmap* bitmap, float left, float top, float right, float bottom,
            const int32_t* xDivs,  const int32_t* yDivs,
            const uint32_t width, const uint32_t height);
    void dump();

    uint32_t xCount;
    uint32_t yCount;

    uint16_t* indices;
    uint32_t indicesCount;

    TextureVertex* vertices;
    uint32_t verticesCount;

private:
    static inline void generateVertices(TextureVertex* vertex, float y, float v,
            const int32_t xDivs[], uint32_t xCount, float xStretch, float xStretchTex,
            float width, float widthTex);
    static inline void generateRow(TextureVertex*& vertex, float y1, float y2,
            float v1, float v2, const int32_t xDivs[], uint32_t xCount,
            float stretchX, float width, float bitmapWidth);
    static inline void generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, float y2,
            float u1, float v1, float u2, float v2);
}; // struct Patch

}; // namespace uirenderer
+2.8 KiB
Loading image diff...
Loading