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

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

Merge "Refactoring to move vertex computing to the Patch class."

parents 187c7216 fb5e23c3
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -5,6 +5,7 @@ LOCAL_SRC_FILES:= \
	LayerCache.cpp \
	LayerCache.cpp \
	Matrix.cpp \
	Matrix.cpp \
	OpenGLRenderer.cpp \
	OpenGLRenderer.cpp \
	Patch.cpp \
	PatchCache.cpp \
	PatchCache.cpp \
	Program.cpp \
	Program.cpp \
	TextureCache.cpp
	TextureCache.cpp
+2 −91
Original line number Original line Diff line number Diff line
@@ -463,71 +463,9 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch,
    SkXfermode::Mode mode;
    SkXfermode::Mode mode;
    getAlphaAndMode(paint, &alpha, &mode);
    getAlphaAndMode(paint, &alpha, &mode);


    const uint32_t width = patch->numXDivs;
    const uint32_t height = patch->numYDivs;

    Patch* mesh = mPatchCache.get(patch);
    Patch* mesh = mPatchCache.get(patch);

    mesh->updateVertices(bitmap, left, top, right, bottom,
    const uint32_t xStretchCount = (width + 1) >> 1;
            &patch->xDivs[0], &patch->yDivs[0], patch->numXDivs, patch->numYDivs);
    const uint32_t yStretchCount = (height + 1) >> 1;

    const int32_t* xDivs = &patch->xDivs[0];
    const int32_t* yDivs = &patch->yDivs[0];

    float xStretch = 0;
    float yStretch = 0;
    float xStretchTex = 0;
    float yStretchTex = 0;

    const float meshWidth = right - left;

    const float bitmapWidth = float(bitmap->width());
    const float bitmapHeight = float(bitmap->height());

    if (xStretchCount > 0) {
        uint32_t stretchSize = 0;
        for (uint32_t i = 1; i < width; i += 2) {
            stretchSize += xDivs[i] - xDivs[i - 1];
        }
        xStretchTex = (stretchSize / bitmapWidth) / xStretchCount;
        const float fixed = bitmapWidth - stretchSize;
        xStretch = (right - left - fixed) / xStretchCount;
    }

    if (yStretchCount > 0) {
        uint32_t stretchSize = 0;
        for (uint32_t i = 1; i < height; i += 2) {
            stretchSize += yDivs[i] - yDivs[i - 1];
        }
        yStretchTex = (stretchSize / bitmapHeight) / yStretchCount;
        const float fixed = bitmapHeight - stretchSize;
        yStretch = (bottom - top - fixed) / yStretchCount;
    }

    float vy = 0.0f;
    float ty = 0.0f;
    TextureVertex* vertex = mesh->vertices;

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

    for (uint32_t y = 0; y < height; y++) {
        if (y & 1) {
            vy += yStretch;
            ty += yStretchTex;
        } else {
            const float step = float(yDivs[y]);
            vy += step;
            ty += step / bitmapHeight;
        }
        generateVertices(vertex, vy, ty, xDivs, width, xStretch, xStretchTex,
                meshWidth, bitmapWidth);
        vertex += width + 2;
    }

    generateVertices(vertex, bottom - top, 1.0f, xDivs, width, xStretch, xStretchTex,
            meshWidth, bitmapWidth);


    // Specify right and bottom as +1.0f from left/top to prevent scaling since the
    // Specify right and bottom as +1.0f from left/top to prevent scaling since the
    // patch mesh already defines the final size
    // patch mesh already defines the final size
@@ -536,33 +474,6 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch,
            mesh->indicesCount);
            mesh->indicesCount);
}
}


void OpenGLRenderer::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;

    TextureVertex::set(vertex, vx, y, tx, v);
    vertex++;

    for (uint32_t x = 0; x < xCount; x++) {
        if (x & 1) {
            vx += xStretch;
            tx += xStretchTex;
        } else {
            const float step = float(xDivs[x]);
            vx += step;
            tx += step / widthTex;
        }

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

    TextureVertex::set(vertex, width, y, 1.0f, v);
    vertex++;
}

void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
    const Rect& clip = mSnapshot->clipRect;
    const Rect& clip = mSnapshot->clipRect;
    drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode);
    drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode);
+0 −6
Original line number Original line Diff line number Diff line
@@ -241,12 +241,6 @@ private:
     */
     */
    inline void getAlphaAndMode(const SkPaint* paint, int* alpha, SkXfermode::Mode* mode);
    inline void getAlphaAndMode(const SkPaint* paint, int* alpha, SkXfermode::Mode* mode);


    /**
     * TODO: documentation
     */
    inline void generateVertices(TextureVertex* vertex, float y, float v, const int32_t xDivs[],
            uint32_t xCount, float xStretch, float xStretchTex, float width, float widthTex);

    /**
    /**
     * Enable or disable blending as necessary. This function sets the appropriate
     * Enable or disable blending as necessary. This function sets the appropriate
     * blend function based on the specified xfermode.
     * blend function based on the specified xfermode.

libs/hwui/Patch.cpp

0 → 100644
+188 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "OpenGLRenderer"

#include <cstring>

#include <utils/Log.h>

#include "Patch.h"

namespace android {
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];

    // 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;
    }
}

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

///////////////////////////////////////////////////////////////////////////////
// Vertices management
///////////////////////////////////////////////////////////////////////////////

void Patch::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) {
    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;

    const float meshWidth = right - left;

    const float bitmapWidth = float(bitmap->width());
    const float bitmapHeight = float(bitmap->height());

    if (xStretchCount > 0) {
        uint32_t stretchSize = 0;
        for (uint32_t i = 1; i < width; i += 2) {
            stretchSize += xDivs[i] - xDivs[i - 1];
        }
        xStretchTex = (stretchSize / bitmapWidth) / xStretchCount;
        const float fixed = bitmapWidth - stretchSize;
        xStretch = (right - left - fixed) / xStretchCount;
    }

    if (yStretchCount > 0) {
        uint32_t stretchSize = 0;
        for (uint32_t i = 1; i < height; i += 2) {
            stretchSize += yDivs[i] - yDivs[i - 1];
        }
        yStretchTex = (stretchSize / bitmapHeight) / yStretchCount;
        const float fixed = bitmapHeight - stretchSize;
        yStretch = (bottom - top - fixed) / yStretchCount;
    }

    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;

    for (uint32_t y = 0; y < height; y++) {
        if (y & 1) {
            vy += yStretch;
            ty += yStretchTex;
        } else {
            const float step = float(yDivs[y]);
            vy += step;
            ty += step / bitmapHeight;
        }
        generateVertices(vertex, vy, ty, xDivs, width, xStretch, xStretchTex,
                meshWidth, bitmapWidth);
        vertex += width + 2;
    }

    generateVertices(vertex, bottom - top, 1.0f, xDivs, width, xStretch, xStretchTex,
            meshWidth, 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;

    TextureVertex::set(vertex, vx, y, tx, v);
    vertex++;

    for (uint32_t x = 0; x < xCount; x++) {
        if (x & 1) {
            vx += xStretch;
            tx += xStretchTex;
        } else {
            const float step = float(xDivs[x]);
            vx += step;
            tx += step / widthTex;
        }

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

    TextureVertex::set(vertex, width, y, 1.0f, v);
    vertex++;
}

///////////////////////////////////////////////////////////////////////////////
// Debug tools
///////////////////////////////////////////////////////////////////////////////

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);
}

}; // namespace uirenderer
}; // namespace android
+12 −56
Original line number Original line Diff line number Diff line
@@ -19,7 +19,7 @@


#include <sys/types.h>
#include <sys/types.h>


#include <cstring>
#include <SkBitmap.h>


#include "Vertex.h"
#include "Vertex.h"


@@ -56,62 +56,13 @@ struct PatchDescription {
 * indices to render the vertices.
 * indices to render the vertices.
 */
 */
struct Patch {
struct Patch {
    Patch(const uint32_t xCount, const uint32_t yCount): xCount(xCount + 2), yCount(yCount + 2) {
    Patch(const uint32_t xCount, const uint32_t yCount);
        verticesCount = (xCount + 2) * (yCount + 2);
    ~Patch();
        vertices = new TextureVertex[verticesCount];

        // 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;
        }
    }

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


    void dump() {
    void updateVertices(const SkBitmap* bitmap, float left, float top, float right, float bottom,
        LOGD("Vertices [");
            const int32_t* xDivs,  const int32_t* yDivs,
        for (uint32_t y = 0; y < yCount; y++) {
            const uint32_t width, const uint32_t height);
            char buffer[512];
    void dump();
            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);
    }


    uint32_t xCount;
    uint32_t xCount;
    uint32_t yCount;
    uint32_t yCount;
@@ -121,6 +72,11 @@ struct Patch {


    TextureVertex* vertices;
    TextureVertex* vertices;
    uint32_t verticesCount;
    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);
}; // struct Patch
}; // struct Patch


}; // namespace uirenderer
}; // namespace uirenderer