switch over clip calls to use SkClipOp instead of SkRegion::Op

Change-Id: I67d23c487b5249bc31d96e3b2393f693c0b2bcff
diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp
index 04a7543..a31bd80 100644
--- a/core/jni/android_graphics_Canvas.cpp
+++ b/core/jni/android_graphics_Canvas.cpp
@@ -183,26 +183,46 @@
     return result ? JNI_TRUE : JNI_FALSE;
 }
 
+// SkRegion::Op and SkClipOp are numerically identical, so we can freely cast
+// from one to the other (though SkClipOp is destined to become a strict subset)
+static_assert(SkRegion::kDifference_Op == static_cast<SkRegion::Op>(kDifference_SkClipOp), "");
+static_assert(SkRegion::kIntersect_Op == static_cast<SkRegion::Op>(kIntersect_SkClipOp), "");
+static_assert(SkRegion::kUnion_Op == static_cast<SkRegion::Op>(kUnion_SkClipOp), "");
+static_assert(SkRegion::kXOR_Op == static_cast<SkRegion::Op>(kXOR_SkClipOp), "");
+static_assert(SkRegion::kReverseDifference_Op == static_cast<SkRegion::Op>(kReverseDifference_SkClipOp), "");
+static_assert(SkRegion::kReplace_Op == static_cast<SkRegion::Op>(kReplace_SkClipOp), "");
+
+static SkClipOp opHandleToClipOp(jint opHandle) {
+    // The opHandle is defined in Canvas.java to be Region::Op
+    SkRegion::Op rgnOp = static_cast<SkRegion::Op>(opHandle);
+
+    // In the future, when we no longer support the wide range of ops (e.g. Union, Xor)
+    // this function can perform a range check and throw an unsupported-exception.
+    // e.g. if (rgnOp != kIntersect && rgnOp != kDifference) throw...
+
+    // Skia now takes a different type, SkClipOp, as the parameter to clipping calls
+    // This type is binary compatible with SkRegion::Op, so a static_cast<> is safe.
+    return static_cast<SkClipOp>(rgnOp);
+}
+
 static jboolean clipRect(JNIEnv*, jobject, jlong canvasHandle, jfloat l, jfloat t,
                          jfloat r, jfloat b, jint opHandle) {
-    SkRegion::Op op = static_cast<SkRegion::Op>(opHandle);
-    bool nonEmptyClip = get_canvas(canvasHandle)->clipRect(l, t, r, b, op);
+    bool nonEmptyClip = get_canvas(canvasHandle)->clipRect(l, t, r, b,
+            opHandleToClipOp(opHandle));
     return nonEmptyClip ? JNI_TRUE : JNI_FALSE;
 }
 
 static jboolean clipPath(JNIEnv* env, jobject, jlong canvasHandle, jlong pathHandle,
                          jint opHandle) {
     SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
-    SkRegion::Op op = static_cast<SkRegion::Op>(opHandle);
-    bool nonEmptyClip = get_canvas(canvasHandle)->clipPath(path, op);
+    bool nonEmptyClip = get_canvas(canvasHandle)->clipPath(path, opHandleToClipOp(opHandle));
     return nonEmptyClip ? JNI_TRUE : JNI_FALSE;
 }
 
 static jboolean clipRegion(JNIEnv* env, jobject, jlong canvasHandle, jlong deviceRgnHandle,
                            jint opHandle) {
     SkRegion* deviceRgn = reinterpret_cast<SkRegion*>(deviceRgnHandle);
-    SkRegion::Op op = static_cast<SkRegion::Op>(opHandle);
-    bool nonEmptyClip = get_canvas(canvasHandle)->clipRegion(deviceRgn, op);
+    bool nonEmptyClip = get_canvas(canvasHandle)->clipRegion(deviceRgn, opHandleToClipOp(opHandle));
     return nonEmptyClip ? JNI_TRUE : JNI_FALSE;
 }
 
diff --git a/core/jni/android_view_GraphicBuffer.cpp b/core/jni/android_view_GraphicBuffer.cpp
index 4b105ca..53c9ff0 100644
--- a/core/jni/android_view_GraphicBuffer.cpp
+++ b/core/jni/android_view_GraphicBuffer.cpp
@@ -196,7 +196,8 @@
 
     Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvas);
     nativeCanvas->setBitmap(bitmap);
-    nativeCanvas->clipRect(rect.left, rect.top, rect.right, rect.bottom);
+    nativeCanvas->clipRect(rect.left, rect.top, rect.right, rect.bottom,
+            kIntersect_SkClipOp);
 
     if (dirtyRect) {
         INVOKEV(dirtyRect, gRectClassInfo.set,
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index b6c81cf8..63997e5 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -339,7 +339,7 @@
 
     if (dirtyRectPtr) {
         nativeCanvas->clipRect(dirtyRect.left, dirtyRect.top,
-                dirtyRect.right, dirtyRect.bottom);
+                dirtyRect.right, dirtyRect.bottom, kIntersect_SkClipOp);
     }
 
     if (dirtyRectObj) {
diff --git a/core/jni/android_view_TextureView.cpp b/core/jni/android_view_TextureView.cpp
index 268aec5..351dce9 100644
--- a/core/jni/android_view_TextureView.cpp
+++ b/core/jni/android_view_TextureView.cpp
@@ -166,7 +166,8 @@
 
     Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvas);
     nativeCanvas->setBitmap(bitmap);
-    nativeCanvas->clipRect(rect.left, rect.top, rect.right, rect.bottom);
+    nativeCanvas->clipRect(rect.left, rect.top, rect.right, rect.bottom,
+            kIntersect_SkClipOp);
 
     if (dirtyRect) {
         INVOKEV(dirtyRect, gRectClassInfo.set,
diff --git a/libs/hwui/CanvasState.cpp b/libs/hwui/CanvasState.cpp
index 7e2c28c..489039c2 100644
--- a/libs/hwui/CanvasState.cpp
+++ b/libs/hwui/CanvasState.cpp
@@ -202,17 +202,17 @@
 // Clip
 ///////////////////////////////////////////////////////////////////////////////
 
-bool CanvasState::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) {
+bool CanvasState::clipRect(float left, float top, float right, float bottom, SkClipOp op) {
     mSnapshot->clip(Rect(left, top, right, bottom), op);
     return !mSnapshot->clipIsEmpty();
 }
 
-bool CanvasState::clipPath(const SkPath* path, SkRegion::Op op) {
+bool CanvasState::clipPath(const SkPath* path, SkClipOp op) {
     mSnapshot->clipPath(*path, op);
     return !mSnapshot->clipIsEmpty();
 }
 
-bool CanvasState::clipRegion(const SkRegion* region, SkRegion::Op op) {
+bool CanvasState::clipRegion(const SkRegion* region, SkClipOp op) {
     mSnapshot->clipRegionTransformed(*region, op);
     return !mSnapshot->clipIsEmpty();
 }
@@ -225,7 +225,7 @@
     bool outlineIsRounded = MathUtils::isPositive(radius);
     if (!outlineIsRounded || currentTransform()->isSimple()) {
         // TODO: consider storing this rect separately, so that this can't be replaced with clip ops
-        clipRect(bounds.left, bounds.top, bounds.right, bounds.bottom, SkRegion::kIntersect_Op);
+        clipRect(bounds.left, bounds.top, bounds.right, bounds.bottom, kIntersect_SkClipOp);
     }
     if (outlineIsRounded) {
         setClippingRoundRect(allocator, bounds, radius, false);
diff --git a/libs/hwui/CanvasState.h b/libs/hwui/CanvasState.h
index 22c7e8a..a805597 100644
--- a/libs/hwui/CanvasState.h
+++ b/libs/hwui/CanvasState.h
@@ -18,6 +18,7 @@
 
 #include "Snapshot.h"
 
+#include <SkClipOp.h>
 #include <SkMatrix.h>
 #include <SkPath.h>
 #include <SkRegion.h>
@@ -121,9 +122,9 @@
 
     bool quickRejectConservative(float left, float top, float right, float bottom) const;
 
-    bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
-    bool clipPath(const SkPath* path, SkRegion::Op op);
-    bool clipRegion(const SkRegion* region, SkRegion::Op op);
+    bool clipRect(float left, float top, float right, float bottom, SkClipOp op);
+    bool clipPath(const SkPath* path, SkClipOp op);
+    bool clipRegion(const SkRegion* region, SkClipOp op);
 
     /**
      * Sets a "clipping outline", which is independent from the regular clip.
diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp
index 245db1d..5b683e0 100644
--- a/libs/hwui/FrameBuilder.cpp
+++ b/libs/hwui/FrameBuilder.cpp
@@ -120,7 +120,7 @@
     mCanvasState.save(SaveFlags::MatrixClip);
     mCanvasState.translate(tx, ty);
     mCanvasState.clipRect(clipRect.left, clipRect.top, clipRect.right, clipRect.bottom,
-            SkRegion::kIntersect_Op);
+            kIntersect_SkClipOp);
     deferNodePropsAndOps(renderNode);
     mCanvasState.restore();
 }
@@ -262,7 +262,7 @@
         Rect clipRect;
         properties.getClippingRectForFlags(clipFlags, &clipRect);
         mCanvasState.clipRect(clipRect.left, clipRect.top, clipRect.right, clipRect.bottom,
-                SkRegion::kIntersect_Op);
+                kIntersect_SkClipOp);
     }
 
     if (properties.getRevealClip().willClip()) {
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index 9d18484..96c6d29 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -234,13 +234,13 @@
     SkRect bounds = path.getBounds();
     return mState.quickRejectConservative(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
 }
-bool RecordingCanvas::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) {
+bool RecordingCanvas::clipRect(float left, float top, float right, float bottom, SkClipOp op) {
     return mState.clipRect(left, top, right, bottom, op);
 }
-bool RecordingCanvas::clipPath(const SkPath* path, SkRegion::Op op) {
+bool RecordingCanvas::clipPath(const SkPath* path, SkClipOp op) {
     return mState.clipPath(path, op);
 }
-bool RecordingCanvas::clipRegion(const SkRegion* region, SkRegion::Op op) {
+bool RecordingCanvas::clipRegion(const SkRegion* region, SkClipOp op) {
     return mState.clipRegion(region, op);
 }
 
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index f93e8b8..5d49385 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -131,9 +131,10 @@
     virtual bool quickRejectRect(float left, float top, float right, float bottom) const override;
     virtual bool quickRejectPath(const SkPath& path) const override;
 
-    virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op) override;
-    virtual bool clipPath(const SkPath* path, SkRegion::Op op) override;
-    virtual bool clipRegion(const SkRegion* region, SkRegion::Op op) override;
+    virtual bool clipRect(float left, float top, float right, float bottom,
+            SkClipOp op) override;
+    virtual bool clipPath(const SkPath* path, SkClipOp op) override;
+    virtual bool clipRegion(const SkRegion* region, SkClipOp op) override;
 
     // Misc
     virtual SkDrawFilter* getDrawFilter() override { return mDrawFilter.get(); }
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 6786a69..8ab57c9d 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -78,13 +78,13 @@
 public:
     explicit ClipCopier(SkCanvas* dstCanvas) : m_dstCanvas(dstCanvas) {}
 
-    virtual void clipRect(const SkRect& rect, SkRegion::Op op, bool antialias) {
+    virtual void clipRect(const SkRect& rect, SkClipOp op, bool antialias) {
         m_dstCanvas->clipRect(rect, op, antialias);
     }
-    virtual void clipRRect(const SkRRect& rrect, SkRegion::Op op, bool antialias) {
+    virtual void clipRRect(const SkRRect& rrect, SkClipOp op, bool antialias) {
         m_dstCanvas->clipRRect(rrect, op, antialias);
     }
-    virtual void clipPath(const SkPath& path, SkRegion::Op op, bool antialias) {
+    virtual void clipPath(const SkPath& path, SkClipOp op, bool antialias) {
         m_dstCanvas->clipPath(path, op, antialias);
     }
 
@@ -218,11 +218,11 @@
 
 class SkiaCanvas::Clip {
 public:
-    Clip(const SkRect& rect, SkRegion::Op op, const SkMatrix& m)
+    Clip(const SkRect& rect, SkClipOp op, const SkMatrix& m)
         : mType(Type::Rect), mOp(op), mMatrix(m), mRRect(SkRRect::MakeRect(rect)) {}
-    Clip(const SkRRect& rrect, SkRegion::Op op, const SkMatrix& m)
+    Clip(const SkRRect& rrect, SkClipOp op, const SkMatrix& m)
         : mType(Type::RRect), mOp(op), mMatrix(m), mRRect(rrect) {}
-    Clip(const SkPath& path, SkRegion::Op op, const SkMatrix& m)
+    Clip(const SkPath& path, SkClipOp op, const SkMatrix& m)
         : mType(Type::Path), mOp(op), mMatrix(m), mPath(&path) {}
 
     void apply(SkCanvas* canvas) const {
@@ -247,9 +247,9 @@
         Path,
     };
 
-    Type            mType;
-    SkRegion::Op    mOp;
-    SkMatrix        mMatrix;
+    Type        mType;
+    SkClipOp    mOp;
+    SkMatrix    mMatrix;
 
     // These are logically a union (tracked separately due to non-POD path).
     SkTLazy<SkPath> mPath;
@@ -293,7 +293,7 @@
 }
 
 template <typename T>
-void SkiaCanvas::recordClip(const T& clip, SkRegion::Op op) {
+void SkiaCanvas::recordClip(const T& clip, SkClipOp op) {
     // Only need tracking when in a partial save frame which
     // doesn't restore the clip.
     const SaveRec* rec = this->currentSaveRec();
@@ -397,14 +397,14 @@
     return mCanvas->quickReject(path);
 }
 
-bool SkiaCanvas::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) {
+bool SkiaCanvas::clipRect(float left, float top, float right, float bottom, SkClipOp op) {
     SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
     this->recordClip(rect, op);
     mCanvas->clipRect(rect, op);
     return !mCanvas->isClipEmpty();
 }
 
-bool SkiaCanvas::clipPath(const SkPath* path, SkRegion::Op op) {
+bool SkiaCanvas::clipPath(const SkPath* path, SkClipOp op) {
     SkRRect roundRect;
     if (path->isRRect(&roundRect)) {
         this->recordClip(roundRect, op);
@@ -416,7 +416,7 @@
     return !mCanvas->isClipEmpty();
 }
 
-bool SkiaCanvas::clipRegion(const SkRegion* region, SkRegion::Op op) {
+bool SkiaCanvas::clipRegion(const SkRegion* region, SkClipOp op) {
     SkPath rgnPath;
     if (region->getBoundaryPath(&rgnPath)) {
         // The region is specified in device space.
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index 4f1d857..9639ebd 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -92,9 +92,9 @@
     virtual bool quickRejectRect(float left, float top, float right, float bottom) const override;
     virtual bool quickRejectPath(const SkPath& path) const override;
     virtual bool clipRect(float left, float top, float right, float bottom,
-            SkRegion::Op op) override;
-    virtual bool clipPath(const SkPath* path, SkRegion::Op op) override;
-    virtual bool clipRegion(const SkRegion* region, SkRegion::Op op) override;
+            SkClipOp op) override;
+    virtual bool clipPath(const SkPath* path, SkClipOp op) override;
+    virtual bool clipRegion(const SkRegion* region, SkClipOp op) override;
 
     virtual SkDrawFilter* getDrawFilter() override;
     virtual void setDrawFilter(SkDrawFilter* drawFilter) override;
@@ -174,7 +174,7 @@
     void recordPartialSave(SaveFlags::Flags flags);
 
     template<typename T>
-    void recordClip(const T&, SkRegion::Op);
+    void recordClip(const T&, SkClipOp);
     void applyPersistentClips(size_t clipStartIndex);
 
     void drawPoints(const float* points, int count, const SkPaint& paint,
diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp
index 5978abc..75396f7 100644
--- a/libs/hwui/SkiaCanvasProxy.cpp
+++ b/libs/hwui/SkiaCanvasProxy.cpp
@@ -430,21 +430,21 @@
     }
 }
 
-void SkiaCanvasProxy::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle) {
+void SkiaCanvasProxy::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle) {
     mCanvas->clipRect(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, op);
 }
 
-void SkiaCanvasProxy::onClipRRect(const SkRRect& roundRect, SkRegion::Op op, ClipEdgeStyle) {
+void SkiaCanvasProxy::onClipRRect(const SkRRect& roundRect, SkClipOp op, ClipEdgeStyle) {
     SkPath path;
     path.addRRect(roundRect);
     mCanvas->clipPath(&path, op);
 }
 
-void SkiaCanvasProxy::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle) {
+void SkiaCanvasProxy::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle) {
     mCanvas->clipPath(&path, op);
 }
 
-void SkiaCanvasProxy::onClipRegion(const SkRegion& region, SkRegion::Op op) {
+void SkiaCanvasProxy::onClipRegion(const SkRegion& region, SkClipOp op) {
     mCanvas->clipRegion(&region, op);
 }
 
diff --git a/libs/hwui/SkiaCanvasProxy.h b/libs/hwui/SkiaCanvasProxy.h
index 0111815..badcc1d 100644
--- a/libs/hwui/SkiaCanvasProxy.h
+++ b/libs/hwui/SkiaCanvasProxy.h
@@ -90,10 +90,10 @@
                              const SkPoint texCoords[4], SkBlendMode,
                              const SkPaint& paint) override;
 
-    virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) override;
-    virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) override;
-    virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) override;
-    virtual void onClipRegion(const SkRegion&, SkRegion::Op) override;
+    virtual void onClipRect(const SkRect&, SkClipOp, ClipEdgeStyle) override;
+    virtual void onClipRRect(const SkRRect&, SkClipOp, ClipEdgeStyle) override;
+    virtual void onClipPath(const SkPath&, SkClipOp, ClipEdgeStyle) override;
+    virtual void onClipRegion(const SkRegion&, SkClipOp) override;
 
 private:
     Canvas* mCanvas;
diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp
index f61c3e9..3f08009 100644
--- a/libs/hwui/Snapshot.cpp
+++ b/libs/hwui/Snapshot.cpp
@@ -72,19 +72,19 @@
 // Clipping
 ///////////////////////////////////////////////////////////////////////////////
 
-void Snapshot::clipRegionTransformed(const SkRegion& region, SkRegion::Op op) {
+void Snapshot::clipRegionTransformed(const SkRegion& region, SkClipOp op) {
     flags |= Snapshot::kFlagClipSet;
-    mClipArea->clipRegion(region, op);
+    mClipArea->clipRegion(region, static_cast<SkRegion::Op>(op));
 }
 
-void Snapshot::clip(const Rect& localClip, SkRegion::Op op) {
+void Snapshot::clip(const Rect& localClip, SkClipOp op) {
     flags |= Snapshot::kFlagClipSet;
-    mClipArea->clipRectWithTransform(localClip, transform, op);
+    mClipArea->clipRectWithTransform(localClip, transform, static_cast<SkRegion::Op>(op));
 }
 
-void Snapshot::clipPath(const SkPath& path, SkRegion::Op op) {
+void Snapshot::clipPath(const SkPath& path, SkClipOp op) {
     flags |= Snapshot::kFlagClipSet;
-    mClipArea->clipPathWithTransform(path, transform, op);
+    mClipArea->clipPathWithTransform(path, transform, static_cast<SkRegion::Op>(op));
 }
 
 void Snapshot::setClip(float left, float top, float right, float bottom) {
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index 4ab5830..287e58a 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -23,6 +23,7 @@
 #include <utils/RefBase.h>
 #include <ui/Region.h>
 
+#include <SkClipOp.h>
 #include <SkRegion.h>
 
 #include "ClipArea.h"
@@ -107,25 +108,25 @@
      * the specified operation. The specified rectangle is transformed
      * by this snapshot's trasnformation.
      */
-    void clip(const Rect& localClip, SkRegion::Op op);
+    void clip(const Rect& localClip, SkClipOp op);
 
     /**
      * Modifies the current clip with the new clip rectangle and
      * the specified operation. The specified rectangle is considered
      * already transformed.
      */
-    void clipTransformed(const Rect& r, SkRegion::Op op = SkRegion::kIntersect_Op);
+    void clipTransformed(const Rect& r, SkClipOp op = kIntersect_SkClipOp);
 
     /**
      * Modifies the current clip with the specified region and operation.
      * The specified region is considered already transformed.
      */
-    void clipRegionTransformed(const SkRegion& region, SkRegion::Op op);
+    void clipRegionTransformed(const SkRegion& region, SkClipOp op);
 
     /**
      * Modifies the current clip with the specified path and operation.
      */
-    void clipPath(const SkPath& path, SkRegion::Op op);
+    void clipPath(const SkPath& path, SkClipOp op);
 
     /**
      * Sets the current clip.
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index f4ffa7a..208107f 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -308,7 +308,7 @@
 
 void ClipPath::drawPath(SkCanvas* outCanvas, SkPath& renderPath,
         float strokeScale, const SkMatrix& matrix, bool useStagingData){
-    outCanvas->clipPath(renderPath, SkRegion::kIntersect_Op);
+    outCanvas->clipPath(renderPath);
 }
 
 Group::Group(const Group& group) : Node(group) {
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index d7839b4..e7b6b2d 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -182,9 +182,9 @@
     virtual bool quickRejectPath(const SkPath& path) const = 0;
 
     virtual bool clipRect(float left, float top, float right, float bottom,
-            SkRegion::Op op = SkRegion::kIntersect_Op) = 0;
-    virtual bool clipPath(const SkPath* path, SkRegion::Op op) = 0;
-    virtual bool clipRegion(const SkRegion* region, SkRegion::Op op) = 0;
+            SkClipOp op) = 0;
+    virtual bool clipPath(const SkPath* path, SkClipOp op) = 0;
+    virtual bool clipRegion(const SkRegion* region, SkClipOp op) = 0;
 
     // filters
     virtual SkDrawFilter* getDrawFilter() = 0;
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
index 4b34c7c..14cc449 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -68,7 +68,7 @@
         if (pendingClip && !pendingClip->contains(rect)) {
             canvas->clipRect(*pendingClip);
         }
-        canvas->clipRRect(SkRRect::MakeRectXY(rect, radius, radius), SkRegion::kIntersect_Op, true);
+        canvas->clipRRect(SkRRect::MakeRectXY(rect, radius, radius), kIntersect_SkClipOp, true);
     } else {
         if (pendingClip) {
             (void)rect.intersect(*pendingClip);
@@ -263,7 +263,7 @@
     }
 
     if (properties.getRevealClip().willClip()) {
-        canvas->clipPath(*properties.getRevealClip().getPath(), SkRegion::kIntersect_Op, true);
+        canvas->clipPath(*properties.getRevealClip().getPath(), kIntersect_SkClipOp, true);
     } else if (properties.getOutline().willClip()) {
         clipOutline(properties.getOutline(), canvas, pendingClip);
         pendingClip = nullptr;
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 0f2d09d..42068f9 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -98,7 +98,7 @@
             int saveCount = layerCanvas->save();
             SkASSERT(saveCount == 1);
 
-            layerCanvas->clipRect(layerDamage.toSkRect(), SkRegion::kReplace_Op);
+            layerCanvas->clipRect(layerDamage.toSkRect(), kReplace_SkClipOp);
 
             auto savedLightCenter = mLightCenter;
             // map current light center into RenderNode's coordinate space
@@ -222,7 +222,7 @@
         const std::vector<sp<RenderNode>>& nodes, bool opaque, const Rect &contentDrawBounds,
         SkCanvas* canvas) {
 
-    canvas->clipRect(clip, SkRegion::kReplace_Op);
+    canvas->clipRect(clip, kReplace_SkClipOp);
 
     if (!opaque) {
         canvas->clear(SK_ColorTRANSPARENT);
@@ -272,7 +272,7 @@
             const float dy = backdropBounds.top - contentDrawBounds.top;
             canvas->translate(dx, dy);
             // It gets cropped against the bounds of the backdrop to stay inside.
-            canvas->clipRect(clip, SkRegion::kIntersect_Op);
+            canvas->clipRect(clip);
         }
 
         RenderNodeDrawable root(node.get(), canvas);
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index 0ce598d..363b94a 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -118,7 +118,8 @@
 
     static std::unique_ptr<Snapshot> makeSnapshot(const Matrix4& transform, const Rect& clip) {
         std::unique_ptr<Snapshot> snapshot(new Snapshot());
-        snapshot->clip(clip, SkRegion::kReplace_Op); // store clip first, so it isn't transformed
+        // store clip first, so it isn't transformed
+        snapshot->setClip(clip.left, clip.top, clip.right, clip.bottom);
         *(snapshot->transform) = transform;
         return snapshot;
     }
diff --git a/libs/hwui/tests/common/scenes/ClippingAnimation.cpp b/libs/hwui/tests/common/scenes/ClippingAnimation.cpp
index 8f2ba2d..45443b0 100644
--- a/libs/hwui/tests/common/scenes/ClippingAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/ClippingAnimation.cpp
@@ -34,11 +34,11 @@
                 [](RenderProperties& props, Canvas& canvas) {
             canvas.save(SaveFlags::MatrixClip);
             {
-                canvas.clipRect(0, 0, 200, 200, SkRegion::kIntersect_Op);
+                canvas.clipRect(0, 0, 200, 200, kIntersect_SkClipOp);
                 canvas.translate(100, 100);
                 canvas.rotate(45);
                 canvas.translate(-100, -100);
-                canvas.clipRect(0, 0, 200, 200, SkRegion::kIntersect_Op);
+                canvas.clipRect(0, 0, 200, 200, kIntersect_SkClipOp);
                 canvas.drawColor(Color::Blue_500, SkBlendMode::kSrcOver);
             }
             canvas.restore();
@@ -47,7 +47,7 @@
             {
                 SkPath clipCircle;
                 clipCircle.addCircle(100, 300, 100);
-                canvas.clipPath(&clipCircle, SkRegion::kIntersect_Op);
+                canvas.clipPath(&clipCircle, kIntersect_SkClipOp);
                 canvas.drawColor(Color::Red_500, SkBlendMode::kSrcOver);
             }
             canvas.restore();
diff --git a/libs/hwui/tests/common/scenes/SaveLayerAnimation.cpp b/libs/hwui/tests/common/scenes/SaveLayerAnimation.cpp
index 3630935..8b2852b 100644
--- a/libs/hwui/tests/common/scenes/SaveLayerAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/SaveLayerAnimation.cpp
@@ -36,7 +36,7 @@
             // nested clipped saveLayers
             canvas.saveLayerAlpha(0, 0, 400, 400, 200, SaveFlags::ClipToLayer);
             canvas.drawColor(Color::Green_700, SkBlendMode::kSrcOver);
-            canvas.clipRect(50, 50, 350, 350, SkRegion::kIntersect_Op);
+            canvas.clipRect(50, 50, 350, 350, kIntersect_SkClipOp);
             canvas.saveLayerAlpha(100, 100, 300, 300, 128, SaveFlags::ClipToLayer);
             canvas.drawColor(Color::Blue_500, SkBlendMode::kSrcOver);
             canvas.restore();
diff --git a/libs/hwui/tests/common/scenes/ShapeAnimation.cpp b/libs/hwui/tests/common/scenes/ShapeAnimation.cpp
index 5ef8773..d44c3d5 100644
--- a/libs/hwui/tests/common/scenes/ShapeAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/ShapeAnimation.cpp
@@ -82,7 +82,7 @@
                     int middleCount = canvas.save(SaveFlags::MatrixClip);
                     for (auto op : ops) {
                         int innerCount = canvas.save(SaveFlags::MatrixClip);
-                        canvas.clipRect(0, 0, cellSize, cellSize, SkRegion::kIntersect_Op);
+                        canvas.clipRect(0, 0, cellSize, cellSize, kIntersect_SkClipOp);
                         canvas.drawColor(Color::White, SkBlendMode::kSrcOver);
                         op(canvas, cellSize, paint);
                         canvas.restoreToCount(innerCount);
diff --git a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
index bbaf267..3ef0d1c 100644
--- a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
+++ b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
@@ -177,7 +177,7 @@
         // Clip to padding
         // Can expect ~25% of views to have clip to padding with a non-null padding
         int clipRestoreCount = canvas->save(SaveFlags::MatrixClip);
-        canvas->clipRect(1, 1, 199, 199, SkRegion::kIntersect_Op);
+        canvas->clipRect(1, 1, 199, 199, kIntersect_SkClipOp);
 
         canvas->insertReorderBarrier(true);
 
diff --git a/libs/hwui/tests/unit/CanvasStateTests.cpp b/libs/hwui/tests/unit/CanvasStateTests.cpp
index 0afabd8..7555fd4 100644
--- a/libs/hwui/tests/unit/CanvasStateTests.cpp
+++ b/libs/hwui/tests/unit/CanvasStateTests.cpp
@@ -23,7 +23,7 @@
 
 #include <gtest/gtest.h>
 #include <SkPath.h>
-#include <SkRegion.h>
+#include <SkClipOp.h>
 
 namespace android {
 namespace uirenderer {
@@ -68,13 +68,13 @@
     state.initializeSaveStack(200, 200,
             0, 0, 200, 200, Vector3());
 
-    state.clipRect(0, 0, 100, 100, SkRegion::kIntersect_Op);
+    state.clipRect(0, 0, 100, 100, kIntersect_SkClipOp);
     ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(100, 100));
 
-    state.clipRect(10, 10, 200, 200, SkRegion::kIntersect_Op);
+    state.clipRect(10, 10, 200, 200, kIntersect_SkClipOp);
     ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(10, 10, 100, 100));
 
-    state.clipRect(50, 50, 150, 150, SkRegion::kReplace_Op);
+    state.clipRect(50, 50, 150, 150, kReplace_SkClipOp);
     ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(50, 50, 150, 150));
 }
 
@@ -88,7 +88,7 @@
         // rotated clip causes complex clip
         state.rotate(10);
         EXPECT_TRUE(state.clipIsSimple());
-        state.clipRect(0, 0, 200, 200, SkRegion::kIntersect_Op);
+        state.clipRect(0, 0, 200, 200, kIntersect_SkClipOp);
         EXPECT_FALSE(state.clipIsSimple());
     }
     state.restore();
@@ -97,7 +97,7 @@
     {
         // subtracted clip causes complex clip
         EXPECT_TRUE(state.clipIsSimple());
-        state.clipRect(50, 50, 150, 150, SkRegion::kDifference_Op);
+        state.clipRect(50, 50, 150, 150, kDifference_SkClipOp);
         EXPECT_FALSE(state.clipIsSimple());
     }
     state.restore();
@@ -108,7 +108,7 @@
         SkPath path;
         path.addOval(SkRect::MakeWH(200, 200));
         EXPECT_TRUE(state.clipIsSimple());
-        state.clipPath(&path, SkRegion::kDifference_Op);
+        state.clipPath(&path, kDifference_SkClipOp);
         EXPECT_FALSE(state.clipIsSimple());
     }
     state.restore();
@@ -121,7 +121,7 @@
 
     state.save(SaveFlags::Clip);
     {
-        state.clipRect(0, 0, 10, 10, SkRegion::kIntersect_Op);
+        state.clipRect(0, 0, 10, 10, kIntersect_SkClipOp);
         ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(10, 10));
     }
     state.restore();
@@ -145,7 +145,7 @@
 
     state.save(SaveFlags::Matrix); // NOTE: clip not saved
     {
-        state.clipRect(0, 0, 10, 10, SkRegion::kIntersect_Op);
+        state.clipRect(0, 0, 10, 10, kIntersect_SkClipOp);
         ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(10, 10));
     }
     state.restore();
diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp
index a1c225f..12622ff 100644
--- a/libs/hwui/tests/unit/FrameBuilderTests.cpp
+++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp
@@ -174,7 +174,7 @@
     auto node = TestUtils::createNode<RecordingCanvas>(0, 0, 200, 200,
             [](RenderProperties& props, RecordingCanvas& canvas) {
         canvas.save(SaveFlags::MatrixClip);
-        canvas.clipRect(200, 200, 400, 400, SkRegion::kIntersect_Op); // intersection should be empty
+        canvas.clipRect(200, 200, 400, 400, kIntersect_SkClipOp); // intersection should be empty
         canvas.drawRect(0, 0, 400, 400, SkPaint());
         canvas.restore();
     });
@@ -453,19 +453,19 @@
         sk_sp<Bitmap> bitmap(TestUtils::createBitmap(20, 20));
 
         // left side clipped (to inset left half)
-        canvas.clipRect(10, 0, 50, 100, SkRegion::kReplace_Op);
+        canvas.clipRect(10, 0, 50, 100, kReplace_SkClipOp);
         canvas.drawBitmap(*bitmap, 0, 40, nullptr);
 
         // top side clipped (to inset top half)
-        canvas.clipRect(0, 10, 100, 50, SkRegion::kReplace_Op);
+        canvas.clipRect(0, 10, 100, 50, kReplace_SkClipOp);
         canvas.drawBitmap(*bitmap, 40, 0, nullptr);
 
         // right side clipped (to inset right half)
-        canvas.clipRect(50, 0, 90, 100, SkRegion::kReplace_Op);
+        canvas.clipRect(50, 0, 90, 100, kReplace_SkClipOp);
         canvas.drawBitmap(*bitmap, 80, 40, nullptr);
 
         // bottom not clipped, just abutting (inset bottom half)
-        canvas.clipRect(0, 50, 100, 90, SkRegion::kReplace_Op);
+        canvas.clipRect(0, 50, 100, 90, kReplace_SkClipOp);
         canvas.drawBitmap(*bitmap, 40, 70, nullptr);
     });
 
@@ -488,7 +488,7 @@
         SkPath path;
         path.addCircle(200, 200, 200, SkPath::kCW_Direction);
         canvas.save(SaveFlags::MatrixClip);
-        canvas.clipPath(&path, SkRegion::kIntersect_Op);
+        canvas.clipPath(&path, kIntersect_SkClipOp);
         SkPaint paint;
         paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
         paint.setAntiAlias(true);
@@ -649,7 +649,7 @@
     auto node = TestUtils::createNode<RecordingCanvas>(0, 0, 200, 200,
             [&layerUpdater](RenderProperties& props, RecordingCanvas& canvas) {
         canvas.save(SaveFlags::MatrixClip);
-        canvas.clipRect(50, 50, 150, 150, SkRegion::kIntersect_Op);
+        canvas.clipRect(50, 50, 150, 150, kIntersect_SkClipOp);
         canvas.drawLayer(layerUpdater.get());
         canvas.restore();
     });
@@ -973,7 +973,7 @@
         auto node = TestUtils::createNode<RecordingCanvas>(0, 0, 200, 200,
                 [](RenderProperties& props, RecordingCanvas& canvas) {
         canvas.save(SaveFlags::MatrixClip);
-        canvas.clipRect(200, 200, 400, 400, SkRegion::kIntersect_Op);
+        canvas.clipRect(200, 200, 400, 400, kIntersect_SkClipOp);
         canvas.saveLayerAlpha(200, 200, 400, 400, 128, SaveFlags::ClipToLayer);
 
         // draw within save layer may still be recorded, but shouldn't be drawn
@@ -1781,7 +1781,7 @@
     auto child = TestUtils::createNode<RecordingCanvas>(0, 0, 400, 400,
             [&projectingRipple](RenderProperties& properties, RecordingCanvas& canvas) {
         // Record time clip will be ignored by projectee
-        canvas.clipRect(100, 100, 300, 300, SkRegion::kIntersect_Op);
+        canvas.clipRect(100, 100, 300, 300, kIntersect_SkClipOp);
 
         canvas.translate(-scrollX, -scrollY); // Apply scroll (note: bg undoes this internally)
         canvas.drawRenderNode(projectingRipple.get());
@@ -1993,7 +1993,7 @@
             [](RenderProperties& props, RecordingCanvas& canvas) {
         // Apply a clip before the reorder barrier/shadow casting child is drawn.
         // This clip must be applied to the shadow cast by the child.
-        canvas.clipRect(25, 25, 75, 75, SkRegion::kIntersect_Op);
+        canvas.clipRect(25, 25, 75, 75, kIntersect_SkClipOp);
         canvas.insertReorderBarrier(true);
         canvas.drawRenderNode(createWhiteRectShadowCaster(5.0f).get());
     });
@@ -2252,7 +2252,7 @@
     };
     auto node = TestUtils::createNode<RecordingCanvas>(20, 20, 30, 30,
             [](RenderProperties& props, RecordingCanvas& canvas) {
-        canvas.clipRect(0, -20, 10, 30, SkRegion::kReplace_Op);
+        canvas.clipRect(0, -20, 10, 30, kReplace_SkClipOp);
         canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
     });
 
diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
index dda432e..14fa5d6 100644
--- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp
+++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
@@ -57,7 +57,7 @@
 TEST(RecordingCanvas, clipRect) {
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 100, [](RecordingCanvas& canvas) {
         canvas.save(SaveFlags::MatrixClip);
-        canvas.clipRect(0, 0, 100, 100, SkRegion::kIntersect_Op);
+        canvas.clipRect(0, 0, 100, 100, kIntersect_SkClipOp);
         canvas.drawRect(0, 0, 50, 50, SkPaint());
         canvas.drawRect(50, 50, 100, 100, SkPaint());
         canvas.restore();
@@ -73,8 +73,8 @@
 TEST(RecordingCanvas, emptyClipRect) {
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
         canvas.save(SaveFlags::MatrixClip);
-        canvas.clipRect(0, 0, 100, 100, SkRegion::kIntersect_Op);
-        canvas.clipRect(100, 100, 200, 200, SkRegion::kIntersect_Op);
+        canvas.clipRect(0, 0, 100, 100, kIntersect_SkClipOp);
+        canvas.clipRect(100, 100, 200, 200, kIntersect_SkClipOp);
         canvas.drawRect(0, 0, 50, 50, SkPaint()); // rejected at record time
         canvas.restore();
     });
@@ -440,7 +440,7 @@
 TEST(RecordingCanvas, saveLayer_addClipFlag) {
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
         canvas.save(SaveFlags::MatrixClip);
-        canvas.clipRect(10, 20, 190, 180, SkRegion::kIntersect_Op);
+        canvas.clipRect(10, 20, 190, 180, kIntersect_SkClipOp);
         canvas.saveLayerAlpha(10, 20, 190, 180, 128, (SaveFlags::Flags)0); // unclipped
         canvas.drawRect(10, 20, 190, 180, SkPaint());
         canvas.restore();
@@ -459,7 +459,7 @@
 TEST(RecordingCanvas, saveLayer_viewportCrop) {
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
         // shouldn't matter, since saveLayer will clip to its bounds
-        canvas.clipRect(-1000, -1000, 1000, 1000, SkRegion::kReplace_Op);
+        canvas.clipRect(-1000, -1000, 1000, 1000, kReplace_SkClipOp);
 
         canvas.saveLayerAlpha(100, 100, 300, 300, 128, SaveFlags::ClipToLayer);
         canvas.drawRect(0, 0, 400, 400, SkPaint());
@@ -549,7 +549,7 @@
         canvas.save(SaveFlags::MatrixClip);
         canvas.translate(0, -20); // avoid identity case
         // empty clip rect should force layer + contents to be rejected
-        canvas.clipRect(0, -20, 200, -20, SkRegion::kIntersect_Op);
+        canvas.clipRect(0, -20, 200, -20, kIntersect_SkClipOp);
         canvas.saveLayerAlpha(0, 0, 200, 200, 128, SaveFlags::ClipToLayer);
         canvas.drawRect(0, 0, 200, 200, SkPaint());
         canvas.restore();
@@ -568,7 +568,7 @@
     });
 
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [&child](RecordingCanvas& canvas) {
-        canvas.clipRect(0, 0, 0, 0, SkRegion::kIntersect_Op); // empty clip, reject node
+        canvas.clipRect(0, 0, 0, 0, kIntersect_SkClipOp); // empty clip, reject node
         canvas.drawRenderNode(child.get()); // shouldn't crash when rejecting node...
     });
     ASSERT_TRUE(dl->isEmpty());
@@ -621,7 +621,7 @@
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
         canvas.save(SaveFlags::MatrixClip);
         // since no explicit clip set on canvas, this should be the one observed on op:
-        canvas.clipRect(-100, -100, 300, 300, SkRegion::kIntersect_Op);
+        canvas.clipRect(-100, -100, 300, 300, kIntersect_SkClipOp);
 
         SkPaint paint;
         paint.setColor(SK_ColorWHITE);
@@ -637,7 +637,7 @@
 TEST(RecordingCanvas, replaceClipIntersectWithRoot) {
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 100, [](RecordingCanvas& canvas) {
         canvas.save(SaveFlags::MatrixClip);
-        canvas.clipRect(-10, -10, 110, 110, SkRegion::kReplace_Op);
+        canvas.clipRect(-10, -10, 110, 110, kReplace_SkClipOp);
         canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
         canvas.restore();
     });
@@ -675,7 +675,7 @@
         canvas.drawRect(0, 0, 400, 400, SkPaint());
 
         // second chunk: no recorded clip, since inorder region
-        canvas.clipRect(0, 0, 200, 200, SkRegion::kIntersect_Op);
+        canvas.clipRect(0, 0, 200, 200, kIntersect_SkClipOp);
         canvas.insertReorderBarrier(false);
         canvas.drawRect(0, 0, 400, 400, SkPaint());
 
diff --git a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
index f4b686d..7c14952 100644
--- a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
+++ b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
@@ -469,7 +469,7 @@
     auto child = TestUtils::createSkiaNode(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
             [&projectingRipple](RenderProperties& properties, SkiaRecordingCanvas& canvas) {
         // Record time clip will be ignored by projectee
-        canvas.clipRect(100, 100, 300, 300, SkRegion::kIntersect_Op);
+        canvas.clipRect(100, 100, 300, 300, kIntersect_SkClipOp);
 
         canvas.translate(-SCROLL_X, -SCROLL_Y); // Apply scroll (note: bg undoes this internally)
         canvas.drawRenderNode(projectingRipple.get());
diff --git a/libs/hwui/utils/TestWindowContext.cpp b/libs/hwui/utils/TestWindowContext.cpp
index fa3e13d..598cd1e 100644
--- a/libs/hwui/utils/TestWindowContext.cpp
+++ b/libs/hwui/utils/TestWindowContext.cpp
@@ -93,8 +93,7 @@
 
     SkCanvas* prepareToDraw() {
         //mCanvas->reset(mSize.width(), mSize.height());
-        mCanvas->clipRect(0, 0, mSize.width(), mSize.height(),
-                               SkRegion::Op::kReplace_Op);
+        mCanvas->clipRect(0, 0, mSize.width(), mSize.height(), kReplace_SkClipOp);
         return mCanvas->asSkCanvas();
     }