Re-enabling DisplayList properties

Several issues came up after DisplayList properties were enabled,
so they were disabled pending fixes. Those issues have been fixed, so
DisplayList properties are once again being enabled by default. This
CL both re-enables these properties (in View.java and DisplayListRenderer.h)
and fixes the various issues that enabling them caused the first time around.

Related issues (all currently marked as Fixed, though that was simply because
DL properties were disabled - this CL provides the real fixes now that
DL properties are enabled by default):
Issue #6198276 Text input broken
Issue #6198472 Native crash at pc 00076428 in many different apps in JRM80
Issue #6204173 Date/time picker isn't rendering all parts of UI
Issue #6203941 All Apps overscroll effect is rendered weirdly/has flickering
Issue #6200058 CAB rendering issue - not drawing items?
Issue #6198578 Front camera shows black screen after taking picture.
Issue #6232010 Layers not recreated when children change (DisplayList properties)

Change-Id: I8b5f9ec342208ecb20d3e6a60d26cf7c6112ec8b
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index f769e96..2deeba6 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1459,7 +1459,7 @@
      * apps.
      * @hide
      */
-    public static final boolean USE_DISPLAY_LIST_PROPERTIES = false;
+    public static final boolean USE_DISPLAY_LIST_PROPERTIES = true;
 
     /**
      * Map used to store views' tags.
@@ -7401,7 +7401,7 @@
 
         invalidateViewProperty(false, false);
         if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
-            mDisplayList.setCameraDistance(distance);
+            mDisplayList.setCameraDistance(-Math.abs(distance) / dpi);
         }
     }
 
@@ -10747,16 +10747,25 @@
                 int layerType = (
                         !(mParent instanceof ViewGroup) || ((ViewGroup)mParent).mDrawLayers) ?
                         getLayerType() : LAYER_TYPE_NONE;
-                if (!isLayer && layerType == LAYER_TYPE_HARDWARE && USE_DISPLAY_LIST_PROPERTIES) {
-                    final HardwareLayer layer = getHardwareLayer();
-                    if (layer != null && layer.isValid()) {
-                        canvas.drawHardwareLayer(layer, 0, 0, mLayerPaint);
+                if (!isLayer && layerType != LAYER_TYPE_NONE && USE_DISPLAY_LIST_PROPERTIES) {
+                    if (layerType == LAYER_TYPE_HARDWARE) {
+                        final HardwareLayer layer = getHardwareLayer();
+                        if (layer != null && layer.isValid()) {
+                            canvas.drawHardwareLayer(layer, 0, 0, mLayerPaint);
+                        } else {
+                            canvas.saveLayer(0, 0, mRight - mLeft, mBottom - mTop, mLayerPaint,
+                                    Canvas.HAS_ALPHA_LAYER_SAVE_FLAG |
+                                            Canvas.CLIP_TO_LAYER_SAVE_FLAG);
+                        }
+                        caching = true;
                     } else {
-                        canvas.saveLayer(0, 0,
-                                mRight - mLeft, mBottom - mTop, mLayerPaint,
-                                Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);
+                        buildDrawingCache(true);
+                        Bitmap cache = getDrawingCache(true);
+                        if (cache != null) {
+                            canvas.drawBitmap(cache, 0, 0, mLayerPaint);
+                            caching = true;
+                        }
                     }
-                    caching = true;
                 } else {
 
                     computeScroll();
@@ -11395,7 +11404,11 @@
                         mTransformationInfo.mRotation, mTransformationInfo.mRotationX,
                         mTransformationInfo.mRotationY, mTransformationInfo.mScaleX,
                         mTransformationInfo.mScaleY);
-                displayList.setCameraDistance(getCameraDistance());
+                if (mTransformationInfo.mCamera == null) {
+                    mTransformationInfo.mCamera = new Camera();
+                    mTransformationInfo.matrix3D = new Matrix();
+                }
+                displayList.setCameraDistance(mTransformationInfo.mCamera.getLocationZ());
                 if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == PIVOT_EXPLICITLY_SET) {
                     displayList.setPivotX(getPivotX());
                     displayList.setPivotY(getPivotY());
@@ -11489,8 +11502,12 @@
             } else {
                 switch (layerType) {
                     case LAYER_TYPE_SOFTWARE:
-                        buildDrawingCache(true);
-                        cache = getDrawingCache(true);
+                        if (useDisplayListProperties) {
+                            hasDisplayList = canHaveDisplayList();
+                        } else {
+                            buildDrawingCache(true);
+                            cache = getDrawingCache(true);
+                        }
                         break;
                     case LAYER_TYPE_HARDWARE:
                         if (useDisplayListProperties) {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 6ccac78..30d6ec7 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3906,9 +3906,15 @@
             do {
                 if (parent instanceof ViewGroup) {
                     ViewGroup parentVG = (ViewGroup) parent;
-                    parent = parentVG.invalidateChildInParentFast(left, top, dirty);
-                    left = parentVG.mLeft;
-                    top = parentVG.mTop;
+                    if (parentVG.mLayerType != LAYER_TYPE_NONE) {
+                        // Layered parents should be recreated, not just re-issued
+                        parentVG.invalidate();
+                        parent = null;
+                    } else {
+                        parent = parentVG.invalidateChildInParentFast(left, top, dirty);
+                        left = parentVG.mLeft;
+                        top = parentVG.mTop;
+                    }
                 } else {
                     // Reached the top; this calls into the usual invalidate method in
                     // ViewRootImpl, which schedules a traversal
@@ -4664,6 +4670,7 @@
     public void clearDisappearingChildren() {
         if (mDisappearingChildren != null) {
             mDisappearingChildren.clear();
+            invalidate();
         }
     }
 
@@ -4775,7 +4782,7 @@
                         view.mParent = null;
                     }
                 }
-                mGroupFlags |= FLAG_INVALIDATE_REQUIRED;
+                invalidate();
             }
         }
     }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 5c9dc88..1f2410b 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -11683,7 +11683,7 @@
                 highlight = null;
             }
 
-            if (false /* TEMP patch for bugs 6198276 & 6193544 */ && canHaveDisplayList() && canvas.isHardwareAccelerated()) {
+            if (canHaveDisplayList() && canvas.isHardwareAccelerated()) {
                 drawHardwareAccelerated(canvas, layout, highlight, cursorOffsetVertical);
             } else {
                 layout.draw(canvas, highlight, mHighlightPaint, cursorOffsetVertical);
@@ -11758,7 +11758,7 @@
                         hardwareCanvas.onPostDraw();
                         blockDisplayList.end();
                         if (USE_DISPLAY_LIST_PROPERTIES) {
-                            blockDisplayList.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom);
+                            blockDisplayList.setLeftTopRightBottom(0, 0, width, height);
                         }
                     }
                 }
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 93acafc..3a3f8a5 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -106,7 +106,7 @@
 void DisplayList::initProperties() {
     mLeft = 0;
     mTop = 0;
-    mTop = 0;
+    mRight = 0;
     mBottom = 0;
     mApplicationScale = -1;
     mClipChildren = true;
@@ -121,6 +121,7 @@
     mScaleY = 1;
     mPivotX = 0;
     mPivotY = 0;
+    mCameraDistance = 0;
     mMatrixDirty = false;
     mMatrixFlags = 0;
     mPrevWidth = -1;
@@ -686,7 +687,7 @@
                         mTransformMatrix->get(8));
             }
         }
-        if (mAlpha < 1) {
+        if (mAlpha < 1 && !mCaching) {
             // TODO: should be able to store the size of a DL at record time and not
             // have to pass it into this call. In fact, this information might be in the
             // location/size info that we store with the new native transform data.
@@ -765,34 +766,6 @@
     }
 }
 
-void DisplayList::transformRect(float left, float top, float right, float bottom, Rect& result) {
-    result.left = left + mLeft;
-    result.top = top + mTop;
-    result.right = right + mLeft;
-    result.bottom = bottom + mTop;
-    if (mMatrixFlags != 0) {
-        if (mMatrixFlags == TRANSLATION) {
-            result.left += mTranslationX;
-            result.top += mTranslationY;
-            result.right += mTranslationX;
-            result.bottom += mTranslationY;
-        } else {
-            updateMatrix();
-            SkRect r;
-            r.fLeft = result.left;
-            r.fTop = result.top;
-            r.fRight = result.right;
-            r.fBottom = result.bottom;
-            mTransformMatrix->mapRect(&r);
-            result.left = r.fLeft;
-            result.top = r.fTop;
-            result.right = r.fRight;
-            result.bottom = r.fBottom;
-        }
-    }
-}
-
-
 /**
  * Changes to replay(), specifically those involving opcode or parameter changes, should be mimicked
  * in the output() function, since that function processes the same list of opcodes for the
@@ -822,6 +795,12 @@
         restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
     }
     setViewProperties(renderer, width, height, level);
+    if (USE_DISPLAY_LIST_PROPERTIES && renderer.quickReject(0, 0, width, height)) {
+        DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo);
+        renderer.restoreToCount(restoreTo);
+        renderer.endMark();
+        return false;
+    }
 
     DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
     int saveCount = renderer.getSaveCount() - 1;
@@ -974,6 +953,9 @@
                 float x = getFloat();
                 float y = getFloat();
                 SkPaint* paint = getPaint(renderer);
+                if (mCaching && mMultipliedAlpha < 255) {
+                    paint->setAlpha(mMultipliedAlpha);
+                }
                 DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
                         bitmap, x, y, paint);
                 renderer.drawBitmap(bitmap, x, y, paint);
@@ -1421,24 +1403,11 @@
         uint32_t width, uint32_t height, Rect& dirty, int32_t flags, uint32_t level) {
     // dirty is an out parameter and should not be recorded,
     // it matters only when replaying the display list
-    float top = 0;
-    float left = 0;
-    float right = width;
-    float bottom = height;
-    if (USE_DISPLAY_LIST_PROPERTIES) {
-        Rect transformedRect;
-        displayList->transformRect(left, top, right, bottom, transformedRect);
-        left = transformedRect.left;
-        top = transformedRect.top;
-        right = transformedRect.right;
-        bottom = transformedRect.bottom;
-    }
-    const bool reject = quickReject(left, top, right, bottom);
-    uint32_t* location = addOp(DisplayList::DrawDisplayList, reject);
+
+    addOp(DisplayList::DrawDisplayList);
     addDisplayList(displayList);
     addSize(width, height);
     addInt(flags);
-    addSkip(location);
     return DrawGlInfo::kStatusDone;
 }
 
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 2b32073..4a9886b 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -51,7 +51,7 @@
 
 // Set to 1 to enable native processing of View properties. 0 by default. Eventually this
 // will go away and we will always use this approach for accelerated apps.
-#define USE_DISPLAY_LIST_PROPERTIES 0
+#define USE_DISPLAY_LIST_PROPERTIES 1
 
 #define TRANSLATION 0x0001
 #define ROTATION    0x0002
@@ -379,8 +379,6 @@
         mCaching = caching;
     }
 
-    void transformRect(float left, float top, float right, float bottom, Rect& result);
-
 private:
     void init();
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index a7c53ca..eb4b83b 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1323,19 +1323,8 @@
 
 status_t OpenGLRenderer::drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
         Rect& dirty, int32_t flags, uint32_t level) {
-    float top = 0;
-    float left = 0;
-    float right = width;
-    float bottom = height;
-    if (USE_DISPLAY_LIST_PROPERTIES) {
-        Rect transformedRect;
-        displayList->transformRect(left, top, right, bottom, transformedRect);
-        left = transformedRect.left;
-        top = transformedRect.top;
-        right = transformedRect.right;
-        bottom = transformedRect.bottom;
-    }
-    if (quickReject(left, top, right, bottom)) {
+
+    if (!USE_DISPLAY_LIST_PROPERTIES && quickReject(0, 0, width, height)) {
         return false;
     }