Add private circular reveal API on View/RenderNode

Change-Id: I139c8e12b354083149a665f6768f3f6931a8dd15
diff --git a/libs/hwui/RenderProperties.cpp b/libs/hwui/RenderProperties.cpp
index ca291a6..3975a76 100644
--- a/libs/hwui/RenderProperties.cpp
+++ b/libs/hwui/RenderProperties.cpp
@@ -22,6 +22,8 @@
 
 #include <SkCanvas.h>
 #include <SkMatrix.h>
+#include <SkPath.h>
+#include <SkPathOps.h>
 
 #include "Matrix.h"
 
@@ -51,13 +53,15 @@
 RenderProperties::ComputedFields::ComputedFields()
         : mTransformMatrix(NULL)
         , mTransformCamera(NULL)
-        , mTransformMatrix3D(NULL) {
+        , mTransformMatrix3D(NULL)
+        , mClipPath(NULL) {
 }
 
 RenderProperties::ComputedFields::~ComputedFields() {
     delete mTransformMatrix;
     delete mTransformCamera;
     delete mTransformMatrix3D;
+    delete mClipPath;
 }
 
 RenderProperties::RenderProperties()
@@ -80,6 +84,7 @@
 
         // Update the computed fields
         updateMatrix();
+        updateClipPath();
     }
     return *this;
 }
@@ -181,5 +186,39 @@
     }
 }
 
+void RenderProperties::updateClipPath() {
+    const SkPath* outlineClipPath = mPrimitiveFields.mOutline.willClip()
+            ? mPrimitiveFields.mOutline.getPath() : NULL;
+    const SkPath* revealClipPath = mPrimitiveFields.mRevealClip.getPath();
+
+    if (!outlineClipPath && !revealClipPath) {
+        // mComputedFields.mClipPath doesn't need to be updated, since it won't be used
+        return;
+    }
+
+    if (mComputedFields.mClipPath == NULL) {
+        mComputedFields.mClipPath = new SkPath();
+    }
+    SkPath* clipPath = mComputedFields.mClipPath;
+    mComputedFields.mClipPathOp = SkRegion::kIntersect_Op;
+
+    if (outlineClipPath && revealClipPath) {
+        SkPathOp op = kIntersect_PathOp;
+        if (mPrimitiveFields.mRevealClip.isInverseClip()) {
+            op = kDifference_PathOp; // apply difference step in the Op below, instead of draw time
+        }
+
+        Op(*outlineClipPath, *revealClipPath, op, clipPath);
+    } else if (outlineClipPath) {
+        *clipPath = *outlineClipPath;
+    } else {
+        *clipPath = *revealClipPath;
+        if (mPrimitiveFields.mRevealClip.isInverseClip()) {
+            // apply difference step at draw time
+            mComputedFields.mClipPathOp = SkRegion::kDifference_Op;
+        }
+    }
+}
+
 } /* namespace uirenderer */
 } /* namespace android */