Remove SK_SUPPORT_DEPRECATED_CLIPOPS and expanding clip op defs

Bug: skia:10209
Change-Id: I72639b7e768742dcdec810a5a714ce21ff0f6e0a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/436565
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt
index de4fe08..b17bf01 100644
--- a/RELEASE_NOTES.txt
+++ b/RELEASE_NOTES.txt
@@ -10,6 +10,9 @@
     expanding clip ops guarded by SK_SUPPORT_DEPRECATED_CLIPOPS.
     https://review.skia.org/430897
 
+  * Removed SK_SUPPORT_DEPRECATED_CLIPOPS build flag. Clips can only be intersect and difference.
+    https://review.skia.org/436565
+
 * * *
 
 Milestone 93
diff --git a/include/core/SkClipOp.h b/include/core/SkClipOp.h
index 98a0c66..3da6c61 100644
--- a/include/core/SkClipOp.h
+++ b/include/core/SkClipOp.h
@@ -13,26 +13,7 @@
 enum class SkClipOp {
     kDifference    = 0,
     kIntersect     = 1,
-
-#ifdef SK_SUPPORT_DEPRECATED_CLIPOPS
-    kUnion_deprecated             = 2,
-    kXOR_deprecated               = 3,
-    kReverseDifference_deprecated = 4,
-    kReplace_deprecated           = 5,
-
-    // Used internally for validation, can only shrink to 1 when the deprecated flag is gone
-    kMax_EnumValue = 5,
-#else
-    // Technically only kDifference and kIntersect are allowed, hence kMax_EnumValue = 1, but
-    // internally we need these values defined for the deprecated clip ops.
-    kExtraEnumNeedInternallyPleaseIgnoreWillGoAway2   = 2,
-    kExtraEnumNeedInternallyPleaseIgnoreWillGoAway3   = 3,
-    kExtraEnumNeedInternallyPleaseIgnoreWillGoAway4   = 4,
-    kExtraEnumNeedInternallyPleaseIgnoreWillGoAway5   = 5,
-
-    kMax_EnumValue = 1
-#endif
-
+    kMax_EnumValue = kIntersect
 };
 
 #endif
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 18147ed..0e1f609 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -24,7 +24,6 @@
 #include "src/core/SkArenaAlloc.h"
 #include "src/core/SkBitmapDevice.h"
 #include "src/core/SkCanvasPriv.h"
-#include "src/core/SkClipOpPriv.h"
 #include "src/core/SkClipStack.h"
 #include "src/core/SkColorFilterBase.h"
 #include "src/core/SkDraw.h"
@@ -2638,12 +2637,8 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static_assert((int)SkRegion::kDifference_Op         == (int)kDifference_SkClipOp, "");
-static_assert((int)SkRegion::kIntersect_Op          == (int)kIntersect_SkClipOp, "");
-static_assert((int)SkRegion::kUnion_Op              == (int)kUnion_SkClipOp, "");
-static_assert((int)SkRegion::kXOR_Op                == (int)kXOR_SkClipOp, "");
-static_assert((int)SkRegion::kReverseDifference_Op  == (int)kReverseDifference_SkClipOp, "");
-static_assert((int)SkRegion::kReplace_Op            == (int)kReplace_SkClipOp, "");
+static_assert((int)SkRegion::kDifference_Op == (int)SkClipOp::kDifference, "");
+static_assert((int)SkRegion::kIntersect_Op  == (int)SkClipOp::kIntersect, "");
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/core/SkClipOpPriv.h b/src/core/SkClipOpPriv.h
deleted file mode 100644
index 02c8ffa..0000000
--- a/src/core/SkClipOpPriv.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkClipOpPriv_DEFINED
-#define SkClipOpPriv_DEFINED
-
-#include "include/core/SkClipOp.h"
-
-const SkClipOp kDifference_SkClipOp         = SkClipOp::kDifference;
-const SkClipOp kIntersect_SkClipOp          = SkClipOp::kIntersect;
-
-const SkClipOp kUnion_SkClipOp              = (SkClipOp)2;
-const SkClipOp kXOR_SkClipOp                = (SkClipOp)3;
-const SkClipOp kReverseDifference_SkClipOp  = (SkClipOp)4;
-const SkClipOp kReplace_SkClipOp            = (SkClipOp)5;
-
-#endif
diff --git a/src/core/SkClipStack.cpp b/src/core/SkClipStack.cpp
index a4afb87..d53b34f 100644
--- a/src/core/SkClipStack.cpp
+++ b/src/core/SkClipStack.cpp
@@ -7,7 +7,6 @@
 
 #include "include/core/SkCanvas.h"
 #include "include/core/SkPath.h"
-#include "src/core/SkClipOpPriv.h"
 #include "src/core/SkClipStack.h"
 #include "src/core/SkRectPriv.h"
 #include "src/shaders/SkShaderBase.h"
@@ -387,68 +386,6 @@
     }
 }
 
-void SkClipStack::Element::combineBoundsXOR(int combination, const SkRect& prevFinite) {
-
-    switch (combination) {
-        case kInvPrev_Cur_FillCombo:       // fall through
-        case kPrev_InvCur_FillCombo:
-            // With only one of the clips inverted the result will always
-            // extend to infinity. The only pixels that may be un-writeable
-            // lie within the union of the two finite bounds
-            fFiniteBound.join(prevFinite);
-            fFiniteBoundType = kInsideOut_BoundsType;
-            break;
-        case kInvPrev_InvCur_FillCombo:
-            // The only pixels that can survive are within the
-            // union of the two bounding boxes since the extensions
-            // to infinity of both clips cancel out
-            [[fallthrough]];
-        case kPrev_Cur_FillCombo:
-            // The most conservative bound for xor is the
-            // union of the two bounds. If the two clips exactly overlapped
-            // the xor could yield the empty set. Similarly the xor
-            // could reduce the size of the original clip's bound (e.g.,
-            // if the second clip exactly matched the bottom half of the
-            // first clip). We ignore these two cases.
-            fFiniteBound.join(prevFinite);
-            fFiniteBoundType = kNormal_BoundsType;
-            break;
-        default:
-            SkDEBUGFAIL("SkClipStack::Element::combineBoundsXOR Invalid fill combination");
-            break;
-    }
-}
-
-// a mirror of combineBoundsIntersection
-void SkClipStack::Element::combineBoundsUnion(int combination, const SkRect& prevFinite) {
-
-    switch (combination) {
-        case kInvPrev_InvCur_FillCombo:
-            if (!fFiniteBound.intersect(prevFinite)) {
-                fFiniteBound.setEmpty();
-                fGenID = kWideOpenGenID;
-            }
-            fFiniteBoundType = kInsideOut_BoundsType;
-            break;
-        case kInvPrev_Cur_FillCombo:
-            // The only pixels that won't be drawable are inside
-            // the prior clip's finite bound
-            fFiniteBound = prevFinite;
-            fFiniteBoundType = kInsideOut_BoundsType;
-            break;
-        case kPrev_InvCur_FillCombo:
-            // The only pixels that won't be drawable are inside
-            // this clip's finite bound
-            break;
-        case kPrev_Cur_FillCombo:
-            fFiniteBound.join(prevFinite);
-            break;
-        default:
-            SkDEBUGFAIL("SkClipStack::Element::combineBoundsUnion Invalid fill combination");
-            break;
-    }
-}
-
 // a mirror of combineBoundsUnion
 void SkClipStack::Element::combineBoundsIntersection(int combination, const SkRect& prevFinite) {
 
@@ -480,41 +417,6 @@
     }
 }
 
-// a mirror of combineBoundsDiff
-void SkClipStack::Element::combineBoundsRevDiff(int combination, const SkRect& prevFinite) {
-
-    switch (combination) {
-        case kInvPrev_InvCur_FillCombo:
-            // The only pixels that can survive are in the
-            // previous bound since the extensions to infinity in
-            // both clips cancel out
-            fFiniteBound = prevFinite;
-            fFiniteBoundType = kNormal_BoundsType;
-            break;
-        case kInvPrev_Cur_FillCombo:
-            if (!fFiniteBound.intersect(prevFinite)) {
-                this->setEmpty();
-            } else {
-                fFiniteBoundType = kNormal_BoundsType;
-            }
-            break;
-        case kPrev_InvCur_FillCombo:
-            fFiniteBound.join(prevFinite);
-            fFiniteBoundType = kInsideOut_BoundsType;
-            break;
-        case kPrev_Cur_FillCombo:
-            // Fall through - as with the kDifference_Op case, the
-            // most conservative result bound is the bound of the
-            // current clip. The prior clip could reduce the size of this
-            // bound (as in the kDifference_Op case) but we are ignoring
-            // those cases.
-            break;
-        default:
-            SkDEBUGFAIL("SkClipStack::Element::combineBoundsRevDiff Invalid fill combination");
-            break;
-    }
-}
-
 void SkClipStack::Element::updateBoundAndGenID(const Element* prior) {
     // We set this first here but we may overwrite it later if we determine that the clip is
     // either wide-open or empty.
@@ -594,18 +496,9 @@
             case SkClipOp::kDifference:
                 this->combineBoundsDiff(combination, prevFinite);
                 break;
-            case kXOR_SkClipOp:
-                this->combineBoundsXOR(combination, prevFinite);
-                break;
-            case kUnion_SkClipOp:
-                this->combineBoundsUnion(combination, prevFinite);
-                break;
             case SkClipOp::kIntersect:
                 this->combineBoundsIntersection(combination, prevFinite);
                 break;
-            case kReverseDifference_SkClipOp:
-                this->combineBoundsRevDiff(combination, prevFinite);
-                break;
             default:
                 SkDebugf("SkClipOp error\n");
                 SkASSERT(0);
@@ -860,32 +753,17 @@
 void SkClipStack::clipRRect(const SkRRect& rrect, const SkMatrix& matrix, SkClipOp op, bool doAA) {
     Element element(fSaveCount, rrect, matrix, op, doAA);
     this->pushElement(element);
-    if (this->hasClipRestriction(op)) {
-        Element restriction(fSaveCount, fClipRestrictionRect, SkMatrix::I(), SkClipOp::kIntersect,
-                            false);
-        this->pushElement(restriction);
-    }
 }
 
 void SkClipStack::clipRect(const SkRect& rect, const SkMatrix& matrix, SkClipOp op, bool doAA) {
     Element element(fSaveCount, rect, matrix, op, doAA);
     this->pushElement(element);
-    if (this->hasClipRestriction(op)) {
-        Element restriction(fSaveCount, fClipRestrictionRect, SkMatrix::I(), SkClipOp::kIntersect,
-                            false);
-        this->pushElement(restriction);
-    }
 }
 
 void SkClipStack::clipPath(const SkPath& path, const SkMatrix& matrix, SkClipOp op,
                            bool doAA) {
     Element element(fSaveCount, path, matrix, op, doAA);
     this->pushElement(element);
-    if (this->hasClipRestriction(op)) {
-        Element restriction(fSaveCount, fClipRestrictionRect, SkMatrix::I(), SkClipOp::kIntersect,
-                            false);
-        this->pushElement(restriction);
-    }
 }
 
 void SkClipStack::clipShader(sk_sp<SkShader> shader) {
@@ -1105,23 +983,8 @@
     static_assert(4 == static_cast<int>(DeviceSpaceType::kShader), "enum mismatch");
     static_assert(SK_ARRAY_COUNT(kTypeStrings) == kTypeCnt, "enum mismatch");
 
-    static const char* kOpStrings[] = {
-        "difference",
-        "intersect",
-        "union",
-        "xor",
-        "reverse-difference",
-        "replace",
-    };
-    static_assert(0 == static_cast<int>(kDifference_SkClipOp), "enum mismatch");
-    static_assert(1 == static_cast<int>(kIntersect_SkClipOp), "enum mismatch");
-    static_assert(2 == static_cast<int>(kUnion_SkClipOp), "enum mismatch");
-    static_assert(3 == static_cast<int>(kXOR_SkClipOp), "enum mismatch");
-    static_assert(4 == static_cast<int>(kReverseDifference_SkClipOp), "enum mismatch");
-    static_assert(5 == static_cast<int>(kReplace_SkClipOp), "enum mismatch");
-    static_assert(SK_ARRAY_COUNT(kOpStrings) == SkRegion::kOpCnt, "enum mismatch");
-
-    const char* opName = this->isReplaceOp() ? "replace" : kOpStrings[static_cast<int>(fOp)];
+    const char* opName = this->isReplaceOp() ? "replace" :
+            (fOp == SkClipOp::kDifference ? "difference" : "intersect");
     SkDebugf("Type: %s, Op: %s, AA: %s, Save Count: %d\n", kTypeStrings[(int)fDeviceSpaceType],
              opName, (fDoAA ? "yes" : "no"), fSaveCount);
     switch (fDeviceSpaceType) {
diff --git a/src/core/SkClipStack.h b/src/core/SkClipStack.h
index 4067ee6..888ce6b 100644
--- a/src/core/SkClipStack.h
+++ b/src/core/SkClipStack.h
@@ -15,7 +15,6 @@
 #include "include/core/SkRegion.h"
 #include "include/core/SkShader.h"
 #include "include/private/SkDeque.h"
-#include "src/core/SkClipOpPriv.h"
 #include "src/core/SkMessageBus.h"
 #include "src/core/SkTLazy.h"
 
@@ -134,9 +133,9 @@
 
         //!< Call if getDeviceSpaceType() is not kEmpty to get the set operation used to combine
         //!< this element.
-        SkClipOp getOp() const { return fOp == kReplace_SkClipOp ? SkClipOp::kIntersect : fOp; }
+        SkClipOp getOp() const { return fOp; }
         // Augments getOps()'s behavior by requiring a clip reset before the op is applied.
-        bool isReplaceOp() const { return fIsReplace || fOp == kReplace_SkClipOp; }
+        bool isReplaceOp() const { return fIsReplace; }
 
         SkRegion::Op getRegionOp() const {
             return this->isReplaceOp() ? SkRegion::kReplace_Op : (SkRegion::Op) fOp;
@@ -312,10 +311,7 @@
         };
         // per-set operation functions used by updateBoundAndGenID().
         inline void combineBoundsDiff(FillCombo combination, const SkRect& prevFinite);
-        inline void combineBoundsXOR(int combination, const SkRect& prevFinite);
-        inline void combineBoundsUnion(int combination, const SkRect& prevFinite);
         inline void combineBoundsIntersection(int combination, const SkRect& prevFinite);
-        inline void combineBoundsRevDiff(int combination, const SkRect& prevFinite);
     };
 
     SkClipStack();
@@ -551,10 +547,6 @@
      */
     void restoreTo(int saveCount);
 
-    inline bool hasClipRestriction(SkClipOp op) {
-        return op >= kUnion_SkClipOp && !fClipRestrictionRect.isEmpty();
-    }
-
     /**
      * Return the next unique generation ID.
      */
diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h
index 3e5cea4..9b54ea7 100644
--- a/src/core/SkPictureFlat.h
+++ b/src/core/SkPictureFlat.h
@@ -153,22 +153,22 @@
 // clipparams are packed in 5 bits
 //  doAA:1 | clipOp:4
 
+// Newly serialized pictures will only write kIntersect or kDifference.
 static inline uint32_t ClipParams_pack(SkClipOp op, bool doAA) {
     unsigned doAABit = doAA ? 1 : 0;
     return (doAABit << 4) | static_cast<int>(op);
 }
 
-template <typename T> T asValidEnum(SkReadBuffer* buffer, uint32_t candidate) {
-
-    if (buffer->validate(candidate <= static_cast<uint32_t>(T::kMax_EnumValue))) {
-        return static_cast<T>(candidate);
+// But old SKPs may have been serialized with the SK_SUPPORT_DEPRECATED_CLIPOP flag, so might
+// encounter expanding clip ops. Thus, this returns the clip op as the more general Region::Op.
+static inline SkRegion::Op ClipParams_unpackRegionOp(SkReadBuffer* buffer, uint32_t packed) {
+    uint32_t unpacked = packed & 0xF;
+    if (buffer->validate(unpacked <= SkRegion::kIntersect_Op ||
+                         (unpacked <= SkRegion::kReplace_Op &&
+                                buffer->isVersionLT(SkPicturePriv::kNoExpandingClipOps)))) {
+        return static_cast<SkRegion::Op>(unpacked);
     }
-
-    return T::kMax_EnumValue;
-}
-
-static inline SkClipOp ClipParams_unpackRegionOp(SkReadBuffer* buffer, uint32_t packed) {
-    return asValidEnum<SkClipOp>(buffer, packed & 0xF);
+    return SkRegion::kIntersect_Op;
 }
 
 static inline bool ClipParams_unpackDoAA(uint32_t packed) {
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index 9341183..425f937 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -79,6 +79,27 @@
     }
 }
 
+static bool do_clip_op(SkReadBuffer* reader, SkCanvas* canvas, SkRegion::Op op,
+                       SkClipOp* clipOpToUse) {
+    switch(op) {
+        case SkRegion::kDifference_Op:
+        case SkRegion::kIntersect_Op:
+            // Fully supported, identity mapping between SkClipOp and Region::Op
+            *clipOpToUse = static_cast<SkClipOp>(op);
+            return true;
+        case SkRegion::kReplace_Op:
+            // Emulate the replace by resetting first and following it up with an intersect
+            SkASSERT(reader->isVersionLT(SkPicturePriv::kNoExpandingClipOps));
+            SkCanvasPriv::ResetClip(canvas);
+            *clipOpToUse = SkClipOp::kIntersect;
+            return true;
+        default:
+            // An expanding clip op, which if encountered on an old SKP, we just silently ignore
+            SkASSERT(reader->isVersionLT(SkPicturePriv::kNoExpandingClipOps));
+            return false;
+    }
+}
+
 void SkPicturePlayback::handleOp(SkReadBuffer* reader,
                                  DrawType op,
                                  uint32_t size,
@@ -97,13 +118,16 @@
         case CLIP_PATH: {
             const SkPath& path = fPictureData->getPath(reader);
             uint32_t packed = reader->readInt();
-            SkClipOp clipOp = ClipParams_unpackRegionOp(reader, packed);
+            SkRegion::Op rgnOp = ClipParams_unpackRegionOp(reader, packed);
             bool doAA = ClipParams_unpackDoAA(packed);
             size_t offsetToRestore = reader->readInt();
             validate_offsetToRestore(reader, offsetToRestore);
             BREAK_ON_READ_ERROR(reader);
 
-            canvas->clipPath(path, clipOp, doAA);
+            SkClipOp clipOp;
+            if (do_clip_op(reader, canvas, rgnOp, &clipOp)) {
+                canvas->clipPath(path, clipOp, doAA);
+            }
             if (canvas->isClipEmpty() && offsetToRestore) {
                 reader->skip(offsetToRestore - reader->offset());
             }
@@ -112,12 +136,15 @@
             SkRegion region;
             reader->readRegion(&region);
             uint32_t packed = reader->readInt();
-            SkClipOp clipOp = ClipParams_unpackRegionOp(reader, packed);
+            SkRegion::Op rgnOp = ClipParams_unpackRegionOp(reader, packed);
             size_t offsetToRestore = reader->readInt();
             validate_offsetToRestore(reader, offsetToRestore);
             BREAK_ON_READ_ERROR(reader);
 
-            canvas->clipRegion(region, clipOp);
+            SkClipOp clipOp;
+            if (do_clip_op(reader, canvas, rgnOp, &clipOp)) {
+                canvas->clipRegion(region, clipOp);
+            }
             if (canvas->isClipEmpty() && offsetToRestore) {
                 reader->skip(offsetToRestore - reader->offset());
             }
@@ -126,13 +153,16 @@
             SkRect rect;
             reader->readRect(&rect);
             uint32_t packed = reader->readInt();
-            SkClipOp clipOp = ClipParams_unpackRegionOp(reader, packed);
+            SkRegion::Op rgnOp = ClipParams_unpackRegionOp(reader, packed);
             bool doAA = ClipParams_unpackDoAA(packed);
             size_t offsetToRestore = reader->readInt();
             validate_offsetToRestore(reader, offsetToRestore);
             BREAK_ON_READ_ERROR(reader);
 
-            canvas->clipRect(rect, clipOp, doAA);
+            SkClipOp clipOp;
+            if (do_clip_op(reader, canvas, rgnOp, &clipOp)) {
+                canvas->clipRect(rect, clipOp, doAA);
+            }
             if (canvas->isClipEmpty() && offsetToRestore) {
                 reader->skip(offsetToRestore - reader->offset());
             }
@@ -141,25 +171,33 @@
             SkRRect rrect;
             reader->readRRect(&rrect);
             uint32_t packed = reader->readInt();
-            SkClipOp clipOp = ClipParams_unpackRegionOp(reader, packed);
+            SkRegion::Op rgnOp = ClipParams_unpackRegionOp(reader, packed);
             bool doAA = ClipParams_unpackDoAA(packed);
             size_t offsetToRestore = reader->readInt();
             validate_offsetToRestore(reader, offsetToRestore);
             BREAK_ON_READ_ERROR(reader);
 
-            canvas->clipRRect(rrect, clipOp, doAA);
+            SkClipOp clipOp;
+            if (do_clip_op(reader, canvas, rgnOp, &clipOp)) {
+                canvas->clipRRect(rrect, clipOp, doAA);
+            }
             if (canvas->isClipEmpty() && offsetToRestore) {
                 reader->skip(offsetToRestore - reader->offset());
             }
         } break;
         case CLIP_SHADER_IN_PAINT: {
             const SkPaint& paint = fPictureData->requiredPaint(reader);
+            // clipShader() was never used in conjunction with deprecated, expanding clip ops, so
+            // it requires the op to just be intersect or difference.
             SkClipOp clipOp = reader->checkRange(SkClipOp::kDifference, SkClipOp::kIntersect);
             BREAK_ON_READ_ERROR(reader);
 
             canvas->clipShader(paint.refShader(), clipOp);
         } break;
         case RESET_CLIP:
+            // For Android, an emulated "replace" clip op appears as a manual reset followed by
+            // an intersect operation (equivalent to the above handling of replace ops encountered
+            // in old serialized pictures).
             SkCanvasPriv::ResetClip(canvas);
             break;
         case PUSH_CULL: break;  // Deprecated, safe to ignore both push and pop.
diff --git a/src/core/SkPicturePriv.h b/src/core/SkPicturePriv.h
index 657f2fe..29cfe4d 100644
--- a/src/core/SkPicturePriv.h
+++ b/src/core/SkPicturePriv.h
@@ -98,6 +98,7 @@
     // V86: Remove support for custom data inside SkVertices
     // V87: SkPaint now holds a user-defined blend function (SkBlender), no longer has DrawLooper
     // V88: Add blender to ComposeShader and BlendImageFilter
+    // V89: Deprecated SkClipOps are no longer supported
 
     enum Version {
         kPictureShaderFilterParam_Version   = 82,
@@ -107,10 +108,11 @@
         kVerticesRemoveCustomData_Version   = 86,
         kSkBlenderInSkPaint                 = 87,
         kBlenderInEffects                   = 88,
+        kNoExpandingClipOps                 = 89,
 
         // Only SKPs within the min/current picture version range (inclusive) can be read.
         kMin_Version     = kPictureShaderFilterParam_Version,
-        kCurrent_Version = kBlenderInEffects
+        kCurrent_Version = kNoExpandingClipOps
     };
 };
 
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index 5918138..52363b1 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -12,7 +12,6 @@
 #include "include/core/SkTextBlob.h"
 #include "include/private/SkTo.h"
 #include "src/core/SkCanvasPriv.h"
-#include "src/core/SkClipOpPriv.h"
 #include "src/core/SkDrawShadowInfo.h"
 #include "src/core/SkMatrixPriv.h"
 #include "src/core/SkSamplingPriv.h"
@@ -254,22 +253,6 @@
     this->validate(initialOffset, size);
 }
 
-static bool clipOpExpands(SkClipOp op) {
-    switch (op) {
-        case kUnion_SkClipOp:
-        case kXOR_SkClipOp:
-        case kReverseDifference_SkClipOp:
-        case kReplace_SkClipOp:
-            return true;
-        case kIntersect_SkClipOp:
-        case kDifference_SkClipOp:
-            return false;
-        default:
-            SkDEBUGFAIL("unknown clipop");
-            return false;
-    }
-}
-
 void SkPictureRecord::fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t restoreOffset) {
     int32_t offset = fRestoreOffsetStack.top();
     while (offset > 0) {
@@ -301,7 +284,7 @@
     this->restoreToCount(fInitialSaveCount);
 }
 
-size_t SkPictureRecord::recordRestoreOffsetPlaceholder(SkClipOp op) {
+size_t SkPictureRecord::recordRestoreOffsetPlaceholder() {
     if (fRestoreOffsetStack.isEmpty()) {
         return -1;
     }
@@ -313,18 +296,6 @@
     // restore command is recorded.
     int32_t prevOffset = fRestoreOffsetStack.top();
 
-    if (clipOpExpands(op)) {
-        // Run back through any previous clip ops, and mark their offset to
-        // be 0, disabling their ability to trigger a jump-to-restore, otherwise
-        // they could hide this clips ability to expand the clip (i.e. go from
-        // empty to non-empty).
-        this->fillRestoreOffsetPlaceholdersForCurrentStackLevel(0);
-
-        // Reset the pointer back to the previous clip so that subsequent
-        // restores don't overwrite the offsets we just cleared.
-        prevOffset = 0;
-    }
-
     size_t offset = fWriter.bytesWritten();
     this->addInt(prevOffset);
     fRestoreOffsetStack.top() = SkToU32(offset);
@@ -347,7 +318,7 @@
     size_t initialOffset = this->addDraw(CLIP_RECT, &size);
     this->addRect(rect);
     this->addInt(ClipParams_pack(op, doAA));
-    size_t offset = this->recordRestoreOffsetPlaceholder(op);
+    size_t offset = this->recordRestoreOffsetPlaceholder();
 
     this->validate(initialOffset, size);
     return offset;
@@ -369,7 +340,7 @@
     size_t initialOffset = this->addDraw(CLIP_RRECT, &size);
     this->addRRect(rrect);
     this->addInt(ClipParams_pack(op, doAA));
-    size_t offset = recordRestoreOffsetPlaceholder(op);
+    size_t offset = recordRestoreOffsetPlaceholder();
     this->validate(initialOffset, size);
     return offset;
 }
@@ -391,7 +362,7 @@
     size_t initialOffset = this->addDraw(CLIP_PATH, &size);
     this->addInt(pathID);
     this->addInt(ClipParams_pack(op, doAA));
-    size_t offset = recordRestoreOffsetPlaceholder(op);
+    size_t offset = recordRestoreOffsetPlaceholder();
     this->validate(initialOffset, size);
     return offset;
 }
@@ -428,13 +399,19 @@
     size_t initialOffset = this->addDraw(CLIP_REGION, &size);
     this->addRegion(region);
     this->addInt(ClipParams_pack(op, false));
-    size_t offset = this->recordRestoreOffsetPlaceholder(op);
+    size_t offset = this->recordRestoreOffsetPlaceholder();
 
     this->validate(initialOffset, size);
     return offset;
 }
 
 void SkPictureRecord::onResetClip() {
+    if (!fRestoreOffsetStack.isEmpty()) {
+        // Run back through any previous clip ops, and mark their offset to
+        // be 0, disabling their ability to trigger a jump-to-restore, otherwise
+        // they could hide this expansion of the clip.
+        this->fillRestoreOffsetPlaceholdersForCurrentStackLevel(0);
+    }
     size_t size = sizeof(kUInt32Size);
     size_t initialOffset = this->addDraw(RESET_CLIP, &size);
     this->validate(initialOffset, size);
diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h
index b40fc44..89362c3 100644
--- a/src/core/SkPictureRecord.h
+++ b/src/core/SkPictureRecord.h
@@ -80,7 +80,7 @@
 
 private:
     void handleOptimization(int opt);
-    size_t recordRestoreOffsetPlaceholder(SkClipOp);
+    size_t recordRestoreOffsetPlaceholder();
     void fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t restoreOffset);
 
     SkTDArray<int32_t> fRestoreOffsetStack;
diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp
index e9fe59e..855f0a7 100644
--- a/src/gpu/GrClipStackClip.cpp
+++ b/src/gpu/GrClipStackClip.cpp
@@ -9,7 +9,6 @@
 
 #include "include/gpu/GrDirectContext.h"
 #include "include/private/SkTo.h"
-#include "src/core/SkClipOpPriv.h"
 #include "src/core/SkTaskGroup.h"
 #include "src/core/SkTraceEvent.h"
 #include "src/gpu/GrAppliedClip.h"
@@ -338,7 +337,7 @@
         SkRegion::Op op = element->getRegionOp();
         GrAA aa = GrAA(element->isAA());
 
-        if (SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op) {
+        if (SkRegion::kIntersect_Op == op) {
             // Intersect and reverse difference require modifying pixels outside of the geometry
             // that is being "drawn". In both cases we erase all the pixels outside of the geometry
             // but leave the pixels inside the geometry alone. For reverse difference we invert all
diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp
index 8ccdd2f..a7f9f2f 100644
--- a/src/gpu/GrReducedClip.cpp
+++ b/src/gpu/GrReducedClip.cpp
@@ -5,7 +5,6 @@
  * found in the LICENSE file.
  */
 
-#include "src/core/SkClipOpPriv.h"
 #include "src/gpu/GrAppliedClip.h"
 #include "src/gpu/GrClip.h"
 #include "src/gpu/GrColor.h"
@@ -188,7 +187,6 @@
         }
 
         bool skippable = false;
-        bool isFlip = false; // does this op just flip the in/out state of every point in the bounds
 
         switch (element->getRegionOp()) {
             case SkRegion::kDifference_Op:
@@ -260,76 +258,6 @@
                     emsmallens = true;
                 }
                 break;
-            case SkRegion::kUnion_Op:
-                // If the union-ed shape contains the entire bounds then after this element
-                // the bounds is entirely inside the clip. If the union-ed shape is outside the
-                // bounds then this op can be skipped.
-                if (element->isInverseFilled()) {
-                    if (element->contains(relaxedQueryBounds)) {
-                        skippable = true;
-                    } else if (GrClip::IsOutsideClip(element->getBounds(), queryBounds)) {
-                        initialTriState = InitialTriState::kAllIn;
-                        skippable = true;
-                    }
-                } else {
-                    if (element->contains(relaxedQueryBounds)) {
-                        initialTriState = InitialTriState::kAllIn;
-                        skippable = true;
-                    } else if (GrClip::IsOutsideClip(element->getBounds(), queryBounds)) {
-                        skippable = true;
-                    }
-                }
-                if (!skippable) {
-                    embiggens = true;
-                }
-                break;
-            case SkRegion::kXOR_Op:
-                // If the bounds is entirely inside the shape being xor-ed then the effect is
-                // to flip the inside/outside state of every point in the bounds. We may be
-                // able to take advantage of this in the forward pass. If the xor-ed shape
-                // doesn't intersect the bounds then it can be skipped.
-                if (element->isInverseFilled()) {
-                    if (element->contains(relaxedQueryBounds)) {
-                        skippable = true;
-                    } else if (GrClip::IsOutsideClip(element->getBounds(), queryBounds)) {
-                        isFlip = true;
-                    }
-                } else {
-                    if (element->contains(relaxedQueryBounds)) {
-                        isFlip = true;
-                    } else if (GrClip::IsOutsideClip(element->getBounds(), queryBounds)) {
-                        skippable = true;
-                    }
-                }
-                if (!skippable) {
-                    emsmallens = embiggens = true;
-                }
-                break;
-            case SkRegion::kReverseDifference_Op:
-                // When the bounds is entirely within the rev-diff shape then this behaves like xor
-                // and reverses every point inside the bounds. If the shape is completely outside
-                // the bounds then we know after this element is applied that the bounds will be
-                // all outside the current clip.B
-                if (element->isInverseFilled()) {
-                    if (element->contains(relaxedQueryBounds)) {
-                        initialTriState = InitialTriState::kAllOut;
-                        skippable = true;
-                    } else if (GrClip::IsOutsideClip(element->getBounds(), queryBounds)) {
-                        isFlip = true;
-                    }
-                } else {
-                    if (element->contains(relaxedQueryBounds)) {
-                        isFlip = true;
-                    } else if (GrClip::IsOutsideClip(element->getBounds(), queryBounds)) {
-                        initialTriState = InitialTriState::kAllOut;
-                        skippable = true;
-                    }
-                }
-                if (!skippable) {
-                    emsmallens = embiggens = true;
-                }
-                break;
-
             case SkRegion::kReplace_Op:
                 // Replace will always terminate our walk. We will either begin the forward walk
                 // at the replace op or detect here than the shape is either completely inside
@@ -385,29 +313,21 @@
                 fMaskGenID = element->getGenID();
             }
 
-            // if it is a flip, change it to a bounds-filling rect
-            if (isFlip) {
-                SkASSERT(kXOR_SkClipOp == element->getOp() ||
-                         kReverseDifference_SkClipOp == element->getOp());
-                fMaskElements.addToHead(SkRect::Make(fScissor), SkMatrix::I(),
-                                        kReverseDifference_SkClipOp, false);
-            } else {
-                Element* newElement = fMaskElements.addToHead(*element);
-                if (newElement->isAA()) {
-                    ++numAAElements;
-                }
-                // Intersecting an inverse shape is the same as differencing the non-inverse shape.
-                // Replacing with an inverse shape is the same as setting initialState=kAllIn and
-                // differencing the non-inverse shape.
-                bool isReplace = newElement->isReplaceOp();
-                if (newElement->isInverseFilled() &&
-                    (SkClipOp::kIntersect == newElement->getOp() || isReplace)) {
-                    newElement->invertShapeFillType();
-                    newElement->setOp(SkClipOp::kDifference);
-                    if (isReplace) {
-                        SkASSERT(InitialTriState::kAllOut == initialTriState);
-                        initialTriState = InitialTriState::kAllIn;
-                    }
+            Element* newElement = fMaskElements.addToHead(*element);
+            if (newElement->isAA()) {
+                ++numAAElements;
+            }
+            // Intersecting an inverse shape is the same as differencing the non-inverse shape.
+            // Replacing with an inverse shape is the same as setting initialState=kAllIn and
+            // differencing the non-inverse shape.
+            bool isReplace = newElement->isReplaceOp();
+            if (newElement->isInverseFilled() &&
+                (SkClipOp::kIntersect == newElement->getOp() || isReplace)) {
+                newElement->invertShapeFillType();
+                newElement->setOp(SkClipOp::kDifference);
+                if (isReplace) {
+                    SkASSERT(InitialTriState::kAllOut == initialTriState);
+                    initialTriState = InitialTriState::kAllIn;
                 }
             }
         }
@@ -421,60 +341,28 @@
         Element* element = fMaskElements.headIter().get();
         while (element) {
             bool skippable = false;
-            switch (element->getRegionOp()) {
-                case SkRegion::kDifference_Op:
-                    // subtracting from the empty set yields the empty set.
-                    skippable = InitialTriState::kAllOut == initialTriState;
-                    break;
-                case SkRegion::kIntersect_Op:
-                    // intersecting with the empty set yields the empty set
-                    if (InitialTriState::kAllOut == initialTriState) {
-                        skippable = true;
-                    } else {
-                        // We can clear to zero and then simply draw the clip element.
-                        initialTriState = InitialTriState::kAllOut;
-                        element->setReplaceOp();
-                    }
-                    break;
-                case SkRegion::kUnion_Op:
-                    if (InitialTriState::kAllIn == initialTriState) {
-                        // unioning the infinite plane with anything is a no-op.
-                        skippable = true;
-                    } else {
-                        // unioning the empty set with a shape is the shape.
-                        element->setReplaceOp();
-                    }
-                    break;
-                case SkRegion::kXOR_Op:
-                    if (InitialTriState::kAllOut == initialTriState) {
-                        // xor could be changed to diff in the kAllIn case, not sure it's a win.
-                        element->setReplaceOp();
-                    }
-                    break;
-                case SkRegion::kReverseDifference_Op:
-                    if (InitialTriState::kAllIn == initialTriState) {
-                        // subtracting the whole plane will yield the empty set.
-                        skippable = true;
-                        initialTriState = InitialTriState::kAllOut;
-                    } else {
-                        // this picks up flips inserted in the backwards pass.
-                        skippable = element->isInverseFilled() ?
-                            GrClip::IsOutsideClip(element->getBounds(), queryBounds) :
-                            element->contains(relaxedQueryBounds);
-                        if (skippable) {
-                            initialTriState = InitialTriState::kAllIn;
+            // Only check non-replace ops since we would have skipped the replace on backwards walk
+            // if we could have.
+            if (!element->isReplaceOp()) {
+                switch (element->getOp()) {
+                    case SkClipOp::kDifference:
+                        // subtracting from the empty set yields the empty set.
+                        skippable = InitialTriState::kAllOut == initialTriState;
+                        break;
+                    case SkClipOp::kIntersect:
+                        // intersecting with the empty set yields the empty set
+                        if (InitialTriState::kAllOut == initialTriState) {
+                            skippable = true;
                         } else {
+                            // We can clear to zero and then simply draw the clip element.
+                            initialTriState = InitialTriState::kAllOut;
                             element->setReplaceOp();
                         }
-                    }
-                    break;
-                case SkRegion::kReplace_Op:
-                    skippable = false; // we would have skipped it in the backwards walk if we
-                                       // could've.
-                    break;
-                default:
-                    SkDEBUGFAIL("Unexpected op.");
-                    break;
+                        break;
+                    default:
+                        SkDEBUGFAIL("Unexpected op.");
+                        break;
+                }
             }
             if (!skippable) {
                 break;
diff --git a/tests/ClipStackTest.cpp b/tests/ClipStackTest.cpp
index 9c2c887..2fee14f 100644
--- a/tests/ClipStackTest.cpp
+++ b/tests/ClipStackTest.cpp
@@ -26,7 +26,6 @@
 #include "include/private/GrResourceKey.h"
 #include "include/private/SkTemplates.h"
 #include "include/utils/SkRandom.h"
-#include "src/core/SkClipOpPriv.h"
 #include "src/core/SkClipStack.h"
 #include "src/core/SkTLList.h"
 #include "src/gpu/GrClip.h"
@@ -217,43 +216,28 @@
 // Exercise the SkClipStack's getConservativeBounds computation
 static void test_bounds(skiatest::Reporter* reporter,
                         SkClipStack::Element::DeviceSpaceType primType) {
-    static const int gNumCases = 20;
+    static const int gNumCases = 8;
     static const SkRect gAnswerRectsBW[gNumCases] = {
         // A op B
         { 40, 40, 50, 50 },
         { 10, 10, 50, 50 },
-        { 10, 10, 80, 80 },
-        { 10, 10, 80, 80 },
-        { 40, 40, 80, 80 },
 
         // invA op B
         { 40, 40, 80, 80 },
         { 0, 0, 100, 100 },
-        { 0, 0, 100, 100 },
-        { 0, 0, 100, 100 },
-        { 40, 40, 50, 50 },
 
         // A op invB
         { 10, 10, 50, 50 },
         { 40, 40, 50, 50 },
-        { 0, 0, 100, 100 },
-        { 0, 0, 100, 100 },
-        { 0, 0, 100, 100 },
 
         // invA op invB
         { 0, 0, 100, 100 },
         { 40, 40, 80, 80 },
-        { 0, 0, 100, 100 },
-        { 10, 10, 80, 80 },
-        { 10, 10, 50, 50 },
     };
 
     static const SkClipOp gOps[] = {
         SkClipOp::kIntersect,
-        SkClipOp::kDifference,
-        kUnion_SkClipOp,
-        kXOR_SkClipOp,
-        kReverseDifference_SkClipOp
+        SkClipOp::kDifference
     };
 
     SkRect rectA, rectB;
@@ -351,35 +335,6 @@
         REPORTER_ASSERT(reporter, SkClipStack::kWideOpenGenID == stack.getTopmostGenID());
     }
 
-    // Test out case where the user specifies a union that includes everything
-    {
-        SkClipStack stack;
-
-        SkPath clipA, clipB;
-
-        clipA.addRoundRect(rectA, SkIntToScalar(5), SkIntToScalar(5));
-        clipA.setFillType(SkPathFillType::kInverseEvenOdd);
-
-        clipB.addRoundRect(rectB, SkIntToScalar(5), SkIntToScalar(5));
-        clipB.setFillType(SkPathFillType::kInverseEvenOdd);
-
-        stack.clipPath(clipA, SkMatrix::I(), SkClipOp::kIntersect, false);
-        stack.clipPath(clipB, SkMatrix::I(), kUnion_SkClipOp, false);
-
-        REPORTER_ASSERT(reporter, stack.isWideOpen());
-        REPORTER_ASSERT(reporter, SkClipStack::kWideOpenGenID == stack.getTopmostGenID());
-    }
-
-    // Test out union w/ a wide open clip
-    {
-        SkClipStack stack;
-
-        stack.clipRect(rectA, SkMatrix::I(), kUnion_SkClipOp, false);
-
-        REPORTER_ASSERT(reporter, stack.isWideOpen());
-        REPORTER_ASSERT(reporter, SkClipStack::kWideOpenGenID == stack.getTopmostGenID());
-    }
-
     // Test out empty difference from a wide open clip
     {
         SkClipStack stack;
@@ -985,9 +940,6 @@
     static const SkClipOp kOps[] = {
         SkClipOp::kDifference,
         SkClipOp::kIntersect,
-        kUnion_SkClipOp,
-        kXOR_SkClipOp,
-        kReverseDifference_SkClipOp,
     };
 
     // We want to test inverse fills. However, they are quite rare in practice so don't over do it.
@@ -1120,121 +1072,6 @@
     #define SUPPRESS_VISIBILITY_WARNING __attribute__((visibility("hidden")))
 #endif
 
-static void test_reduced_clip_stack_genid(skiatest::Reporter* reporter) {
-    {
-        SkClipStack stack;
-        stack.replaceClip(SkRect::MakeXYWH(0, 0, 100, 100), true);
-        stack.replaceClip(SkRect::MakeXYWH(0, 0, 50.3f, 50.3f), true);
-        SkRect bounds = SkRect::MakeXYWH(0, 0, 100, 100);
-
-        sk_sp<GrDirectContext> context = GrDirectContext::MakeMock(nullptr);
-        const GrCaps* caps = context->priv().caps();
-
-        SkAlignedSTStorage<1, GrReducedClip> storage;
-        memset(storage.get(), 0, sizeof(GrReducedClip));
-        static_assert(0 == SkClipStack::kInvalidGenID);
-        const GrReducedClip* reduced = new (storage.get()) GrReducedClip(stack, bounds, caps);
-
-        REPORTER_ASSERT(reporter, reduced->maskElements().count() == 1);
-        // Clips will be cached based on the generation id. Make sure the gen id is valid.
-        REPORTER_ASSERT(reporter, SkClipStack::kInvalidGenID != reduced->maskGenID());
-
-        reduced->~GrReducedClip();
-    }
-    {
-        SkClipStack stack;
-
-        // Create a clip with following 25.3, 25.3 boxes which are 25 apart:
-        //  A  B
-        //  C  D
-
-        stack.replaceClip(SkRect::MakeXYWH(0, 0, 25.3f, 25.3f), true);
-        uint32_t genIDA = stack.getTopmostGenID();
-        stack.clipRect(SkRect::MakeXYWH(50, 0, SkScalar(25.3), SkScalar(25.3)), SkMatrix::I(),
-                       kUnion_SkClipOp, true);
-        uint32_t genIDB = stack.getTopmostGenID();
-        stack.clipRect(SkRect::MakeXYWH(0, 50, SkScalar(25.3), SkScalar(25.3)), SkMatrix::I(),
-                       kUnion_SkClipOp, true);
-        uint32_t genIDC = stack.getTopmostGenID();
-        stack.clipRect(SkRect::MakeXYWH(50, 50, SkScalar(25.3), SkScalar(25.3)), SkMatrix::I(),
-                       kUnion_SkClipOp, true);
-        uint32_t genIDD = stack.getTopmostGenID();
-
-
-#define IXYWH SkIRect::MakeXYWH
-#define XYWH SkRect::MakeXYWH
-
-        SkIRect stackBounds = IXYWH(0, 0, 76, 76);
-
-        // The base test is to test each rect in two ways:
-        // 1) The box dimensions. (Should reduce to "all in", no elements).
-        // 2) A bit over the box dimensions.
-        // In the case 2, test that the generation id is what is expected.
-        // The rects are of fractional size so that case 2 never gets optimized to an empty element
-        // list.
-
-        // Not passing in tighter bounds is tested for consistency.
-        static const struct SUPPRESS_VISIBILITY_WARNING {
-            SkRect testBounds;
-            int reducedClipCount;
-            uint32_t reducedGenID;
-            InitialState initialState;
-            SkIRect clipIRect;
-            // parameter.
-        } testCases[] = {
-
-            // Rect A.
-            { XYWH(0, 0, 25, 25), 0, SkClipStack::kInvalidGenID, GrReducedClip::InitialState::kAllIn, IXYWH(0, 0, 25, 25) },
-            { XYWH(0.1f, 0.1f, 25.1f, 25.1f), 0, SkClipStack::kInvalidGenID, GrReducedClip::InitialState::kAllIn, IXYWH(0, 0, 26, 26) },
-            { XYWH(0, 0, 27, 27), 1, genIDA, GrReducedClip::InitialState::kAllOut, IXYWH(0, 0, 26, 26)},
-
-            // Rect B.
-            { XYWH(50, 0, 25, 25), 0, SkClipStack::kInvalidGenID, GrReducedClip::InitialState::kAllIn, IXYWH(50, 0, 25, 25) },
-            { XYWH(50, 0, 25.3f, 25.3f), 0, SkClipStack::kInvalidGenID, GrReducedClip::InitialState::kAllIn, IXYWH(50, 0, 26, 26) },
-            { XYWH(50, 0, 27, 27), 1, genIDB, GrReducedClip::InitialState::kAllOut, IXYWH(50, 0, 26, 27) },
-
-            // Rect C.
-            { XYWH(0, 50, 25, 25), 0, SkClipStack::kInvalidGenID, GrReducedClip::InitialState::kAllIn, IXYWH(0, 50, 25, 25) },
-            { XYWH(0.2f, 50.1f, 25.1f, 25.2f), 0, SkClipStack::kInvalidGenID, GrReducedClip::InitialState::kAllIn, IXYWH(0, 50, 26, 26) },
-            { XYWH(0, 50, 27, 27), 1, genIDC, GrReducedClip::InitialState::kAllOut, IXYWH(0, 50, 27, 26) },
-
-            // Rect D.
-            { XYWH(50, 50, 25, 25), 0, SkClipStack::kInvalidGenID, GrReducedClip::InitialState::kAllIn, IXYWH(50, 50, 25, 25)},
-            { XYWH(50.3f, 50.3f, 25, 25), 0, SkClipStack::kInvalidGenID, GrReducedClip::InitialState::kAllIn, IXYWH(50, 50, 26, 26)},
-            { XYWH(50, 50, 27, 27), 1, genIDD, GrReducedClip::InitialState::kAllOut,  IXYWH(50, 50, 26, 26)},
-
-            // Other tests:
-            { XYWH(0, 0, 100, 100), 4, genIDD, GrReducedClip::InitialState::kAllOut, stackBounds },
-
-            // Rect in the middle, touches none (so should not be drawn)
-            { XYWH(26, 26, 24, 24), 0, SkClipStack::kInvalidGenID, GrReducedClip::InitialState::kAllOut, SkIRect::MakeEmpty() },
-
-            // Rect in the middle, touches all the rects. GenID is the last rect.
-            { XYWH(24, 24, 27, 27), 4, genIDD, GrReducedClip::InitialState::kAllOut, IXYWH(24, 24, 27, 27) },
-        };
-
-#undef XYWH
-#undef IXYWH
-        sk_sp<GrDirectContext> context = GrDirectContext::MakeMock(nullptr);
-        const GrCaps* caps = context->priv().caps();
-
-        for (size_t i = 0; i < SK_ARRAY_COUNT(testCases); ++i) {
-            const GrReducedClip reduced(stack, testCases[i].testBounds, caps);
-            REPORTER_ASSERT(reporter, reduced.maskElements().count() ==
-                            testCases[i].reducedClipCount);
-            if (reduced.maskElements().count()) {
-                REPORTER_ASSERT(reporter, reduced.maskGenID() == testCases[i].reducedGenID);
-            }
-            REPORTER_ASSERT(reporter, reduced.initialState() == testCases[i].initialState);
-
-            bool expectsScissor = !testCases[i].clipIRect.isEmpty();
-            REPORTER_ASSERT(reporter, expectsScissor == reduced.hasScissor());
-            if (expectsScissor) {
-                REPORTER_ASSERT(reporter, reduced.scissor() == testCases[i].clipIRect);
-            }
-        }
-    }
-}
 static void test_reduced_clip_stack_no_aa_crash(skiatest::Reporter* reporter) {
     SkClipStack stack;
     stack.clipDevRect(SkIRect::MakeXYWH(0, 0, 100, 100), SkClipOp::kIntersect);
@@ -1526,7 +1363,6 @@
 #if SK_GPU_V1
     test_reduced_clip_stack(reporter, /* clipShader */ false);
     test_reduced_clip_stack(reporter, /* clipShader */ true);
-    test_reduced_clip_stack_genid(reporter);
     test_reduced_clip_stack_no_aa_crash(reporter);
     test_reduced_clip_stack_aa(reporter);
     test_tiny_query_bounds_assertion_bug(reporter);
diff --git a/tools/debugger/DrawCommand.cpp b/tools/debugger/DrawCommand.cpp
index e638d6f..74f0e81 100644
--- a/tools/debugger/DrawCommand.cpp
+++ b/tools/debugger/DrawCommand.cpp
@@ -20,7 +20,6 @@
 #include "include/private/SkTHash.h"
 #include "src/core/SkAutoMalloc.h"
 #include "src/core/SkCanvasPriv.h"
-#include "src/core/SkClipOpPriv.h"
 #include "src/core/SkLatticeIter.h"
 #include "src/core/SkMaskFilterBase.h"
 #include "src/core/SkPaintDefaults.h"
@@ -150,12 +149,8 @@
 #define DEBUGCANVAS_POINTMODE_LINES "lines"
 #define DEBUGCANVAS_POINTMODE_POLYGON "polygon"
 
-#define DEBUGCANVAS_REGIONOP_DIFFERENCE "difference"
-#define DEBUGCANVAS_REGIONOP_INTERSECT "intersect"
-#define DEBUGCANVAS_REGIONOP_UNION "union"
-#define DEBUGCANVAS_REGIONOP_XOR "xor"
-#define DEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE "reverseDifference"
-#define DEBUGCANVAS_REGIONOP_REPLACE "replace"
+#define DEBUGCANVAS_CLIPOP_DIFFERENCE "difference"
+#define DEBUGCANVAS_CLIPOP_INTERSECT "intersect"
 
 #define DEBUGCANVAS_BLURSTYLE_NORMAL "normal"
 #define DEBUGCANVAS_BLURSTYLE_SOLID "solid"
@@ -567,14 +562,10 @@
     MakeJsonPath(writer, path);
 }
 
-static const char* regionop_name(SkClipOp op) {
+static const char* clipop_name(SkClipOp op) {
     switch (op) {
-        case kDifference_SkClipOp: return DEBUGCANVAS_REGIONOP_DIFFERENCE;
-        case kIntersect_SkClipOp: return DEBUGCANVAS_REGIONOP_INTERSECT;
-        case kUnion_SkClipOp: return DEBUGCANVAS_REGIONOP_UNION;
-        case kXOR_SkClipOp: return DEBUGCANVAS_REGIONOP_XOR;
-        case kReverseDifference_SkClipOp: return DEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE;
-        case kReplace_SkClipOp: return DEBUGCANVAS_REGIONOP_REPLACE;
+        case SkClipOp::kDifference: return DEBUGCANVAS_CLIPOP_DIFFERENCE;
+        case SkClipOp::kIntersect: return DEBUGCANVAS_CLIPOP_INTERSECT;
         default: SkASSERT(false); return "<invalid region op>";
     }
 }
@@ -1013,7 +1004,7 @@
     INHERITED::toJSON(writer, urlDataManager);
     writer.appendName(DEBUGCANVAS_ATTRIBUTE_PATH);
     MakeJsonPath(writer, fPath);
-    writer.appendString(DEBUGCANVAS_ATTRIBUTE_REGIONOP, regionop_name(fOp));
+    writer.appendString(DEBUGCANVAS_ATTRIBUTE_REGIONOP, clipop_name(fOp));
     writer.appendBool(DEBUGCANVAS_ATTRIBUTE_ANTIALIAS, fDoAA);
 }
 
@@ -1029,7 +1020,7 @@
     INHERITED::toJSON(writer, urlDataManager);
     writer.appendName(DEBUGCANVAS_ATTRIBUTE_REGION);
     MakeJsonRegion(writer, fRegion);
-    writer.appendString(DEBUGCANVAS_ATTRIBUTE_REGIONOP, regionop_name(fOp));
+    writer.appendString(DEBUGCANVAS_ATTRIBUTE_REGIONOP, clipop_name(fOp));
 }
 
 ClipRectCommand::ClipRectCommand(const SkRect& rect, SkClipOp op, bool doAA)
@@ -1045,7 +1036,7 @@
     INHERITED::toJSON(writer, urlDataManager);
     writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
     MakeJsonRect(writer, fRect);
-    writer.appendString(DEBUGCANVAS_ATTRIBUTE_REGIONOP, regionop_name(fOp));
+    writer.appendString(DEBUGCANVAS_ATTRIBUTE_REGIONOP, clipop_name(fOp));
     writer.appendBool(DEBUGCANVAS_ATTRIBUTE_ANTIALIAS, fDoAA);
 
     SkString desc;
@@ -1070,7 +1061,7 @@
     INHERITED::toJSON(writer, urlDataManager);
     writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
     make_json_rrect(writer, fRRect);
-    writer.appendString(DEBUGCANVAS_ATTRIBUTE_REGIONOP, regionop_name(fOp));
+    writer.appendString(DEBUGCANVAS_ATTRIBUTE_REGIONOP, clipop_name(fOp));
     writer.appendBool(DEBUGCANVAS_ATTRIBUTE_ANTIALIAS, fDoAA);
 }
 
@@ -1092,7 +1083,7 @@
 void ClipShaderCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
     INHERITED::toJSON(writer, urlDataManager);
     apply_flattenable(DEBUGCANVAS_ATTRIBUTE_SHADER, fShader.get(), writer, urlDataManager);
-    writer.appendString(DEBUGCANVAS_ATTRIBUTE_REGIONOP, regionop_name(fOp));
+    writer.appendString(DEBUGCANVAS_ATTRIBUTE_REGIONOP, clipop_name(fOp));
 }
 
 ResetClipCommand::ResetClipCommand() : INHERITED(kResetClip_OpType) {}