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/renderstate/Blend.cpp b/libs/hwui/renderstate/Blend.cpp
index 8865c6e..b1ca4a2 100644
--- a/libs/hwui/renderstate/Blend.cpp
+++ b/libs/hwui/renderstate/Blend.cpp
@@ -118,7 +118,7 @@
 }
 
 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);
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index ededffb..5fc5cb2 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -262,7 +262,8 @@
 // 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 @@
     // ------------------------------------
     // ---------- GL state setup ----------
     // ------------------------------------
-    blend().setFactors(glop.blend.src, glop.blend.dst);
+    if (CC_UNLIKELY(overrideDisableBlending)) {
+        blend().setFactors(GL_ZERO, GL_ZERO);
+    } else {
+        blend().setFactors(glop.blend.src, glop.blend.dst);
+    }
 
     GL_CHECKPOINT(MODERATE);
 
diff --git a/libs/hwui/renderstate/RenderState.h b/libs/hwui/renderstate/RenderState.h
index df81e86..315fa2d 100644
--- a/libs/hwui/renderstate/RenderState.h
+++ b/libs/hwui/renderstate/RenderState.h
@@ -106,7 +106,7 @@
     // 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; }