Convert GrAppliedClip interface to builder style

GrAppliedClip was about at its limit for how many "make" functions it
could have. Window rectangles would push it over the edge. This change
makes it so GrDrawTarget supplies the original draw bounds to the
constructor, and then GrClip adds the various required clipping
techniques.

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2246113002

Review-Url: https://codereview.chromium.org/2246113002
diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp
index e117144..6cb216e 100644
--- a/src/gpu/GrClipStackClip.cpp
+++ b/src/gpu/GrClipStackClip.cpp
@@ -242,18 +242,14 @@
 ////////////////////////////////////////////////////////////////////////////////
 // sort out what kind of clip mask needs to be created: alpha, stencil,
 // scissor, or entirely software
-bool GrClipStackClip::apply(GrContext* context,
-                            GrDrawContext* drawContext,
-                            const SkRect* origDevBounds,
-                            bool useHWAA,
-                            bool hasUserStencilSettings,
-                            GrAppliedClip* out) const {
+bool GrClipStackClip::apply(GrContext* context, GrDrawContext* drawContext, bool useHWAA,
+                            bool hasUserStencilSettings, GrAppliedClip* out) const {
     if (!fStack || fStack->isWideOpen()) {
         return true;
     }
 
     SkRect devBounds = SkRect::MakeIWH(drawContext->width(), drawContext->height());
-    if (origDevBounds && !devBounds.intersect(*origDevBounds)) {
+    if (!devBounds.intersect(out->clippedDrawBounds())) {
         return false;
     }
 
@@ -263,18 +259,19 @@
     SkRect clipSpaceDevBounds = devBounds.makeOffset(clipX, clipY);
     const GrReducedClip reducedClip(*fStack, clipSpaceDevBounds);
 
-    if (reducedClip.elements().isEmpty()) {
-        if (GrReducedClip::InitialState::kAllOut == reducedClip.initialState()) {
-            return false;
-        }
-        if (!GrClip::IsInsideClip(reducedClip.iBounds(), clipSpaceDevBounds)) {
-            SkIRect scissorSpaceIBounds(reducedClip.iBounds());
-            scissorSpaceIBounds.offset(-fOrigin);
-            out->makeScissored(scissorSpaceIBounds);
-        }
-        return true;
+    if (reducedClip.hasIBounds() &&
+        !GrClip::IsInsideClip(reducedClip.ibounds(), clipSpaceDevBounds)) {
+        SkIRect scissorSpaceIBounds(reducedClip.ibounds());
+        scissorSpaceIBounds.offset(-fOrigin);
+        out->addScissor(scissorSpaceIBounds);
     }
 
+    if (reducedClip.elements().isEmpty()) {
+        return InitialState::kAllIn == reducedClip.initialState();
+    }
+
+    SkASSERT(reducedClip.hasIBounds());
+
     // An element count of 4 was chosen because of the common pattern in Blink of:
     //   isect RR
     //   diff  RR
@@ -297,13 +294,7 @@
         if (reducedClip.requiresAA() &&
             get_analytic_clip_processor(reducedClip.elements(), disallowAnalyticAA,
                                         {-clipX, -clipY}, devBounds, &clipFP)) {
-            SkIRect scissorSpaceIBounds(reducedClip.iBounds());
-            scissorSpaceIBounds.offset(-fOrigin);
-            if (GrClip::IsInsideClip(scissorSpaceIBounds, devBounds)) {
-                out->makeFPBased(std::move(clipFP), SkRect::Make(scissorSpaceIBounds));
-            } else {
-                out->makeScissoredFPBased(std::move(clipFP), scissorSpaceIBounds);
-            }
+            out->addCoverageFP(std::move(clipFP));
             return true;
         }
     }
@@ -333,10 +324,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();
+            SkIRect rtSpaceMaskBounds = reducedClip.ibounds();
             rtSpaceMaskBounds.offset(-fOrigin);
-            out->makeFPBased(create_fp_for_mask(result.get(), rtSpaceMaskBounds),
-                             SkRect::Make(rtSpaceMaskBounds));
+            out->addCoverageFP(create_fp_for_mask(result.get(), rtSpaceMaskBounds));
             return true;
         }
         // if alpha clip mask creation fails fall through to the non-AA code paths
@@ -345,17 +335,7 @@
     // use the stencil clip if we can't represent the clip as a rectangle.
     SkIPoint clipSpaceToStencilSpaceOffset = -fOrigin;
     CreateStencilClipMask(context, drawContext, reducedClip, clipSpaceToStencilSpaceOffset);
-
-    // This must occur after createStencilClipMask. That function may change the scissor. Also, it
-    // only guarantees that the stencil mask is correct within the bounds it was passed, so we must
-    // use both stencil and scissor test to the bounds for the final draw.
-    if (GrClip::IsInsideClip(reducedClip.iBounds(), clipSpaceDevBounds)) {
-        out->makeStencil(true, devBounds);
-    } else {
-        SkIRect scissorSpaceIBounds(reducedClip.iBounds());
-        scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset);
-        out->makeScissoredStencil(scissorSpaceIBounds);
-    }
+    out->addStencilClip();
     return true;
 }
 
@@ -438,7 +418,7 @@
                                                       const SkVector& clipToMaskOffset) {
     GrResourceProvider* resourceProvider = context->resourceProvider();
     GrUniqueKey key;
-    GetClipMaskKey(reducedClip.genID(), reducedClip.iBounds(), &key);
+    GetClipMaskKey(reducedClip.genID(), reducedClip.ibounds(), &key);
     if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key)) {
         return sk_sp<GrTexture>(texture);
     }
@@ -463,9 +443,7 @@
 
     // The scratch texture that we are drawing into can be substantially larger than the mask. Only
     // clear the part that we care about.
-    dc->clear(&maskSpaceIBounds,
-              GrReducedClip::InitialState::kAllIn == reducedClip.initialState() ? -1 : 0,
-              true);
+    dc->clear(&maskSpaceIBounds, InitialState::kAllIn == reducedClip.initialState() ? -1 : 0, true);
 
     // Set the matrix so that rendered clip elements are transformed to mask space from clip
     // space.
@@ -513,7 +491,7 @@
             if (!dc->drawContextPriv().drawAndStencilRect(clip, &kDrawOutsideElement,
                                                           op, !invert, false,
                                                           translate,
-                                                          SkRect::Make(reducedClip.iBounds()))) {
+                                                          SkRect::Make(reducedClip.ibounds()))) {
                 return nullptr;
             }
         } else {
@@ -548,9 +526,9 @@
     }
 
     // TODO: these need to be swapped over to using a StencilAttachmentProxy
-    if (stencilAttachment->mustRenderClip(reducedClip.genID(), reducedClip.iBounds(),
+    if (stencilAttachment->mustRenderClip(reducedClip.genID(), reducedClip.ibounds(),
                                           clipSpaceToStencilOffset)) {
-        stencilAttachment->setLastClip(reducedClip.genID(), reducedClip.iBounds(),
+        stencilAttachment->setLastClip(reducedClip.genID(), reducedClip.ibounds(),
                                        clipSpaceToStencilOffset);
         // Set the matrix so that rendered clip elements are transformed from clip to stencil space.
         SkVector translate = {
@@ -561,11 +539,11 @@
         viewMatrix.setTranslate(translate);
 
         // We set the current clip to the bounds so that our recursive draws are scissored to them.
-        SkIRect stencilSpaceIBounds(reducedClip.iBounds());
+        SkIRect stencilSpaceIBounds(reducedClip.ibounds());
         stencilSpaceIBounds.offset(clipSpaceToStencilOffset);
         GrFixedClip clip(stencilSpaceIBounds);
 
-        bool insideClip = GrReducedClip::InitialState::kAllIn == reducedClip.initialState();
+        bool insideClip = InitialState::kAllIn == reducedClip.initialState();
         drawContext->drawContextPriv().clearStencilClip(stencilSpaceIBounds, insideClip);
 
         // walk through each clip element and perform its set op
@@ -671,22 +649,19 @@
                 }
             }
 
+            // Just enable stencil clip. The passes choose whether or not they will actually use it.
+            clip.enableStencilClip();
+
             // now we modify the clip bit by rendering either the clip
             // element directly or a bounding rect of the entire clip.
             for (GrUserStencilSettings const* const* pass = stencilPasses; *pass; ++pass) {
-
                 if (drawDirectToClip) {
                     if (Element::kRect_Type == element->getType()) {
-                        clip.enableStencilClip(element->getRect().makeOffset(translate.fX,
-                                                                             translate.fY));
                         drawContext->drawContextPriv().stencilRect(clip, *pass, useHWAA, viewMatrix,
                                                                    element->getRect());
                     } else {
                         GrShape shape(clipPath, GrStyle::SimpleFill());
                         GrPaint paint;
-                        SkRect bounds = clipPath.getBounds();
-                        bounds.offset(translate.fX, translate.fY);
-                        clip.enableStencilClip(bounds);
                         paint.setXPFactory(GrDisableColorXPFactory::Make());
                         paint.setAntiAlias(element->isAA());
                         GrPathRenderer::DrawPathArgs args;
@@ -704,11 +679,8 @@
                 } else {
                     // The view matrix is setup to do clip space -> stencil space translation, so
                     // draw rect in clip space.
-                    SkRect bounds = SkRect::Make(reducedClip.iBounds());
-                    bounds.offset(translate.fX, translate.fY);
-                    clip.enableStencilClip(bounds);
                     drawContext->drawContextPriv().stencilRect(clip, *pass, false, viewMatrix,
-                                                               SkRect::Make(reducedClip.iBounds()));
+                                                               SkRect::Make(reducedClip.ibounds()));
                 }
             }
         }
@@ -721,7 +693,7 @@
                                                          const GrReducedClip& reducedClip,
                                                          const SkVector& clipToMaskOffset) {
     GrUniqueKey key;
-    GetClipMaskKey(reducedClip.genID(), reducedClip.iBounds(), &key);
+    GetClipMaskKey(reducedClip.genID(), reducedClip.ibounds(), &key);
     if (GrTexture* texture = texProvider->findAndRefTextureByUniqueKey(key)) {
         return sk_sp<GrTexture>(texture);
     }
@@ -738,7 +710,7 @@
     translate.setTranslate(clipToMaskOffset);
 
     helper.init(maskSpaceIBounds, &translate);
-    helper.clear(GrReducedClip::InitialState::kAllIn == reducedClip.initialState() ? 0xFF : 0x00);
+    helper.clear(InitialState::kAllIn == reducedClip.initialState() ? 0xFF : 0x00);
 
     for (ElementList::Iter iter(reducedClip.elements()); iter.get(); iter.next()) {
         const Element* element = iter.get();
@@ -750,7 +722,7 @@
             // but leave the pixels inside the geometry alone. For reverse difference we invert all
             // the pixels before clearing the ones outside the geometry.
             if (SkRegion::kReverseDifference_Op == op) {
-                SkRect temp = SkRect::Make(reducedClip.iBounds());
+                SkRect temp = SkRect::Make(reducedClip.ibounds());
                 // invert the entire scene
                 helper.drawRect(temp, SkRegion::kXOR_Op, false, 0xFF);
             }