Remove origin from GrClipStackClip and GrWindowRectsState.

Change-Id: I993f426fee0f21cf1f529f58d242de3017253678
Reviewed-on: https://skia-review.googlesource.com/9623
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Chris Dalton <csmartdalton@google.com>
diff --git a/gm/windowrectangles.cpp b/gm/windowrectangles.cpp
index c57ad7d..b24febd 100644
--- a/gm/windowrectangles.cpp
+++ b/gm/windowrectangles.cpp
@@ -21,7 +21,6 @@
 #endif
 
 constexpr static SkIRect kDeviceRect = {0, 0, 600, 600};
-constexpr static SkIRect kLayerRect = {25, 25, 575, 575};
 constexpr static SkIRect kCoverRect = {50, 50, 550, 550};
 
 namespace skiagm {
@@ -39,7 +38,6 @@
 
 void WindowRectanglesBaseGM::onDraw(SkCanvas* canvas) {
     sk_tool_utils::draw_checkerboard(canvas, 0xffffffff, 0xffc6c3c6, 25);
-    canvas->saveLayer(SkRect::Make(kLayerRect), nullptr);
 
     SkClipStack stack;
     stack.clipRect(SkRect::MakeXYWH(370.75, 80.25, 149, 100), SkMatrix::I(),
@@ -59,8 +57,6 @@
     stack.clipRRect(complx, SkMatrix::I(), kDifference_SkClipOp, false);
 
     this->onCoverClipStack(stack, canvas);
-
-    canvas->restore();
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -200,10 +196,13 @@
 
 void WindowRectanglesMaskGM::visualizeAlphaMask(GrContext* ctx, GrRenderTargetContext* rtc,
                                                 const GrReducedClip& reducedClip, GrPaint&& paint) {
+    const int padRight = (kDeviceRect.right() - kCoverRect.right()) / 2;
+    const int padBottom = (kDeviceRect.bottom() - kCoverRect.bottom()) / 2;
     sk_sp<GrRenderTargetContext> maskRTC(
-        ctx->makeRenderTargetContextWithFallback(SkBackingFit::kExact, kLayerRect.width(),
-                                                 kLayerRect.height(), kAlpha_8_GrPixelConfig,
-                                                 nullptr));
+        ctx->makeRenderTargetContextWithFallback(SkBackingFit::kExact,
+                                                 kCoverRect.width() + padRight,
+                                                 kCoverRect.height() + padBottom,
+                                                 kAlpha_8_GrPixelConfig, nullptr));
     if (!maskRTC ||
         !ctx->resourceProvider()->attachStencilAttachment(maskRTC->accessRenderTarget())) {
         return;
@@ -218,8 +217,8 @@
                                        SkRect::MakeIWH(maskRTC->width(), maskRTC->height()));
     reducedClip.drawAlphaClipMask(maskRTC.get());
 
-    int x = kCoverRect.x() - kLayerRect.x(),
-        y = kCoverRect.y() - kLayerRect.y();
+    int x = kCoverRect.x() - kDeviceRect.x(),
+        y = kCoverRect.y() - kDeviceRect.y();
 
     // Now visualize the alpha mask by drawing a rect over the area where it is defined. The regions
     // inside window rectangles or outside the scissor should still have the initial checkerboard
@@ -239,7 +238,7 @@
     // Draw a checker pattern into the stencil buffer so we can visualize the regions left untouched
     // by the clip mask generation.
     this->stencilCheckerboard(rtc, false);
-    reducedClip.drawStencilClipMask(ctx, rtc, {kLayerRect.x(), kLayerRect.y()});
+    reducedClip.drawStencilClipMask(ctx, rtc);
 
     // Now visualize the stencil mask by covering the entire render target. The regions inside
     // window rectangless or outside the scissor should still have the initial checkerboard intact.
@@ -260,9 +259,9 @@
 
     rtc->priv().clearStencilClip(GrFixedClip::Disabled(), false);
 
-    for (int y = 0; y < kLayerRect.height(); y += kMaskCheckerSize) {
+    for (int y = 0; y < kDeviceRect.height(); y += kMaskCheckerSize) {
         for (int x = (y & 1) == flip ? 0 : kMaskCheckerSize;
-             x < kLayerRect.width(); x += 2 * kMaskCheckerSize) {
+             x < kDeviceRect.width(); x += 2 * kMaskCheckerSize) {
             SkIRect checker = SkIRect::MakeXYWH(x, y, kMaskCheckerSize, kMaskCheckerSize);
             rtc->priv().stencilRect(GrNoClip(), &kSetClip, GrAAType::kNone, SkMatrix::I(),
                                     SkRect::Make(checker));
diff --git a/src/gpu/GrAppliedClip.h b/src/gpu/GrAppliedClip.h
index ed75bec..4786f64 100644
--- a/src/gpu/GrAppliedClip.h
+++ b/src/gpu/GrAppliedClip.h
@@ -40,10 +40,9 @@
         fWindowRectsState = windowState;
     }
 
-    void addWindowRectangles(const GrWindowRectangles& windows, const SkIPoint& origin,
-                             GrWindowRectsState::Mode mode) {
+    void addWindowRectangles(const GrWindowRectangles& windows, GrWindowRectsState::Mode mode) {
         SkASSERT(!fWindowRectsState.enabled());
-        fWindowRectsState.set(windows, origin, mode);
+        fWindowRectsState.set(windows, mode);
     }
 
     void addCoverageFP(sk_sp<GrFragmentProcessor> fp) {
diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp
index a0682f4..b2dd936 100644
--- a/src/gpu/GrClipStackClip.cpp
+++ b/src/gpu/GrClipStackClip.cpp
@@ -33,16 +33,14 @@
     if (!fStack || fStack->isWideOpen()) {
         return true;
     }
-    return fStack->quickContains(rect.makeOffset(SkIntToScalar(fOrigin.x()),
-                                                 SkIntToScalar(fOrigin.y())));
+    return fStack->quickContains(rect);
 }
 
 bool GrClipStackClip::quickContains(const SkRRect& rrect) const {
     if (!fStack || fStack->isWideOpen()) {
         return true;
     }
-    return fStack->quickContains(rrect.makeOffset(SkIntToScalar(fOrigin.fX),
-                                                  SkIntToScalar(fOrigin.fY)));
+    return fStack->quickContains(rrect);
 }
 
 bool GrClipStackClip::isRRect(const SkRect& origRTBounds, SkRRect* rr, GrAA* aa) const {
@@ -50,19 +48,9 @@
         return false;
     }
     const SkRect* rtBounds = &origRTBounds;
-    SkRect tempRTBounds;
-    bool origin = fOrigin.fX || fOrigin.fY;
-    if (origin) {
-        tempRTBounds = origRTBounds;
-        tempRTBounds.offset(SkIntToScalar(fOrigin.fX), SkIntToScalar(fOrigin.fY));
-        rtBounds = &tempRTBounds;
-    }
     bool isAA;
     if (fStack->isRRect(*rtBounds, rr, &isAA)) {
         *aa = GrBoolToAA(isAA);
-        if (origin) {
-            rr->offset(-SkIntToScalar(fOrigin.fX), -SkIntToScalar(fOrigin.fY));
-        }
         return true;
     }
     return false;
@@ -78,8 +66,7 @@
         return;
     }
     SkRect devBounds;
-    fStack->getConservativeBounds(-fOrigin.x(), -fOrigin.y(), width, height, &devBounds,
-                                  isIntersectionOfRects);
+    fStack->getConservativeBounds(0, 0, width, height, &devBounds, isIntersectionOfRects);
     devBounds.roundOut(devResult);
 }
 
@@ -187,11 +174,8 @@
 
 static bool get_analytic_clip_processor(const ElementList& elements,
                                         bool abortIfAA,
-                                        const SkVector& clipToRTOffset,
-                                        const SkRect& drawBounds,
+                                        const SkRect& drawDevBounds,
                                         sk_sp<GrFragmentProcessor>* resultFP) {
-    SkRect boundsInClipSpace;
-    boundsInClipSpace = drawBounds.makeOffset(-clipToRTOffset.fX, -clipToRTOffset.fY);
     SkASSERT(elements.count() <= kMaxAnalyticElements);
     SkSTArray<kMaxAnalyticElements, sk_sp<GrFragmentProcessor>> fps;
     ElementList::Iter iter(elements);
@@ -205,7 +189,7 @@
                 // Fallthrough, handled same as intersect.
             case kIntersect_SkClipOp:
                 invert = false;
-                if (iter.get()->contains(boundsInClipSpace)) {
+                if (iter.get()->contains(drawDevBounds)) {
                     skip = true;
                 }
                 break;
@@ -232,19 +216,14 @@
 
             switch (iter.get()->getType()) {
                 case SkClipStack::Element::kPath_Type:
-                    fps.emplace_back(GrConvexPolyEffect::Make(edgeType, iter.get()->getPath(),
-                                                              &clipToRTOffset));
+                    fps.emplace_back(GrConvexPolyEffect::Make(edgeType, iter.get()->getPath()));
                     break;
                 case SkClipStack::Element::kRRect_Type: {
-                    SkRRect rrect = iter.get()->getRRect();
-                    rrect.offset(clipToRTOffset.fX, clipToRTOffset.fY);
-                    fps.emplace_back(GrRRectEffect::Make(edgeType, rrect));
+                    fps.emplace_back(GrRRectEffect::Make(edgeType, iter.get()->getRRect()));
                     break;
                 }
                 case SkClipStack::Element::kRect_Type: {
-                    SkRect rect = iter.get()->getRect();
-                    rect.offset(clipToRTOffset.fX, clipToRTOffset.fY);
-                    fps.emplace_back(GrConvexPolyEffect::Make(edgeType, rect));
+                    fps.emplace_back(GrConvexPolyEffect::Make(edgeType, iter.get()->getRect()));
                     break;
                 }
                 default:
@@ -279,22 +258,15 @@
         return false;
     }
 
-    const SkScalar clipX = SkIntToScalar(fOrigin.x()),
-                   clipY = SkIntToScalar(fOrigin.y());
-
-    SkRect clipSpaceDevBounds = devBounds.makeOffset(clipX, clipY);
-    const GrReducedClip reducedClip(*fStack, clipSpaceDevBounds,
+    const GrReducedClip reducedClip(*fStack, devBounds,
                                     renderTargetContext->priv().maxWindowRectangles());
 
-    if (reducedClip.hasIBounds() &&
-        !GrClip::IsInsideClip(reducedClip.ibounds(), clipSpaceDevBounds)) {
-        SkIRect scissorSpaceIBounds(reducedClip.ibounds());
-        scissorSpaceIBounds.offset(-fOrigin);
-        out->addScissor(scissorSpaceIBounds);
+    if (reducedClip.hasIBounds() && !GrClip::IsInsideClip(reducedClip.ibounds(), devBounds)) {
+        out->addScissor(reducedClip.ibounds());
     }
 
     if (!reducedClip.windowRectangles().empty()) {
-        out->addWindowRectangles(reducedClip.windowRectangles(), fOrigin,
+        out->addWindowRectangles(reducedClip.windowRectangles(),
                                  GrWindowRectsState::Mode::kExclusive);
     }
 
@@ -306,7 +278,7 @@
     SkASSERT(reducedClip.hasIBounds());
     SkIRect rtIBounds = SkIRect::MakeWH(renderTargetContext->width(),
                                         renderTargetContext->height());
-    SkIRect clipIBounds = reducedClip.ibounds().makeOffset(-fOrigin.x(), -fOrigin.y());
+    const SkIRect& clipIBounds = reducedClip.ibounds();
     SkASSERT(rtIBounds.contains(clipIBounds)); // Mask shouldn't be larger than the RT.
 #endif
 
@@ -330,8 +302,8 @@
         }
         sk_sp<GrFragmentProcessor> clipFP;
         if (reducedClip.requiresAA() &&
-            get_analytic_clip_processor(reducedClip.elements(), disallowAnalyticAA,
-                                        {-clipX, -clipY}, devBounds, &clipFP)) {
+            get_analytic_clip_processor(reducedClip.elements(), disallowAnalyticAA, devBounds,
+                                        &clipFP)) {
             out->addCoverageFP(std::move(clipFP));
             return true;
         }
@@ -350,10 +322,9 @@
 
         if (result) {
             // The mask's top left coord should be pinned to the rounded-out top left corner of
-            // clipSpace bounds. We determine the mask's position WRT to the render target here.
-            SkIRect rtSpaceMaskBounds = reducedClip.ibounds();
-            rtSpaceMaskBounds.offset(-fOrigin);
-            out->addCoverageFP(create_fp_for_mask(context, std::move(result), rtSpaceMaskBounds));
+            // the clip's device space bounds.
+            out->addCoverageFP(create_fp_for_mask(context, std::move(result),
+                                                  reducedClip.ibounds()));
             return true;
         }
         // if alpha clip mask creation fails fall through to the non-AA code paths
@@ -374,10 +345,9 @@
     // relevant window rectangles that were in the last clip. This subtle requirement will go away
     // after clipping is overhauled.
     if (renderTargetContext->priv().mustRenderClip(reducedClip.elementsGenID(),
-                                                   reducedClip.ibounds(), fOrigin)) {
-        reducedClip.drawStencilClipMask(context, renderTargetContext, fOrigin);
-        renderTargetContext->priv().setLastClip(reducedClip.elementsGenID(), reducedClip.ibounds(),
-                                                fOrigin);
+                                                   reducedClip.ibounds())) {
+        reducedClip.drawStencilClipMask(context, renderTargetContext);
+        renderTargetContext->priv().setLastClip(reducedClip.elementsGenID(), reducedClip.ibounds());
     }
     out->addStencilClip();
     return true;
@@ -391,7 +361,7 @@
     GrUniqueKey::Builder builder(key, kDomain, 3, GrClipStackClip::kMaskTestTag);
     builder[0] = clipGenID;
     // SkToS16 because image filters outset layers to a size indicated by the filter, which can
-    // sometimes result in negative coordinates from clip space.
+    // sometimes result in negative coordinates from device space.
     builder[1] = SkToS16(bounds.fLeft) | (SkToS16(bounds.fRight) << 16);
     builder[2] = SkToS16(bounds.fTop) | (SkToS16(bounds.fBottom) << 16);
 }
@@ -464,8 +434,8 @@
         return GrSurfaceProxy::MakeWrapped(std::move(texture));
     }
 
-    // The mask texture may be larger than necessary. We round out the clip space bounds and pin
-    // the top left corner of the resulting rect to the top left of the texture.
+    // The mask texture may be larger than necessary. We round out the clip bounds and pin the top
+    // left corner of the resulting rect to the top left of the texture.
     SkIRect maskSpaceIBounds = SkIRect::MakeWH(reducedClip.width(), reducedClip.height());
 
     GrSWMaskHelper helper;
diff --git a/src/gpu/GrClipStackClip.h b/src/gpu/GrClipStackClip.h
index 6607595..a1365a7 100644
--- a/src/gpu/GrClipStackClip.h
+++ b/src/gpu/GrClipStackClip.h
@@ -20,14 +20,9 @@
  */
 class GrClipStackClip final : public GrClip {
 public:
-    GrClipStackClip(const SkClipStack* stack = nullptr, const SkIPoint* origin = nullptr) {
-        this->reset(stack, origin);
-    }
+    GrClipStackClip(const SkClipStack* stack = nullptr) { this->reset(stack); }
 
-    void reset(const SkClipStack* stack = nullptr, const SkIPoint* origin = nullptr) {
-        fOrigin = origin ? *origin : SkIPoint::Make(0, 0);
-        fStack = stack;
-    }
+    void reset(const SkClipStack* stack) { fStack = stack; }
 
     bool quickContains(const SkRect&) const final;
     bool quickContains(const SkRRect&) const final;
@@ -62,7 +57,6 @@
                               const GrRenderTargetContext*,
                               const GrReducedClip&);
 
-    SkIPoint            fOrigin;
     const SkClipStack*  fStack;
 };
 
diff --git a/src/gpu/GrFixedClip.h b/src/gpu/GrFixedClip.h
index 7f18c26..0f51752 100644
--- a/src/gpu/GrFixedClip.h
+++ b/src/gpu/GrFixedClip.h
@@ -35,9 +35,8 @@
 
     void disableWindowRectangles() { fWindowRectsState.setDisabled(); }
 
-    void setWindowRectangles(const GrWindowRectangles& windows, const SkIPoint& origin,
-                             GrWindowRectsState::Mode mode) {
-        fWindowRectsState.set(windows, origin, mode);
+    void setWindowRectangles(const GrWindowRectangles& windows, GrWindowRectsState::Mode mode) {
+        fWindowRectsState.set(windows, mode);
     }
 
     bool quickContains(const SkRect&) const override;
diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp
index e1cbd65..845ae44 100644
--- a/src/gpu/GrPipeline.cpp
+++ b/src/gpu/GrPipeline.cpp
@@ -168,7 +168,7 @@
         a.fFragmentProcessors.count() != b.fFragmentProcessors.count() ||
         a.fNumColorProcessors != b.fNumColorProcessors ||
         a.fScissorState != b.fScissorState ||
-        !a.fWindowRectsState.cheapEqualTo(b.fWindowRectsState) ||
+        a.fWindowRectsState != b.fWindowRectsState ||
         a.fFlags != b.fFlags ||
         a.fUserStencilSettings != b.fUserStencilSettings ||
         a.fDrawFace != b.fDrawFace) {
diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp
index 8105ed4..d322c6b 100644
--- a/src/gpu/GrReducedClip.cpp
+++ b/src/gpu/GrReducedClip.cpp
@@ -590,7 +590,7 @@
     GrFixedClip clip(SkIRect::MakeWH(fIBounds.width(), fIBounds.height()));
 
     if (!fWindowRects.empty()) {
-        clip.setWindowRectangles(fWindowRects, {fIBounds.left(), fIBounds.top()},
+        clip.setWindowRectangles(fWindowRects.makeOffset(-fIBounds.left(), -fIBounds.top()),
                                  GrWindowRectsState::Mode::kExclusive);
     }
 
@@ -659,9 +659,8 @@
     StencilClip(const SkIRect& scissorRect) : fFixedClip(scissorRect) {}
     const GrFixedClip& fixedClip() const { return fFixedClip; }
 
-    void setWindowRectangles(const GrWindowRectangles& windows, const SkIPoint& origin,
-                             GrWindowRectsState::Mode mode) {
-        fFixedClip.setWindowRectangles(windows, origin, mode);
+    void setWindowRectangles(const GrWindowRectangles& windows, GrWindowRectsState::Mode mode) {
+        fFixedClip.setWindowRectangles(windows, mode);
     }
 
 private:
@@ -689,23 +688,17 @@
 };
 
 bool GrReducedClip::drawStencilClipMask(GrContext* context,
-                                        GrRenderTargetContext* renderTargetContext,
-                                        const SkIPoint& clipOrigin) const {
+                                        GrRenderTargetContext* renderTargetContext) const {
     // We set the current clip to the bounds so that our recursive draws are scissored to them.
-    StencilClip stencilClip(fIBounds.makeOffset(-clipOrigin.x(), -clipOrigin.y()));
+    StencilClip stencilClip(fIBounds);
 
     if (!fWindowRects.empty()) {
-        stencilClip.setWindowRectangles(fWindowRects, clipOrigin,
-                                        GrWindowRectsState::Mode::kExclusive);
+        stencilClip.setWindowRectangles(fWindowRects, GrWindowRectsState::Mode::kExclusive);
     }
 
     bool initialState = InitialState::kAllIn == this->initialState();
     renderTargetContext->priv().clearStencilClip(stencilClip.fixedClip(), initialState);
 
-    // Set the matrix so that rendered clip elements are transformed from clip to stencil space.
-    SkMatrix viewMatrix;
-    viewMatrix.setTranslate(SkIntToScalar(-clipOrigin.x()), SkIntToScalar(-clipOrigin.y()));
-
     // walk through each clip element and perform its set op with the existing clip.
     for (ElementList::Iter iter(fElements); iter.get(); iter.next()) {
         const Element* element = iter.get();
@@ -737,7 +730,7 @@
             GrShape shape(clipPath, GrStyle::SimpleFill());
             GrPathRenderer::CanDrawPathArgs canDrawArgs;
             canDrawArgs.fShaderCaps = context->caps()->shaderCaps();
-            canDrawArgs.fViewMatrix = &viewMatrix;
+            canDrawArgs.fViewMatrix = &SkMatrix::I();
             canDrawArgs.fShape = &shape;
             canDrawArgs.fAAType = aaType;
             canDrawArgs.fHasUserStencilSettings = false;
@@ -773,7 +766,7 @@
             );
             if (Element::kRect_Type == element->getType()) {
                 renderTargetContext->priv().stencilRect(stencilClip.fixedClip(), &kDrawToStencil,
-                                                        aaType, viewMatrix, element->getRect());
+                                                        aaType, SkMatrix::I(), element->getRect());
             } else {
                 if (!clipPath.isEmpty()) {
                     GrShape shape(clipPath, GrStyle::SimpleFill());
@@ -786,7 +779,7 @@
                                                           &kDrawToStencil,
                                                           renderTargetContext,
                                                           &stencilClip.fixedClip(),
-                                                          &viewMatrix,
+                                                          &SkMatrix::I(),
                                                           &shape,
                                                           aaType,
                                                           false};
@@ -796,7 +789,7 @@
                         args.fContext = context;
                         args.fRenderTargetContext = renderTargetContext;
                         args.fClip = &stencilClip.fixedClip();
-                        args.fViewMatrix = &viewMatrix;
+                        args.fViewMatrix = &SkMatrix::I();
                         args.fAAType = aaType;
                         args.fShape = &shape;
                         pr->stencilPath(args);
@@ -810,8 +803,8 @@
         for (GrUserStencilSettings const* const* pass = stencilPasses; *pass; ++pass) {
             if (drawDirectToClip) {
                 if (Element::kRect_Type == element->getType()) {
-                    renderTargetContext->priv().stencilRect(stencilClip, *pass, aaType, viewMatrix,
-                                                            element->getRect());
+                    renderTargetContext->priv().stencilRect(stencilClip, *pass, aaType,
+                                                            SkMatrix::I(), element->getRect());
                 } else {
                     GrShape shape(clipPath, GrStyle::SimpleFill());
                     GrPaint paint;
@@ -821,7 +814,7 @@
                                                       *pass,
                                                       renderTargetContext,
                                                       &stencilClip,
-                                                      &viewMatrix,
+                                                      &SkMatrix::I(),
                                                       &shape,
                                                       aaType,
                                                       false};
@@ -830,7 +823,7 @@
             } else {
                 // The view matrix is setup to do clip space -> stencil space translation, so
                 // draw rect in clip space.
-                renderTargetContext->priv().stencilRect(stencilClip, *pass, aaType, viewMatrix,
+                renderTargetContext->priv().stencilRect(stencilClip, *pass, aaType, SkMatrix::I(),
                                                         SkRect::Make(fIBounds));
             }
         }
diff --git a/src/gpu/GrReducedClip.h b/src/gpu/GrReducedClip.h
index 0063d46..6dceb00 100644
--- a/src/gpu/GrReducedClip.h
+++ b/src/gpu/GrReducedClip.h
@@ -71,7 +71,7 @@
     InitialState initialState() const { return fInitialState; }
 
     bool drawAlphaClipMask(GrRenderTargetContext*) const;
-    bool drawStencilClipMask(GrContext*, GrRenderTargetContext*, const SkIPoint& clipOrigin) const;
+    bool drawStencilClipMask(GrContext*, GrRenderTargetContext*) const;
 
 private:
     void walkStack(const SkClipStack&, const SkRect& queryBounds, int maxWindowRectangles);
diff --git a/src/gpu/GrRenderTargetContextPriv.h b/src/gpu/GrRenderTargetContextPriv.h
index 430abd0..dcde608 100644
--- a/src/gpu/GrRenderTargetContextPriv.h
+++ b/src/gpu/GrRenderTargetContextPriv.h
@@ -27,24 +27,18 @@
 
     // called to note the last clip drawn to the stencil buffer.
     // TODO: remove after clipping overhaul.
-    void setLastClip(int32_t clipStackGenID,
-                     const SkIRect& clipSpaceRect,
-                     const SkIPoint clipOrigin) {
+    void setLastClip(int32_t clipStackGenID, const SkIRect& devClipBounds) {
         GrRenderTargetOpList* opList = fRenderTargetContext->getOpList();
         opList->fLastClipStackGenID = clipStackGenID;
-        opList->fLastClipStackRect = clipSpaceRect;
-        opList->fLastClipOrigin = clipOrigin;
+        opList->fLastDevClipBounds = devClipBounds;
     }
 
     // called to determine if we have to render the clip into SB.
     // TODO: remove after clipping overhaul.
-    bool mustRenderClip(int32_t clipStackGenID,
-                        const SkIRect& clipSpaceRect,
-                        const SkIPoint& clipOrigin) const {
+    bool mustRenderClip(int32_t clipStackGenID, const SkIRect& devClipBounds) const {
         GrRenderTargetOpList* opList = fRenderTargetContext->getOpList();
         return opList->fLastClipStackGenID != clipStackGenID ||
-               opList->fLastClipOrigin != clipOrigin ||
-               !opList->fLastClipStackRect.contains(clipSpaceRect);
+               !opList->fLastDevClipBounds.contains(devClipBounds);
     }
 
     void clear(const GrFixedClip&, const GrColor, bool canIgnoreClip);
diff --git a/src/gpu/GrRenderTargetOpList.h b/src/gpu/GrRenderTargetOpList.h
index 3929c5c..f4458b5 100644
--- a/src/gpu/GrRenderTargetOpList.h
+++ b/src/gpu/GrRenderTargetOpList.h
@@ -135,8 +135,7 @@
     std::unique_ptr<gr_instanced::InstancedRendering> fInstancedRendering;
 
     int32_t fLastClipStackGenID;
-    SkIRect fLastClipStackRect;
-    SkIPoint fLastClipOrigin;
+    SkIRect fLastDevClipBounds;
 
     typedef GrOpList INHERITED;
 };
diff --git a/src/gpu/GrWindowRectangles.h b/src/gpu/GrWindowRectangles.h
index 076c40d..4a37586 100644
--- a/src/gpu/GrWindowRectangles.h
+++ b/src/gpu/GrWindowRectangles.h
@@ -19,6 +19,8 @@
     GrWindowRectangles(const GrWindowRectangles& that) : fCount(0) { *this = that; }
     ~GrWindowRectangles() { SkSafeUnref(this->rec()); }
 
+    GrWindowRectangles makeOffset(int dx, int dy) const;
+
     bool empty() const { return !fCount; }
     int count() const { return fCount; }
     const SkIRect* data() const;
@@ -50,6 +52,7 @@
         SkASSERT(numWindows < kMaxWindows);
         memcpy(fData, windows, sizeof(SkIRect) * numWindows);
     }
+    Rec() = default;
 
     SkIRect fData[kMaxWindows];
 };
@@ -74,6 +77,25 @@
     return *this;
 }
 
+inline GrWindowRectangles GrWindowRectangles::makeOffset(int dx, int dy) const {
+    if (!dx && !dy) {
+        return *this;
+    }
+    GrWindowRectangles result;
+    result.fCount = fCount;
+    SkIRect* windows;
+    if (result.fCount > kNumLocalWindows) {
+        result.fRec = new Rec();
+        windows = result.fRec->fData;
+    } else {
+        windows = result.fLocalWindows;
+    }
+    for (int i = 0; i < fCount; ++i) {
+        windows[i] = this->data()[i].makeOffset(dx, dy);
+    }
+    return result;
+}
+
 inline SkIRect& GrWindowRectangles::addWindow() {
     SkASSERT(fCount < kMaxWindows);
     if (fCount < kNumLocalWindows) {
diff --git a/src/gpu/GrWindowRectsState.h b/src/gpu/GrWindowRectsState.h
index 9d3b61b..bb9c608 100644
--- a/src/gpu/GrWindowRectsState.h
+++ b/src/gpu/GrWindowRectsState.h
@@ -18,15 +18,13 @@
     };
 
     GrWindowRectsState() : fMode(Mode::kExclusive) {}
-    GrWindowRectsState(const GrWindowRectangles& windows, const SkIPoint& origin, Mode mode)
+    GrWindowRectsState(const GrWindowRectangles& windows, Mode mode)
         : fMode(mode)
-        , fOrigin(origin)
         , fWindows(windows) {
     }
 
     bool enabled() const { return Mode::kInclusive == fMode || !fWindows.empty(); }
     Mode mode() const { return fMode; }
-    const SkIPoint& origin() const { return fOrigin; }
     const GrWindowRectangles& windows() const { return fWindows; }
     int numWindows() const { return fWindows.count(); }
 
@@ -35,25 +33,21 @@
         fWindows.reset();
     }
 
-    void set(const GrWindowRectangles& windows, const SkIPoint& origin, Mode mode) {
+    void set(const GrWindowRectangles& windows, Mode mode) {
         fMode = mode;
-        fOrigin = origin;
         fWindows = windows;
     }
 
-    bool cheapEqualTo(const GrWindowRectsState& that) const {
+    bool operator==(const GrWindowRectsState& that) const {
         if (fMode != that.fMode) {
             return false;
         }
-        if (!fWindows.empty() && fOrigin != that.fOrigin) {
-            return false;
-        }
         return fWindows == that.fWindows;
     }
+    bool operator!=(const GrWindowRectsState& that) const { return !(*this == that); }
 
 private:
     Mode                 fMode;
-    SkIPoint             fOrigin;
     GrWindowRectangles   fWindows;
 };
 
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index e7e776f..e02f807 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -233,8 +233,7 @@
 // and not the state from some other canvas/device
 void SkGpuDevice::prepareDraw() {
     ASSERT_SINGLE_OWNER
-
-    fClip.reset(&this->cs(), nullptr);
+    fClip.reset(&this->cs());
 }
 
 GrRenderTargetContext* SkGpuDevice::accessRenderTargetContext() {
diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp
index 838dff8..d07d591 100644
--- a/src/gpu/effects/GrConvexPolyEffect.cpp
+++ b/src/gpu/effects/GrConvexPolyEffect.cpp
@@ -234,8 +234,7 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-sk_sp<GrFragmentProcessor> GrConvexPolyEffect::Make(GrPrimitiveEdgeType type, const SkPath& path,
-                                                    const SkVector* offset) {
+sk_sp<GrFragmentProcessor> GrConvexPolyEffect::Make(GrPrimitiveEdgeType type, const SkPath& path) {
     if (kHairlineAA_GrProcessorEdgeType == type) {
         return nullptr;
     }
@@ -261,13 +260,6 @@
                                            GrConstColorProcessor::kModulateRGBA_InputMode);
     }
 
-    SkVector t;
-    if (nullptr == offset) {
-        t.set(0, 0);
-    } else {
-        t = *offset;
-    }
-
     SkScalar        edges[3 * kMaxEdges];
     SkPoint         pts[4];
     SkPath::Verb    verb;
@@ -297,8 +289,7 @@
                     edges[3 * n] = -v.fY;
                     edges[3 * n + 1] = v.fX;
                 }
-                SkPoint p = pts[1] + t;
-                edges[3 * n + 2] = -(edges[3 * n] * p.fX + edges[3 * n + 1] * p.fY);
+                edges[3 * n + 2] = -(edges[3 * n] * pts[1].fX + edges[3 * n + 1] * pts[1].fY);
                 ++n;
                 break;
             }
diff --git a/src/gpu/effects/GrConvexPolyEffect.h b/src/gpu/effects/GrConvexPolyEffect.h
index b5ae724..89a8124 100644
--- a/src/gpu/effects/GrConvexPolyEffect.h
+++ b/src/gpu/effects/GrConvexPolyEffect.h
@@ -48,11 +48,9 @@
 
     /**
      * Creates an effect that clips against the path. If the path is not a convex polygon, is
-     * inverse filled, or has too many edges, this will return nullptr. If offset is non-nullptr, then
-     * the path is translated by the vector.
+     * inverse filled, or has too many edges, this will return nullptr.
      */
-    static sk_sp<GrFragmentProcessor> Make(GrPrimitiveEdgeType, const SkPath&,
-                                           const SkVector* offset = nullptr);
+    static sk_sp<GrFragmentProcessor> Make(GrPrimitiveEdgeType, const SkPath&);
 
     /**
      * Creates an effect that fills inside the rect with AA edges..
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 3924a5a..b24f197 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1878,10 +1878,8 @@
 
     GrGLIRect glwindows[GrWindowRectangles::kMaxWindows];
     const SkIRect* skwindows = windowState.windows().data();
-    int dx = -windowState.origin().x(), dy = -windowState.origin().y();
     for (int i = 0; i < numWindows; ++i) {
-        const SkIRect& skwindow = skwindows[i].makeOffset(dx, dy);
-        glwindows[i].setRelativeTo(rt->getViewport(), skwindow, rt->origin());
+        glwindows[i].setRelativeTo(rt->getViewport(), skwindows[i], rt->origin());
     }
 
     GrGLenum glmode = (Mode::kExclusive == windowState.mode()) ? GR_GL_EXCLUSIVE : GR_GL_INCLUSIVE;
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 57142e9..fa42533 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -451,7 +451,7 @@
             if (fWindowState.numWindows() && (fRTOrigin != rtOrigin || fViewport != viewport)) {
                 return false;
             }
-            return fWindowState.cheapEqualTo(windowState);
+            return fWindowState == windowState;
         }
 
     private:
diff --git a/src/gpu/ops/GrClearOp.h b/src/gpu/ops/GrClearOp.h
index 218dcd1..455c684 100644
--- a/src/gpu/ops/GrClearOp.h
+++ b/src/gpu/ops/GrClearOp.h
@@ -86,7 +86,7 @@
         // same color.
         GrClearOp* cb = t->cast<GrClearOp>();
         SkASSERT(cb->fRenderTarget == fRenderTarget);
-        if (!fClip.windowRectsState().cheapEqualTo(cb->fClip.windowRectsState())) {
+        if (fClip.windowRectsState() != cb->fClip.windowRectsState()) {
             return false;
         }
         if (cb->contains(this)) {