From e47aadd9b8e34601e8b1665865ad111224fe2018 Mon Sep 17 00:00:00 2001 From: Chris Craik Date: Thu, 31 Aug 2017 17:28:20 -0700 Subject: [PATCH] Fix blending behavior with first draw op Bug: 65077146 Test: Manual - uirendering tests don't allow test draw content to be displayed first. It's not always valid to disable blending on the first draw to the framebuffer, since some blend modes affect the framebuffer in different ways. We now only disable blending if the op is SRC_OVER to be safe. For example: canvas.drawColor(0xfeff0000, PorterDuff.Mode.CLEAR); canvas.drawColor(Color.BLUE, PorterDuff.Mode.DST_OVER); The BLUE should always be seen - the other draw should just clear the buffer. Prior to this fix, the above code (put in a window background) would draw black. In addition, this removes the disable behavior in drawRects(), since that should never benefit from the optimization - that decoration is always drawn at the end of a frame. Change-Id: I34e8d9d62d6e1dfa00e9301f44c277475f2940a8 --- libs/hwui/BakedOpRenderer.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/libs/hwui/BakedOpRenderer.cpp b/libs/hwui/BakedOpRenderer.cpp index 4e59baa48983..3c3b3177159b 100644 --- a/libs/hwui/BakedOpRenderer.cpp +++ b/libs/hwui/BakedOpRenderer.cpp @@ -216,10 +216,7 @@ void BakedOpRenderer::drawRects(const float* rects, int count, const SkPaint* pa .setTransform(Matrix4::identity(), TransformFlags::None) .setModelViewIdentityEmptyBounds() .build(); - // 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); + mRenderState.render(glop, mRenderTarget.orthoMatrix, false); mHasDrawn = true; } @@ -350,8 +347,14 @@ void BakedOpRenderer::renderGlopImpl(const Rect* dirtyBounds, const ClipBase* cl const Glop& glop) { prepareRender(dirtyBounds, clip); // 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; + // transparency where it doesn't make sense - as first draw in opaque window. Note that we only + // apply this improvement when the blend mode is SRC_OVER - other modes (e.g. CLEAR) can be + // valid draws that affect other content (e.g. draw CLEAR, then draw DST_OVER) + bool overrideDisableBlending = !mHasDrawn + && mOpaque + && !mRenderTarget.frameBufferId + && glop.blend.src == GL_ONE + && glop.blend.dst == GL_ONE_MINUS_SRC_ALPHA; mRenderState.render(glop, mRenderTarget.orthoMatrix, overrideDisableBlending); if (!mRenderTarget.frameBufferId) mHasDrawn = true; } -- 2.11.0