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

Commit 530a2b44 authored by Arun's avatar Arun Committed by Chris Craik
Browse files

Disable hwui blending for first draw to main FBO

bug:34809371

In some applications, the first draw is not opaque - either because the
application is misbehaved, or because hwui is not able to reliably tell
whether the layer is opaque or translucent. This is undefined behaviour
in OpenGL ES and has a significant performance and bandwidth impact on
some tiler GPUs as it requires loading the previous frame's color data.
This change disables blending in that case and also for effectively
opaque blend modes (SRC=GL_ONE, DST=GL_ZERO). It increases performance
by ~10% for Leanback CTS on some low-end GPUs (gradient layer that hwui
incorrectly believes to be translucent).

Test: manual - visual inspection on fugu (nexus player)

Change-Id: I2cbf1c76678acae1a36923e72fd18ed55cd89dc2
parent 94fa7ee9
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -208,7 +208,6 @@ void BakedOpRenderer::drawRects(const float* rects, int count, const SkPaint* pa
    // TODO: Currently assume full FBO damage, due to FrameInfoVisualizer::unionDirty.
    // Should should scissor/set mHasDrawn safely.
    mRenderState.scissor().setEnabled(false);
    mHasDrawn = true;
    Glop glop;
    GlopBuilder(mRenderState, mCaches, &glop)
            .setRoundRectClipState(nullptr)
@@ -217,7 +216,11 @@ void BakedOpRenderer::drawRects(const float* rects, int count, const SkPaint* pa
            .setTransform(Matrix4::identity(), TransformFlags::None)
            .setModelViewIdentityEmptyBounds()
            .build();
    mRenderState.render(glop, mRenderTarget.orthoMatrix);
    // Disable blending if this is the first draw to the main framebuffer, in case app has defined
    // transparency where it doesn't make sense - as first draw in opaque window.
    bool overrideDisableBlending = !mHasDrawn && mOpaque && !mRenderTarget.frameBufferId;
    mRenderState.render(glop, mRenderTarget.orthoMatrix, overrideDisableBlending);
    mHasDrawn = true;
}

// clears and re-fills stencil with provided rendertarget space quads,
@@ -234,7 +237,7 @@ void BakedOpRenderer::setupStencilQuads(std::vector<Vertex>& quadVertices,
            .setTransform(Matrix4::identity(), TransformFlags::None)
            .setModelViewIdentityEmptyBounds()
            .build();
    mRenderState.render(glop, mRenderTarget.orthoMatrix);
    mRenderState.render(glop, mRenderTarget.orthoMatrix, false);
    mRenderState.stencil().enableTest(incrementThreshold);
}

@@ -346,7 +349,10 @@ void BakedOpRenderer::prepareRender(const Rect* dirtyBounds, const ClipBase* cli
void BakedOpRenderer::renderGlopImpl(const Rect* dirtyBounds, const ClipBase* clip,
        const Glop& glop) {
    prepareRender(dirtyBounds, clip);
    mRenderState.render(glop, mRenderTarget.orthoMatrix);
    // Disable blending if this is the first draw to the main framebuffer, in case app has defined
    // transparency where it doesn't make sense - as first draw in opaque window.
    bool overrideDisableBlending = !mHasDrawn && mOpaque && !mRenderTarget.frameBufferId;
    mRenderState.render(glop, mRenderTarget.orthoMatrix, overrideDisableBlending);
    if (!mRenderTarget.frameBufferId) mHasDrawn = true;
}

+1 −1
Original line number Diff line number Diff line
@@ -228,7 +228,7 @@ inline CopyResult copyTextureInto(Caches& caches, RenderState& renderState,
                .build();
        Matrix4 ortho;
        ortho.loadOrtho(destWidth, destHeight);
        renderState.render(glop, ortho);
        renderState.render(glop, ortho, false);

        // TODO: We should convert to linear space when the target is RGBA16F
        glReadPixels(0, 0, bitmap->width(), bitmap->height(), format,
+1 −1
Original line number Diff line number Diff line
@@ -118,7 +118,7 @@ void Blend::getFactors(SkBlendMode mode, ModeOrderSwap modeUsage, GLenum* outSrc
}

void Blend::setFactors(GLenum srcMode, GLenum dstMode) {
    if (srcMode == GL_ZERO && dstMode == GL_ZERO) {
    if ((srcMode == GL_ZERO || srcMode == GL_ONE) && dstMode == GL_ZERO) {
        // disable blending
        if (mEnabled) {
            glDisable(GL_BLEND);
+7 −2
Original line number Diff line number Diff line
@@ -262,7 +262,8 @@ void RenderState::postDecStrong(VirtualLightRefBase* object) {
// Render
///////////////////////////////////////////////////////////////////////////////

void RenderState::render(const Glop& glop, const Matrix4& orthoMatrix) {
void RenderState::render(const Glop& glop, const Matrix4& orthoMatrix,
        bool overrideDisableBlending) {
    const Glop::Mesh& mesh = glop.mesh;
    const Glop::Mesh::Vertices& vertices = mesh.vertices;
    const Glop::Mesh::Indices& indices = mesh.indices;
@@ -417,7 +418,11 @@ void RenderState::render(const Glop& glop, const Matrix4& orthoMatrix) {
    // ------------------------------------
    // ---------- GL state setup ----------
    // ------------------------------------
    if (CC_UNLIKELY(overrideDisableBlending)) {
        blend().setFactors(GL_ZERO, GL_ZERO);
    } else {
        blend().setFactors(glop.blend.src, glop.blend.dst);
    }

    GL_CHECKPOINT(MODERATE);

+1 −1
Original line number Diff line number Diff line
@@ -106,7 +106,7 @@ public:
    // more thinking...
    void postDecStrong(VirtualLightRefBase* object);

    void render(const Glop& glop, const Matrix4& orthoMatrix);
    void render(const Glop& glop, const Matrix4& orthoMatrix, bool overrideDisableBlending);

    Blend& blend() { return *mBlend; }
    MeshState& meshState() { return *mMeshState; }