Fix quickReject logic for transformed views

When a parent draws its child views, each child's bounds is checked
against the current dirty region. If the view falls outside of that
region is is rejected and doesn't enter into the parent's DisplayList.

This works in general, for both transformed and untransformed views
(because we skip this check if the view is transformed). But it breaks down
when the transform properties of the view change later, since DisplayList
properties simply push these values down to the view's DisplayList without
invalidating the parent. If a view is rejected when untransformed, then there
is nothing to cause it to be considered again until something causes an
invalidate of the parent.

The fix is to note when a view is rejected and record that information.
Later, when one of the transform-related properties change, we invalidate the parent
to force the check to happen again, which will cause the view to get drawn
if it's visible.

Issue #6477730 quickRejected views must recreate their DisplayLists on transform changes

Change-Id: I70caf198005cd7e424a37bccc6ae050e09880a6c
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index b4478bf..55ea938 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2135,6 +2135,13 @@
      */
     static final int VIEW_IS_ANIMATING_TRANSFORM = 0x10000000;
 
+    /**
+     * Flag indicating whether a view failed the quickReject() check in draw(). This condition
+     * is used to check whether later changes to the view's transform should invalidate the
+     * view to force the quickReject test to run again.
+     */
+    static final int VIEW_QUICK_REJECTED = 0x20000000;
+
     /* End of masks for mPrivateFlags2 */
 
     static final int DRAG_MASK = DRAG_CAN_ACCEPT | DRAG_HOVERED;
@@ -8567,6 +8574,10 @@
         if (mDisplayList != null) {
             mDisplayList.setCameraDistance(-Math.abs(distance) / dpi);
         }
+        if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+            // View was rejected last time it was drawn by its parent; this may have changed
+            invalidateParentIfNeeded();
+        }
     }
 
     /**
@@ -8609,6 +8620,10 @@
             if (mDisplayList != null) {
                 mDisplayList.setRotation(rotation);
             }
+            if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+                // View was rejected last time it was drawn by its parent; this may have changed
+                invalidateParentIfNeeded();
+            }
         }
     }
 
@@ -8656,6 +8671,10 @@
             if (mDisplayList != null) {
                 mDisplayList.setRotationY(rotationY);
             }
+            if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+                // View was rejected last time it was drawn by its parent; this may have changed
+                invalidateParentIfNeeded();
+            }
         }
     }
 
@@ -8703,6 +8722,10 @@
             if (mDisplayList != null) {
                 mDisplayList.setRotationX(rotationX);
             }
+            if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+                // View was rejected last time it was drawn by its parent; this may have changed
+                invalidateParentIfNeeded();
+            }
         }
     }
 
@@ -8742,6 +8765,10 @@
             if (mDisplayList != null) {
                 mDisplayList.setScaleX(scaleX);
             }
+            if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+                // View was rejected last time it was drawn by its parent; this may have changed
+                invalidateParentIfNeeded();
+            }
         }
     }
 
@@ -8781,6 +8808,10 @@
             if (mDisplayList != null) {
                 mDisplayList.setScaleY(scaleY);
             }
+            if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+                // View was rejected last time it was drawn by its parent; this may have changed
+                invalidateParentIfNeeded();
+            }
         }
     }
 
@@ -8828,6 +8859,10 @@
             if (mDisplayList != null) {
                 mDisplayList.setPivotX(pivotX);
             }
+            if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+                // View was rejected last time it was drawn by its parent; this may have changed
+                invalidateParentIfNeeded();
+            }
         }
     }
 
@@ -8874,6 +8909,10 @@
             if (mDisplayList != null) {
                 mDisplayList.setPivotY(pivotY);
             }
+            if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+                // View was rejected last time it was drawn by its parent; this may have changed
+                invalidateParentIfNeeded();
+            }
         }
     }
 
@@ -9032,6 +9071,10 @@
             }
             mBackgroundSizeChanged = true;
             invalidateParentIfNeeded();
+            if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+                // View was rejected last time it was drawn by its parent; this may have changed
+                invalidateParentIfNeeded();
+            }
         }
     }
 
@@ -9101,6 +9144,10 @@
             }
             mBackgroundSizeChanged = true;
             invalidateParentIfNeeded();
+            if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+                // View was rejected last time it was drawn by its parent; this may have changed
+                invalidateParentIfNeeded();
+            }
         }
     }
 
@@ -9164,6 +9211,10 @@
             }
             mBackgroundSizeChanged = true;
             invalidateParentIfNeeded();
+            if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+                // View was rejected last time it was drawn by its parent; this may have changed
+                invalidateParentIfNeeded();
+            }
         }
     }
 
@@ -9224,6 +9275,10 @@
             }
             mBackgroundSizeChanged = true;
             invalidateParentIfNeeded();
+            if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+                // View was rejected last time it was drawn by its parent; this may have changed
+                invalidateParentIfNeeded();
+            }
         }
     }
 
@@ -9308,6 +9363,10 @@
             if (mDisplayList != null) {
                 mDisplayList.setTranslationX(translationX);
             }
+            if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+                // View was rejected last time it was drawn by its parent; this may have changed
+                invalidateParentIfNeeded();
+            }
         }
     }
 
@@ -9345,6 +9404,10 @@
             if (mDisplayList != null) {
                 mDisplayList.setTranslationY(translationY);
             }
+            if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+                // View was rejected last time it was drawn by its parent; this may have changed
+                invalidateParentIfNeeded();
+            }
         }
     }
 
@@ -12816,8 +12879,10 @@
 
         if (!concatMatrix && canvas.quickReject(mLeft, mTop, mRight, mBottom, Canvas.EdgeType.BW) &&
                 (mPrivateFlags & DRAW_ANIMATION) == 0) {
+            mPrivateFlags2 |= VIEW_QUICK_REJECTED;
             return more;
         }
+        mPrivateFlags2 &= ~VIEW_QUICK_REJECTED;
 
         if (hardwareAccelerated) {
             // Clear INVALIDATED flag to allow invalidation to occur during rendering, but