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

Commit 448455fe authored by Romain Guy's avatar Romain Guy
Browse files

Use global indices array to draw layers

An array of indices local to a layer would only be necessary if
we changed the way we resolve T-junctions. Since we only ever
draw quads, let's just use the indices we use everywhere else.

This change also uses the global indices array to render list
of colored rectangles to save on the number of vertices generated
CPU-side.

Change-Id: Ia6d1970b0e9247805af5a114ca2a84b5d0b7c282
parent e4d4e20e
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@ namespace uirenderer {
Layer::Layer(const uint32_t layerWidth, const uint32_t layerHeight):
        caches(Caches::getInstance()), texture(caches) {
    mesh = NULL;
    meshIndices = NULL;
    meshElementCount = 0;
    cacheable = true;
    dirty = false;
@@ -57,7 +56,6 @@ Layer::~Layer() {
    deleteTexture();

    delete[] mesh;
    delete[] meshIndices;
    delete deferredList;
}

+0 −1
Original line number Diff line number Diff line
@@ -277,7 +277,6 @@ struct Layer {
     * If the layer can be rendered as a mesh, this is non-null.
     */
    TextureVertex* mesh;
    uint16_t* meshIndices;
    GLsizei meshElementCount;

    /**
+0 −21
Original line number Diff line number Diff line
@@ -130,10 +130,7 @@ void LayerRenderer::generateMesh() {
    if (mLayer->region.isRect() || mLayer->region.isEmpty()) {
        if (mLayer->mesh) {
            delete[] mLayer->mesh;
            delete[] mLayer->meshIndices;

            mLayer->mesh = NULL;
            mLayer->meshIndices = NULL;
            mLayer->meshElementCount = 0;
        }

@@ -154,17 +151,11 @@ void LayerRenderer::generateMesh() {

    if (mLayer->mesh && mLayer->meshElementCount < elementCount) {
        delete[] mLayer->mesh;
        delete[] mLayer->meshIndices;

        mLayer->mesh = NULL;
        mLayer->meshIndices = NULL;
    }

    bool rebuildIndices = false;
    if (!mLayer->mesh) {
        mLayer->mesh = new TextureVertex[count * 4];
        mLayer->meshIndices = new uint16_t[elementCount];
        rebuildIndices = true;
    }
    mLayer->meshElementCount = elementCount;

@@ -173,7 +164,6 @@ void LayerRenderer::generateMesh() {
    const float height = mLayer->layer.getHeight();

    TextureVertex* mesh = mLayer->mesh;
    uint16_t* indices = mLayer->meshIndices;

    for (size_t i = 0; i < count; i++) {
        const android::Rect* r = &rects[i];
@@ -187,17 +177,6 @@ void LayerRenderer::generateMesh() {
        TextureVertex::set(mesh++, r->right, r->top, u2, v1);
        TextureVertex::set(mesh++, r->left, r->bottom, u1, v2);
        TextureVertex::set(mesh++, r->right, r->bottom, u2, v2);

        if (rebuildIndices) {
            uint16_t quad = i * 4;
            int index = i * 6;
            indices[index    ] = quad;       // top-left
            indices[index + 1] = quad + 1;   // top-right
            indices[index + 2] = quad + 2;   // bottom-left
            indices[index + 3] = quad + 2;   // bottom-left
            indices[index + 4] = quad + 1;   // top-right
            indices[index + 5] = quad + 3;   // bottom-right
        }
    }
}

+46 −22
Original line number Diff line number Diff line
@@ -106,6 +106,15 @@ static const Blender gBlendsSwap[] = {
    { SkXfermode::kScreen_Mode,   GL_ONE_MINUS_DST_COLOR, GL_ONE }
};

///////////////////////////////////////////////////////////////////////////////
// Functions
///////////////////////////////////////////////////////////////////////////////

template<typename T>
static inline T min(T a, T b) {
    return a < b ? a : b;
}

///////////////////////////////////////////////////////////////////////////////
// Constructors/destructor
///////////////////////////////////////////////////////////////////////////////
@@ -1284,7 +1293,6 @@ void OpenGLRenderer::drawRegionRects(const Region& region) {

void OpenGLRenderer::drawRegionRects(const SkRegion& region, int color,
        SkXfermode::Mode mode, bool dirty) {
    int count = 0;
    Vector<float> rects;

    SkRegion::Iterator it(region);
@@ -1294,11 +1302,10 @@ void OpenGLRenderer::drawRegionRects(const SkRegion& region, int color,
        rects.push(r.fTop);
        rects.push(r.fRight);
        rects.push(r.fBottom);
        count += 4;
        it.next();
    }

    drawColorRects(rects.array(), count, color, mode, true, dirty, false);
    drawColorRects(rects.array(), rects.size(), color, mode, true, dirty, false);
}

void OpenGLRenderer::dirtyLayer(const float left, const float top,
@@ -1328,6 +1335,21 @@ void OpenGLRenderer::dirtyLayerUnchecked(Rect& bounds, Region* region) {
    }
}

void OpenGLRenderer::drawIndexedQuads(Vertex* mesh, GLsizei quadsCount) {
    GLsizei elementsCount = quadsCount * 6;
    while (elementsCount > 0) {
        GLsizei drawCount = min(elementsCount, (GLsizei) gMaxNumberOfQuads * 6);

        setupDrawIndexedVertices(&mesh[0].position[0]);
        glDrawElements(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, NULL);

        elementsCount -= drawCount;
        // Though there are 4 vertices in a quad, we use 6 indices per
        // quad to draw with GL_TRIANGLES
        mesh += (drawCount / 6) * 4;
    }
}

void OpenGLRenderer::clearLayerRegions() {
    const size_t count = mLayers.size();
    if (count == 0) return;
@@ -1342,17 +1364,15 @@ void OpenGLRenderer::clearLayerRegions() {
        // is likely different so we need to disable clipping here
        bool scissorChanged = mCaches.disableScissor();

        Vertex mesh[count * 6];
        Vertex mesh[count * 4];
        Vertex* vertex = mesh;

        for (uint32_t i = 0; i < count; i++) {
            Rect* bounds = mLayers.itemAt(i);

            Vertex::set(vertex++, bounds->left, bounds->bottom);
            Vertex::set(vertex++, bounds->left, bounds->top);
            Vertex::set(vertex++, bounds->right, bounds->top);
            Vertex::set(vertex++, bounds->left, bounds->bottom);
            Vertex::set(vertex++, bounds->right, bounds->top);
            Vertex::set(vertex++, bounds->right, bounds->bottom);

            delete bounds;
@@ -1368,9 +1388,8 @@ void OpenGLRenderer::clearLayerRegions() {
        setupDrawProgram();
        setupDrawPureColorUniforms();
        setupDrawModelViewTranslate(0.0f, 0.0f, 0.0f, 0.0f, true);
        setupDrawVertices(&mesh[0].position[0]);

        glDrawArrays(GL_TRIANGLES, 0, count * 6);
        drawIndexedQuads(&mesh[0], count);

        if (scissorChanged) mCaches.enableScissor();
    } else {
@@ -1976,10 +1995,10 @@ void OpenGLRenderer::setupDrawMeshIndices(GLvoid* vertices, GLvoid* texCoords, G
    }
}

void OpenGLRenderer::setupDrawVertices(GLvoid* vertices) {
void OpenGLRenderer::setupDrawIndexedVertices(GLvoid* vertices) {
    bool force = mCaches.unbindMeshBuffer();
    mCaches.bindIndicesBuffer();
    mCaches.bindPositionVertexPointer(force, vertices, gVertexStride);
    mCaches.unbindIndicesBuffer();
}

void OpenGLRenderer::finishDrawTexture() {
@@ -3139,11 +3158,22 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) {
                setupDrawModelViewTranslate(x, y,
                        x + layer->layer.getWidth(), y + layer->layer.getHeight());
            }
            setupDrawMesh(&layer->mesh[0].position[0], &layer->mesh[0].texture[0]);

            TextureVertex* mesh = &layer->mesh[0];
            GLsizei elementsCount = layer->meshElementCount;

            while (elementsCount > 0) {
                GLsizei drawCount = min(elementsCount, (GLsizei) gMaxNumberOfQuads * 6);

                setupDrawMeshIndices(&mesh[0].position[0], &mesh[0].texture[0]);
                DRAW_DOUBLE_STENCIL_IF(!layer->hasDrawnSinceUpdate,
                    glDrawElements(GL_TRIANGLES, layer->meshElementCount,
                            GL_UNSIGNED_SHORT, layer->meshIndices));
                        glDrawElements(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, NULL));

                elementsCount -= drawCount;
                // Though there are 4 vertices in a quad, we use 6 indices per
                // quad to draw with GL_TRIANGLES
                mesh += (drawCount / 6) * 4;
            }

            finishDrawTexture();

@@ -3361,8 +3391,7 @@ status_t OpenGLRenderer::drawColorRects(const float* rects, int count, int color
    float right = FLT_MIN;
    float bottom = FLT_MIN;

    int vertexCount = 0;
    Vertex mesh[count * 6];
    Vertex mesh[count];
    Vertex* vertex = mesh;

    for (int index = 0; index < count; index += 4) {
@@ -3371,15 +3400,11 @@ status_t OpenGLRenderer::drawColorRects(const float* rects, int count, int color
        float r = rects[index + 2];
        float b = rects[index + 3];

        Vertex::set(vertex++, l, b);
        Vertex::set(vertex++, l, t);
        Vertex::set(vertex++, r, t);
        Vertex::set(vertex++, l, b);
        Vertex::set(vertex++, r, t);
        Vertex::set(vertex++, r, b);

        vertexCount += 6;

        left = fminf(left, l);
        top = fminf(top, t);
        right = fmaxf(right, r);
@@ -3402,13 +3427,12 @@ status_t OpenGLRenderer::drawColorRects(const float* rects, int count, int color
    setupDrawColorUniforms();
    setupDrawShaderUniforms();
    setupDrawColorFilterUniforms();
    setupDrawVertices((GLvoid*) &mesh[0].position[0]);

    if (dirty && hasLayer()) {
        dirtyLayer(left, top, right, bottom, currentTransform());
    }

    glDrawArrays(GL_TRIANGLES, 0, vertexCount);
    drawIndexedQuads(&mesh[0], count / 4);

    return DrawGlInfo::kStatusDrew;
}
+8 −1
Original line number Diff line number Diff line
@@ -849,6 +849,13 @@ private:
            GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
            bool ignoreTransform, bool ignoreScale = false, bool dirty = true);

    /**
     * Draws the specified list of vertices as quads using indexed GL_TRIANGLES.
     * If the number of vertices to draw exceeds the number of indices we have
     * pre-allocated, this method will generate several glDrawElements() calls.
     */
    void drawIndexedQuads(Vertex* mesh, GLsizei quadsCount);

    /**
     * Draws text underline and strike-through if needed.
     *
@@ -988,7 +995,7 @@ private:
    void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords = NULL, GLuint vbo = 0);
    void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords, GLvoid* colors);
    void setupDrawMeshIndices(GLvoid* vertices, GLvoid* texCoords, GLuint vbo = 0);
    void setupDrawVertices(GLvoid* vertices);
    void setupDrawIndexedVertices(GLvoid* vertices);
    void finishDrawTexture();
    void accountForClear(SkXfermode::Mode mode);