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

Commit 2ab95d78 authored by Chris Craik's avatar Chris Craik
Browse files

Glop support for indexed quads

bug:19014311
Change-Id: If35a873421b41cc4508b0d8ac1b4d900c9bb3717
parent 92b2fe5d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -65,7 +65,7 @@ struct Glop {
     * Stores mesh - vertex and index data.
     *
     * buffer objects and void*s are mutually exclusive
     * indices are optional
     * indices are optional, currently only GL_UNSIGNED_SHORT supported
     */
    struct Mesh {
        VertexAttribFlags vertexFlags;
+44 −6
Original line number Diff line number Diff line
@@ -78,6 +78,21 @@ GlopBuilder& GlopBuilder::setMeshUnitQuad() {
    return *this;
}

GlopBuilder& GlopBuilder::setMeshIndexedQuads(void* vertexData, int quadCount) {
    TRIGGER_STAGE(kMeshStage);

    mOutGlop->mesh.vertexFlags = kNone_Attrib;
    mOutGlop->mesh.primitiveMode = GL_TRIANGLES;
    mOutGlop->mesh.vertexBufferObject = 0;
    mOutGlop->mesh.vertices = vertexData;
    mOutGlop->mesh.indexBufferObject = mRenderState.meshState().getQuadListIBO();
    mOutGlop->mesh.indices = nullptr;
    mOutGlop->mesh.vertexCount = 6 * quadCount;
    mOutGlop->mesh.stride = kVertexStride;

    return *this;
}

GlopBuilder& GlopBuilder::setTransform(const Matrix4& ortho,
        const Matrix4& transform, bool fudgingOffset) {
    TRIGGER_STAGE(kTransformStage);
@@ -90,6 +105,7 @@ GlopBuilder& GlopBuilder::setTransform(const Matrix4& ortho,

GlopBuilder& GlopBuilder::setModelViewMapUnitToRect(const Rect destination) {
    TRIGGER_STAGE(kModelViewStage);

    mOutGlop->transform.modelView.loadTranslate(destination.left, destination.top, 0.0f);
    mOutGlop->transform.modelView.scale(destination.getWidth(), destination.getHeight(), 1.0f);
    mOutGlop->bounds = destination;
@@ -98,22 +114,42 @@ GlopBuilder& GlopBuilder::setModelViewMapUnitToRect(const Rect destination) {

GlopBuilder& GlopBuilder::setModelViewOffsetRect(float offsetX, float offsetY, const Rect source) {
    TRIGGER_STAGE(kModelViewStage);

    mOutGlop->transform.modelView.loadTranslate(offsetX, offsetY, 0.0f);
    mOutGlop->bounds = source;
    mOutGlop->bounds.translate(offsetX, offsetY);
    return *this;
}

GlopBuilder& GlopBuilder::setPaint(const SkPaint* paint, float alphaScale) {
GlopBuilder& GlopBuilder::setOptionalPaint(const SkPaint* paint, float alphaScale) {
    if (paint) {
        return setPaint(*paint, alphaScale);
    }

    TRIGGER_STAGE(kFillStage);

    // TODO: support null paint
    const SkShader* shader = paint->getShader();
    const SkColorFilter* colorFilter = paint->getColorFilter();
    mOutGlop->fill.color = { alphaScale, alphaScale, alphaScale, alphaScale };

    SkXfermode::Mode mode = PaintUtils::getXfermode(paint->getXfermode());
    const bool SWAP_SRC_DST = false;
    // TODO: account for texture blend
    if (alphaScale < 1.0f) {
        Blend::getFactors(SkXfermode::kSrcOver_Mode, SWAP_SRC_DST,
                &mOutGlop->blend.src, &mOutGlop->blend.dst);
    } else {
        mOutGlop->blend = { GL_ZERO, GL_ZERO };
    }

    return *this;
}
GlopBuilder& GlopBuilder::setPaint(const SkPaint& paint, float alphaScale) {
    TRIGGER_STAGE(kFillStage);

    const SkShader* shader = paint.getShader();
    const SkColorFilter* colorFilter = paint.getColorFilter();

    SkXfermode::Mode mode = PaintUtils::getXfermode(paint.getXfermode());
    if (mode != SkXfermode::kClear_Mode) {
        int color = paint->getColor();
        int color = paint.getColor();
        float alpha = (SkColorGetA(color) / 255.0f) * alphaScale;
        if (!shader) {
            float colorScale = alpha / 255.0f;
@@ -195,6 +231,8 @@ GlopBuilder& GlopBuilder::setPaint(const SkPaint* paint, float alphaScale) {
            colorVector[1] = srcColorMatrix[9] / 255.0f;
            colorVector[2] = srcColorMatrix[14] / 255.0f;
            colorVector[3] = srcColorMatrix[19] / 255.0f;
        } else {
            LOG_ALWAYS_FATAL("unsupported ColorFilter");
        }
    } else {
        mOutGlop->fill.filterMode = ProgramDescription::kColorNone;
+4 −1
Original line number Diff line number Diff line
@@ -36,15 +36,18 @@ class GlopBuilder {
    PREVENT_COPY_AND_ASSIGN(GlopBuilder);
public:
    GlopBuilder(RenderState& renderState, Caches& caches, Glop* outGlop);

    GlopBuilder& setMeshUnitQuad();
    GlopBuilder& setMeshVertexBuffer(const VertexBuffer& vertexBuffer, bool shadowInterp);
    GlopBuilder& setMeshIndexedQuads(void* vertexData, int quadCount);

    GlopBuilder& setTransform(const Matrix4& ortho, const Matrix4& transform, bool fudgingOffset);

    GlopBuilder& setModelViewMapUnitToRect(const Rect destination);
    GlopBuilder& setModelViewOffsetRect(float offsetX, float offsetY, const Rect source);

    GlopBuilder& setPaint(const SkPaint* paint, float alphaScale);
    GlopBuilder& setOptionalPaint(const SkPaint* paint, float alphaScale);
    GlopBuilder& setPaint(const SkPaint& paint, float alphaScale);
    void build();
private:
    enum StageFlags {
+27 −10
Original line number Diff line number Diff line
@@ -1581,8 +1581,13 @@ void OpenGLRenderer::renderGlop(const Glop& glop) {
        setStencilFromClip();
    }
    mRenderState.render(glop);

    if (!mRenderState.stencil().isWriteEnabled()) {
        // TODO: specify more clearly when a draw should dirty the layer.
        // is writing to the stencil the only time we should ignore this?
        dirtyLayer(glop.bounds.left, glop.bounds.top, glop.bounds.right, glop.bounds.bottom);
    }
}

///////////////////////////////////////////////////////////////////////////////
// Drawing commands
@@ -2353,13 +2358,12 @@ void OpenGLRenderer::drawVertexBuffer(float translateX, float translateY,
        aBuilder.setMeshVertexBuffer(vertexBuffer, shadowInterp)
                .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), fudgeOffset)
                .setModelViewOffsetRect(translateX, translateY, vertexBuffer.getBounds())
                .setPaint(paint, currentSnapshot()->alpha)
                .setPaint(*paint, currentSnapshot()->alpha)
                .build();
        renderGlop(glop);
        return;
    }


    const VertexBuffer::MeshFeatureFlags meshFeatureFlags = vertexBuffer.getMeshFeatureFlags();
    Rect bounds(vertexBuffer.getBounds());
    bounds.translate(translateX, translateY);
@@ -3218,12 +3222,6 @@ void OpenGLRenderer::drawColorRects(const float* rects, int count, const SkPaint
        return;
    }

    int color = paint->getColor();
    // If a shader is set, preserve only the alpha
    if (getShader(paint)) {
        color |= 0x00ffffff;
    }

    float left = FLT_MAX;
    float top = FLT_MAX;
    float right = FLT_MIN;
@@ -3253,6 +3251,25 @@ void OpenGLRenderer::drawColorRects(const float* rects, int count, const SkPaint
        return;
    }

    if (!paint->getShader() && !currentSnapshot()->roundRectClipState) {
        const Matrix4& transform = ignoreTransform ? Matrix4::identity() : *currentTransform();
        Glop glop;
        GlopBuilder aBuilder(mRenderState, mCaches, &glop);
        aBuilder.setMeshIndexedQuads(&mesh[0], count / 4)
                .setTransform(currentSnapshot()->getOrthoMatrix(), transform, false)
                .setModelViewOffsetRect(0, 0, Rect(left, top, right, bottom))
                .setPaint(*paint, currentSnapshot()->alpha)
                .build();
        renderGlop(glop);
        return;
    }

    int color = paint->getColor();
    // If a shader is set, preserve only the alpha
    if (getShader(paint)) {
        color |= 0x00ffffff;
    }

    setupDraw();
    setupDrawNoTexture();
    setupDrawColor(color, ((color >> 24) & 0xFF) * currentSnapshot()->alpha);
@@ -3286,7 +3303,7 @@ void OpenGLRenderer::drawColorRect(float left, float top, float right, float bot
        aBuilder.setMeshUnitQuad()
                .setTransform(currentSnapshot()->getOrthoMatrix(), transform, false)
                .setModelViewMapUnitToRect(Rect(left, top, right, bottom))
                .setPaint(paint, currentSnapshot()->alpha)
                .setPaint(*paint, currentSnapshot()->alpha)
                .build();
        renderGlop(glop);
        return;
+17 −21
Original line number Diff line number Diff line
@@ -31,13 +31,29 @@ MeshState::MeshState()
        , mCurrentTexCoordsStride(0)
        , mTexCoordsArrayEnabled(false)
        , mQuadListIndices(0) {

    glGenBuffers(1, &mUnitQuadBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, mUnitQuadBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(kUnitQuadVertices), kUnitQuadVertices, GL_STATIC_DRAW);

    mCurrentBuffer = mUnitQuadBuffer;

    std::unique_ptr<uint16_t[]> regionIndices(new uint16_t[kMaxNumberOfQuads * 6]);
    for (uint32_t i = 0; i < kMaxNumberOfQuads; i++) {
        uint16_t quad = i * 4;
        int index = i * 6;
        regionIndices[index    ] = quad;       // top-left
        regionIndices[index + 1] = quad + 1;   // top-right
        regionIndices[index + 2] = quad + 2;   // bottom-left
        regionIndices[index + 3] = quad + 2;   // bottom-left
        regionIndices[index + 4] = quad + 1;   // top-right
        regionIndices[index + 5] = quad + 3;   // bottom-right
    }
    glGenBuffers(1, &mQuadListIndices);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mQuadListIndices);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, kMaxNumberOfQuads * 6 * sizeof(uint16_t),
            regionIndices.get(), GL_STATIC_DRAW);
    mCurrentIndicesBuffer = mQuadListIndices;

    // position attribute always enabled
    glEnableVertexAttribArray(Program::kBindingPosition);
}
@@ -138,26 +154,6 @@ bool MeshState::bindIndicesBufferInternal(const GLuint buffer) {
}

bool MeshState::bindQuadIndicesBuffer() {
    if (!mQuadListIndices) {
        std::unique_ptr<uint16_t[]> regionIndices(new uint16_t[kMaxNumberOfQuads * 6]);
        for (uint32_t i = 0; i < kMaxNumberOfQuads; i++) {
            uint16_t quad = i * 4;
            int index = i * 6;
            regionIndices[index    ] = quad;       // top-left
            regionIndices[index + 1] = quad + 1;   // top-right
            regionIndices[index + 2] = quad + 2;   // bottom-left
            regionIndices[index + 3] = quad + 2;   // bottom-left
            regionIndices[index + 4] = quad + 1;   // top-right
            regionIndices[index + 5] = quad + 3;   // bottom-right
        }

        glGenBuffers(1, &mQuadListIndices);
        bool force = bindIndicesBufferInternal(mQuadListIndices);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, kMaxNumberOfQuads * 6 * sizeof(uint16_t),
                regionIndices.get(), GL_STATIC_DRAW);
        return force;
    }

    return bindIndicesBufferInternal(mQuadListIndices);
}

Loading