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

Commit e52a3b29 authored by Chris Craik's avatar Chris Craik Committed by Android (Google) Code Review
Browse files

Merge "Glop support for indexed quads"

parents 69e358e3 2ab95d78
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