Don't draw fully transparent views/primitives.

Change-Id: Icd7d8ef1f57b51a24faf32f7004125e6300d4fdc
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index acdfc28..f413475 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -25,6 +25,20 @@
  */
 public class ViewConfiguration {
     /**
+     * Expected bit depth of the display panel.
+     * 
+     * @hide
+     */
+    public static final float PANEL_BIT_DEPTH = 24;
+
+    /**
+     * Minimum alpha required for a view to draw.
+     * 
+     * @hide
+     */
+    public static final float ALPHA_THRESHOLD = 0.5f / PANEL_BIT_DEPTH;
+    
+    /**
      * Defines the width of the horizontal scrollbar and the height of the vertical scrollbar in
      * pixels
      */
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 5b3a091..be6aa43b 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -69,7 +69,7 @@
 public abstract class ViewGroup extends View implements ViewParent, ViewManager {
 
     private static final boolean DBG = false;
-
+    
     /**
      * Views which have been hidden or removed which need to be animated on
      * their way out.
@@ -2185,6 +2185,10 @@
                 (child.mPrivateFlags & DRAW_ANIMATION) == 0) {
             return more;
         }
+        
+        float alpha = child.getAlpha();
+        // Bail out early if the view does not need to be drawn
+        if (alpha <= ViewConfiguration.ALPHA_THRESHOLD) return more;
 
         child.computeScroll();
 
@@ -2217,8 +2221,6 @@
             }
         }
 
-        float alpha = child.getAlpha();
-
         if (transformToApply != null || alpha < 1.0f || !child.hasIdentityMatrix()) {
             int transX = 0;
             int transY = 0;
@@ -2253,7 +2255,7 @@
 
             if (alpha < 1.0f) {
                 mGroupFlags |= FLAG_CLEAR_TRANSFORMATION;
-            
+
                 if (hasNoCache) {
                     final int multipliedAlpha = (int) (255 * alpha);
                     if (!child.onSetAlpha(multipliedAlpha)) {
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 4878063..57de43a 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -43,6 +43,9 @@
 #define RAD_TO_DEG (180.0f / 3.14159265f)
 #define MIN_ANGLE 0.001f
 
+// TODO: This should be set in properties
+#define ALPHA_THRESHOLD (0x7f / PANEL_BIT_DEPTH)
+
 ///////////////////////////////////////////////////////////////////////////////
 // Globals
 ///////////////////////////////////////////////////////////////////////////////
@@ -294,7 +297,9 @@
         mode = SkXfermode::kSrcOver_Mode;
     }
 
-    createLayer(mSnapshot, left, top, right, bottom, alpha, mode, flags, previousFbo);
+    if (!mSnapshot->previous->invisible) {
+        createLayer(mSnapshot, left, top, right, bottom, alpha, mode, flags, previousFbo);
+    }
 
     return count;
 }
@@ -380,6 +385,14 @@
 
     if (bounds.isEmpty() || bounds.getWidth() > mMaxTextureSize ||
             bounds.getHeight() > mMaxTextureSize) {
+        snapshot->invisible = true;
+    } else {
+        // TODO: Should take the mode into account
+        snapshot->invisible = snapshot->previous->invisible || alpha <= ALPHA_THRESHOLD;
+    }
+
+    // Bail out if we won't draw in this snapshot
+    if (snapshot->invisible) {
         return false;
     }
 
@@ -536,7 +549,7 @@
 }
 
 void OpenGLRenderer::clearLayerRegions() {
-    if (mLayers.size() == 0) return;
+    if (mLayers.size() == 0 || mSnapshot->invisible) return;
 
     for (uint32_t i = 0; i < mLayers.size(); i++) {
         Rect* bounds = mLayers.itemAt(i);
@@ -598,6 +611,10 @@
 }
 
 bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom) {
+    if (mSnapshot->invisible) {
+        return true;
+    }
+
     Rect r(left, top, right, bottom);
     mSnapshot->transform->mapRect(r);
     return !mSnapshot->clipRect->intersects(r);
@@ -703,6 +720,8 @@
 }
 
 void OpenGLRenderer::drawLines(float* points, int count, const SkPaint* paint) {
+    if (mSnapshot->invisible) return;
+
     int alpha;
     SkXfermode::Mode mode;
     getAlphaAndMode(paint, &alpha, &mode);
@@ -802,6 +821,7 @@
     if (text == NULL || count == 0 || (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) {
         return;
     }
+    if (mSnapshot->invisible) return;
 
     paint->setAntiAlias(true);
 
@@ -866,6 +886,8 @@
 }
 
 void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
+    if (mSnapshot->invisible) return;
+
     GLuint textureUnit = 0;
     glActiveTexture(gTextureUnits[textureUnit]);
 
diff --git a/libs/hwui/ProgramCache.h b/libs/hwui/ProgramCache.h
index 964d842..ec9851e 100644
--- a/libs/hwui/ProgramCache.h
+++ b/libs/hwui/ProgramCache.h
@@ -45,7 +45,7 @@
 #endif
 
 // TODO: This should be set in properties
-#define PANEL_BIT_DEPTH 18
+#define PANEL_BIT_DEPTH 20
 #define COLOR_COMPONENT_THRESHOLD (1.0f - (0.5f / PANEL_BIT_DEPTH))
 #define COLOR_COMPONENT_INV_THRESHOLD (0.5f / PANEL_BIT_DEPTH)
 
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index 3d74b4c..35cdf6f 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -43,7 +43,7 @@
  */
 class Snapshot: public LightRefBase<Snapshot> {
 public:
-    Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0) {
+    Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0), invisible(false) {
         transform = &mTransformRoot;
         clipRect = &mClipRectRoot;
     }
@@ -53,8 +53,8 @@
      * the previous snapshot.
      */
     Snapshot(const sp<Snapshot>& s, int saveFlags):
-            flags(0), previous(s), layer(NULL),
-            fbo(s->fbo), viewport(s->viewport), height(s->height) {
+            flags(0), previous(s), layer(NULL), fbo(s->fbo),
+            invisible(s->invisible), viewport(s->viewport), height(s->height) {
         if (saveFlags & SkCanvas::kMatrix_SaveFlag) {
             mTransformRoot.load(*s->transform);
             transform = &mTransformRoot;
@@ -212,6 +212,12 @@
     GLuint fbo;
 
     /**
+     * Indicates that this snapshot is invisible and nothing should be drawn
+     * inside it.
+     */
+    bool invisible;
+
+    /**
      * Current viewport.
      */
     Rect viewport;