Prioritize reveal clipping over Outline clipping

bug:15780987
bug:17350602

Also update docs around clipping nesting behavior,
and some Z ordering behavior.

Change-Id: Iaa204350a0adfdcbd8c4b821fb4a9c0ae22f2613
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 72786eb0..7c29f48 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -405,7 +405,7 @@
         handler(op, PROPERTY_SAVECOUNT, properties().getClipToBounds());
     }
 
-    // TODO: support both reveal clip and outline clip simultaneously
+    // TODO: support nesting round rect clips
     if (mProperties.getRevealClip().willClip()) {
         Rect bounds;
         mProperties.getRevealClip().getBounds(&bounds);
@@ -413,7 +413,6 @@
     } else if (mProperties.getOutline().willClip()) {
         renderer.setClippingOutline(handler.allocator(), &(mProperties.getOutline()));
     }
-
 }
 
 /**
diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp
index ecc47d2..cf8229fd 100644
--- a/libs/hwui/Snapshot.cpp
+++ b/libs/hwui/Snapshot.cpp
@@ -216,14 +216,22 @@
 // Clipping round rect
 ///////////////////////////////////////////////////////////////////////////////
 
-void Snapshot::setClippingRoundRect(LinearAllocator& allocator, const Rect& bounds, float radius) {
+void Snapshot::setClippingRoundRect(LinearAllocator& allocator, const Rect& bounds,
+        float radius, bool highPriority) {
     if (bounds.isEmpty()) {
         clipRect->setEmpty();
         return;
     }
 
+    if (roundRectClipState && roundRectClipState->highPriority) {
+        // ignore, don't replace, already have a high priority clip
+        return;
+    }
+
     RoundRectClipState* state = new (allocator) RoundRectClipState;
 
+    state->highPriority = highPriority;
+
     // store the inverse drawing matrix
     Matrix4 roundRectDrawingMatrix;
     roundRectDrawingMatrix.load(getOrthoMatrix());
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index ad4ee9d..549de9b 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -55,6 +55,7 @@
                 || rect.intersects(dangerRects[3]);
     }
 
+    bool highPriority;
     Matrix4 matrix;
     Rect dangerRects[4];
     Rect innerRect;
@@ -166,8 +167,11 @@
 
     /**
      * Sets (and replaces) the current clipping outline
+     *
+     * If the current round rect clip is high priority, the incoming clip is ignored.
      */
-    void setClippingRoundRect(LinearAllocator& allocator, const Rect& bounds, float radius);
+    void setClippingRoundRect(LinearAllocator& allocator, const Rect& bounds,
+            float radius, bool highPriority);
 
     /**
      * Indicates whether this snapshot should be ignored. A snapshot
diff --git a/libs/hwui/StatefulBaseRenderer.cpp b/libs/hwui/StatefulBaseRenderer.cpp
index 3e1aed3..12b8c8d 100644
--- a/libs/hwui/StatefulBaseRenderer.cpp
+++ b/libs/hwui/StatefulBaseRenderer.cpp
@@ -198,13 +198,13 @@
         clipRect(bounds.left, bounds.top, bounds.right, bounds.bottom, SkRegion::kIntersect_Op);
     }
     if (outlineIsRounded) {
-        setClippingRoundRect(allocator, bounds, radius);
+        setClippingRoundRect(allocator, bounds, radius, false);
     }
 }
 
 void StatefulBaseRenderer::setClippingRoundRect(LinearAllocator& allocator,
-        const Rect& rect, float radius) {
-    mSnapshot->setClippingRoundRect(allocator, rect, radius);
+        const Rect& rect, float radius, bool highPriority) {
+    mSnapshot->setClippingRoundRect(allocator, rect, radius, highPriority);
 }
 
 
diff --git a/libs/hwui/StatefulBaseRenderer.h b/libs/hwui/StatefulBaseRenderer.h
index c6974b4..745e48a 100644
--- a/libs/hwui/StatefulBaseRenderer.h
+++ b/libs/hwui/StatefulBaseRenderer.h
@@ -97,7 +97,7 @@
      */
     void setClippingOutline(LinearAllocator& allocator, const Outline* outline);
     void setClippingRoundRect(LinearAllocator& allocator,
-            const Rect& rect, float radius);
+            const Rect& rect, float radius, bool highPriority = true);
 
     inline const mat4* currentTransform() const {
         return mSnapshot->transform;