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
diff --git a/libs/hwui/BakedOpRenderer.cpp b/libs/hwui/BakedOpRenderer.cpp
index df2b35b..4e59baa 100644
--- a/libs/hwui/BakedOpRenderer.cpp
+++ b/libs/hwui/BakedOpRenderer.cpp
@@ -208,7 +208,6 @@
// 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 @@
.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 @@
.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::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;
}