Merge "Merge commit '1b003ef0' into mit"
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 055aee3..f4ab133 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -151,12 +151,12 @@
     static native int nCreateTextureLayer(boolean opaque, int[] layerInfo);
     static native int nCreateLayer(int width, int height, boolean isOpaque, int[] layerInfo);
     static native void nResizeLayer(int layerId, int width, int height, int[] layerInfo);
+    static native void nSetOpaqueLayer(int layerId, boolean isOpaque);
     static native void nUpdateTextureLayer(int layerId, int width, int height, boolean opaque,
             SurfaceTexture surface);
     static native void nSetTextureLayerTransform(int layerId, int matrix);
     static native void nDestroyLayer(int layerId);
     static native void nDestroyLayerDeferred(int layerId);
-    static native void nFlushLayer(int layerId);
     static native void nUpdateRenderLayer(int layerId, int renderer, int displayList,
             int left, int top, int right, int bottom);
     static native boolean nCopyLayer(int layerId, int bitmap);
diff --git a/core/java/android/view/GLES20Layer.java b/core/java/android/view/GLES20Layer.java
index 4f25792..a0ae379 100644
--- a/core/java/android/view/GLES20Layer.java
+++ b/core/java/android/view/GLES20Layer.java
@@ -46,11 +46,6 @@
     boolean copyInto(Bitmap bitmap) {
         return GLES20Canvas.nCopyLayer(mLayer, bitmap.mNativeBitmap);
     }
-    
-    @Override
-    void update(int width, int height, boolean isOpaque) {
-        super.update(width, height, isOpaque);
-    }
 
     @Override
     void destroy() {
@@ -60,13 +55,6 @@
         }
         mLayer = 0;
     }
-    
-    @Override
-    void flush() {
-        if (mLayer != 0) {
-            GLES20Canvas.nFlushLayer(mLayer);
-        }
-    }
 
     static class Finalizer {
         private int mLayerId;
diff --git a/core/java/android/view/GLES20RenderLayer.java b/core/java/android/view/GLES20RenderLayer.java
index c727a36..a77425a 100644
--- a/core/java/android/view/GLES20RenderLayer.java
+++ b/core/java/android/view/GLES20RenderLayer.java
@@ -71,6 +71,12 @@
     }
 
     @Override
+    void setOpaque(boolean isOpaque) {
+        mOpaque = isOpaque;
+        GLES20Canvas.nSetOpaqueLayer(mLayer, isOpaque);
+    }
+
+    @Override
     HardwareCanvas getCanvas() {
         return mCanvas;
     }
diff --git a/core/java/android/view/GLES20TextureLayer.java b/core/java/android/view/GLES20TextureLayer.java
index 16a13cf..e198ef6 100644
--- a/core/java/android/view/GLES20TextureLayer.java
+++ b/core/java/android/view/GLES20TextureLayer.java
@@ -42,12 +42,6 @@
         }        
     }
 
-    GLES20TextureLayer(SurfaceTexture surface, boolean isOpaque) {
-        this(isOpaque);
-        mSurface = surface;
-        mSurface.attachToGLContext(mTexture);
-    }
-
     @Override
     boolean isValid() {
         return mLayer != 0 && mTexture != 0;
@@ -93,6 +87,11 @@
     }
 
     @Override
+    void setOpaque(boolean isOpaque) {
+        throw new UnsupportedOperationException("Use update(int, int, boolean) instead");
+    }
+
+    @Override
     void setTransform(Matrix matrix) {
         GLES20Canvas.nSetTextureLayerTransform(mLayer, matrix.native_instance);
     }
diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java
index e73f7bf..06c6e7c 100644
--- a/core/java/android/view/HardwareLayer.java
+++ b/core/java/android/view/HardwareLayer.java
@@ -107,6 +107,13 @@
     }
 
     /**
+     * Sets whether or not this layer should be considered opaque.
+     * 
+     * @param isOpaque True if the layer is opaque, false otherwise
+     */
+    abstract void setOpaque(boolean isOpaque);
+
+    /**
      * Indicates whether this layer can be rendered.
      * 
      * @return True if the layer can be rendered into, false otherwise
@@ -136,11 +143,6 @@
     abstract void destroy();
 
     /**
-     * Flush the render queue associated with this layer.
-     */
-    abstract void flush();
-
-    /**
      * This must be invoked before drawing onto this layer.
      * @param currentCanvas
      */
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 149470a..78b34e6 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4798,9 +4798,10 @@
     }
 
     /**
-     * Computes whether the given portion of this view is visible to the user. Such a view is
-     * attached, visible, all its predecessors are visible, has an alpha greater than zero, and
-     * the specified portion is not clipped entirely by its predecessors.
+     * Computes whether the given portion of this view is visible to the user.
+     * Such a view is attached, visible, all its predecessors are visible,
+     * has an alpha greater than zero, and the specified portion is not
+     * clipped entirely by its predecessors.
      *
      * @param boundInView the portion of the view to test; coordinates should be relative; may be
      *                    <code>null</code>, and the entire view will be tested in this case.
@@ -4814,22 +4815,26 @@
      * @hide
      */
     protected boolean isVisibleToUser(Rect boundInView) {
-        Rect visibleRect = mAttachInfo.mTmpInvalRect;
-        Point offset = mAttachInfo.mPoint;
-        // The first two checks are made also made by isShown() which
-        // however traverses the tree up to the parent to catch that.
-        // Therefore, we do some fail fast check to minimize the up
-        // tree traversal.
-        boolean isVisible = mAttachInfo != null
-            && mAttachInfo.mWindowVisibility == View.VISIBLE
-            && getAlpha() > 0
-            && isShown()
-            && getGlobalVisibleRect(visibleRect, offset);
+        if (mAttachInfo != null) {
+            Rect visibleRect = mAttachInfo.mTmpInvalRect;
+            Point offset = mAttachInfo.mPoint;
+            // The first two checks are made also made by isShown() which
+            // however traverses the tree up to the parent to catch that.
+            // Therefore, we do some fail fast check to minimize the up
+            // tree traversal.
+            boolean isVisible = mAttachInfo.mWindowVisibility == View.VISIBLE
+                && getAlpha() > 0
+                && isShown()
+                && getGlobalVisibleRect(visibleRect, offset);
             if (isVisible && boundInView != null) {
                 visibleRect.offset(-offset.x, -offset.y);
-                isVisible &= boundInView.intersect(visibleRect);
+                // isVisible is always true here, use a simple assignment
+                isVisible = boundInView.intersect(visibleRect);
             }
             return isVisible;
+        }
+
+        return false;
     }
 
     /**
@@ -5272,7 +5277,7 @@
      * @return Return true if this view applied the insets and it should not
      * continue propagating further down the hierarchy, false otherwise.
      * @see #getFitsSystemWindows()
-     * @see #setFitsSystemWindows()
+     * @see #setFitsSystemWindows(boolean) 
      * @see #setSystemUiVisibility(int)
      */
     protected boolean fitSystemWindows(Rect insets) {
@@ -6464,10 +6469,7 @@
      */
     public boolean includeForAccessibility() {
         if (mAttachInfo != null) {
-            if (!mAttachInfo.mIncludeNotImportantViews) {
-                return isImportantForAccessibility();
-            }
-            return true;
+            return mAttachInfo.mIncludeNotImportantViews || isImportantForAccessibility();
         }
         return false;
     }
@@ -11899,13 +11901,6 @@
         }
     }
 
-    // Make sure the HardwareRenderer.validate() was invoked before calling this method
-    void flushLayer() {
-        if (mLayerType == LAYER_TYPE_HARDWARE && mHardwareLayer != null) {
-            mHardwareLayer.flush();
-        }
-    }
-
     /**
      * <p>Returns a hardware layer that can be used to draw this view again
      * without executing its draw method.</p>
@@ -11932,9 +11927,24 @@
                 mHardwareLayer = mAttachInfo.mHardwareRenderer.createHardwareLayer(
                         width, height, isOpaque());
                 mLocalDirtyRect.set(0, 0, width, height);
-            } else if (mHardwareLayer.getWidth() != width || mHardwareLayer.getHeight() != height) {
-                mHardwareLayer.resize(width, height);
-                mLocalDirtyRect.set(0, 0, width, height);
+            } else {
+                if (mHardwareLayer.getWidth() != width || mHardwareLayer.getHeight() != height) {
+                    mHardwareLayer.resize(width, height);
+                    mLocalDirtyRect.set(0, 0, width, height);
+                }
+
+                // This should not be necessary but applications that change
+                // the parameters of their background drawable without calling
+                // this.setBackground(Drawable) can leave the view in a bad state
+                // (for instance isOpaque() returns true, but the background is
+                // not opaque.)
+                computeOpaqueFlags();
+
+                final boolean opaque = isOpaque();
+                if (mHardwareLayer.isOpaque() != opaque) {
+                    mHardwareLayer.setOpaque(opaque);
+                    mLocalDirtyRect.set(0, 0, width, height);
+                }
             }
 
             // The layer is not valid if the underlying GPU resources cannot be allocated
@@ -12741,10 +12751,10 @@
 
         if (more) {
             if (!a.willChangeBounds()) {
-                if ((flags & (parent.FLAG_OPTIMIZE_INVALIDATE | parent.FLAG_ANIMATION_DONE)) ==
-                        parent.FLAG_OPTIMIZE_INVALIDATE) {
-                    parent.mGroupFlags |= parent.FLAG_INVALIDATE_REQUIRED;
-                } else if ((flags & parent.FLAG_INVALIDATE_REQUIRED) == 0) {
+                if ((flags & (ViewGroup.FLAG_OPTIMIZE_INVALIDATE | ViewGroup.FLAG_ANIMATION_DONE)) ==
+                        ViewGroup.FLAG_OPTIMIZE_INVALIDATE) {
+                    parent.mGroupFlags |= ViewGroup.FLAG_INVALIDATE_REQUIRED;
+                } else if ((flags & ViewGroup.FLAG_INVALIDATE_REQUIRED) == 0) {
                     // The child need to draw an animation, potentially offscreen, so
                     // make sure we do not cancel invalidate requests
                     parent.mPrivateFlags |= DRAW_ANIMATION;
@@ -13946,6 +13956,7 @@
     public void setBackgroundColor(int color) {
         if (mBackground instanceof ColorDrawable) {
             ((ColorDrawable) mBackground).setColor(color);
+            computeOpaqueFlags();
         } else {
             setBackground(new ColorDrawable(color));
         }
@@ -13993,6 +14004,8 @@
      */
     @Deprecated
     public void setBackgroundDrawable(Drawable background) {
+        computeOpaqueFlags();
+
         if (background == mBackground) {
             return;
         }
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index a51b77e..9040941 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -769,6 +769,13 @@
     env->ReleaseIntArrayElements(layerInfo, storage, 0);
 }
 
+static void android_view_GLES20Canvas_setOpaqueLayer(JNIEnv* env, jobject clazz,
+        Layer* layer, jboolean isOpaque) {
+    if (layer) {
+        layer->setBlend(!isOpaque);
+    }
+}
+
 static void android_view_GLES20Canvas_updateTextureLayer(JNIEnv* env, jobject clazz,
         Layer* layer, jint width, jint height, jboolean isOpaque, jobject surface) {
     float transform[16];
@@ -803,10 +810,6 @@
     LayerRenderer::destroyLayerDeferred(layer);
 }
 
-static void android_view_GLES20Canvas_flushLayer(JNIEnv* env, jobject clazz, Layer* layer) {
-    LayerRenderer::flushLayer(layer);
-}
-
 static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, Layer* layer, jfloat x, jfloat y, SkPaint* paint) {
     renderer->drawLayer(layer, x, y, paint);
@@ -969,13 +972,13 @@
     { "nCreateLayerRenderer",    "(I)I",       (void*) android_view_GLES20Canvas_createLayerRenderer },
     { "nCreateLayer",            "(IIZ[I)I",   (void*) android_view_GLES20Canvas_createLayer },
     { "nResizeLayer",            "(III[I)V" ,  (void*) android_view_GLES20Canvas_resizeLayer },
+    { "nSetOpaqueLayer",         "(IZ)V",      (void*) android_view_GLES20Canvas_setOpaqueLayer },
     { "nCreateTextureLayer",     "(Z[I)I",     (void*) android_view_GLES20Canvas_createTextureLayer },
     { "nUpdateTextureLayer",     "(IIIZLandroid/graphics/SurfaceTexture;)V",
             (void*) android_view_GLES20Canvas_updateTextureLayer },
     { "nUpdateRenderLayer",      "(IIIIIII)V", (void*) android_view_GLES20Canvas_updateRenderLayer },
     { "nDestroyLayer",           "(I)V",       (void*) android_view_GLES20Canvas_destroyLayer },
     { "nDestroyLayerDeferred",   "(I)V",       (void*) android_view_GLES20Canvas_destroyLayerDeferred },
-    { "nFlushLayer",             "(I)V",       (void*) android_view_GLES20Canvas_flushLayer },
     { "nDrawLayer",              "(IIFFI)V",   (void*) android_view_GLES20Canvas_drawLayer },
     { "nCopyLayer",              "(II)Z",      (void*) android_view_GLES20Canvas_copyLayer },
 
diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h
index 8f3a0a3..531aa5b 100644
--- a/libs/hwui/LayerRenderer.h
+++ b/libs/hwui/LayerRenderer.h
@@ -61,12 +61,13 @@
             bool isOpaque, GLenum renderTarget, float* transform);
     ANDROID_API static void destroyLayer(Layer* layer);
     ANDROID_API static void destroyLayerDeferred(Layer* layer);
-    ANDROID_API static void flushLayer(Layer* layer);
     ANDROID_API static bool copyLayer(Layer* layer, SkBitmap* bitmap);
 
 private:
     void generateMesh();
 
+    static void flushLayer(Layer* layer);
+
     Layer* mLayer;
 }; // class LayerRenderer