Make GrClipMaskManager stateless and push GrPipelineBuilder construction downstack

This will be followed up with a CL to remove the GrRenderTarget from the GrPipelineBuilder.

Split out of:
https://codereview.chromium.org/1988923002/ (Declassify GrClipMaskManager and Remove GrRenderTarget and GrDrawTarget from GrPipelineBuilder)

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

Review-Url: https://codereview.chromium.org/2035823002
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index df58a92..ff95eea 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -9,7 +9,6 @@
 #include "GrCaps.h"
 #include "GrDrawingManager.h"
 #include "GrDrawContextPriv.h"
-#include "GrDrawTarget.h"
 #include "GrGpuResourcePriv.h"
 #include "GrPaint.h"
 #include "GrPathRenderer.h"
@@ -28,6 +27,8 @@
 
 typedef SkClipStack::Element Element;
 
+static const int kMaxAnalyticElements = 4;
+
 ////////////////////////////////////////////////////////////////////////////////
 // set up the draw state to enable the aa clipping mask. Besides setting up the
 // stage matrix this also alters the vertex layout
@@ -50,15 +51,13 @@
                                          kDevice_GrCoordSet));
 }
 
-static void draw_non_aa_rect(GrDrawTarget* drawTarget,
-                             const GrPipelineBuilder& pipelineBuilder,
-                             const GrClip& clip,
-                             GrColor color,
-                             const SkMatrix& viewMatrix,
-                             const SkRect& rect) {
-    SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, viewMatrix, rect,
-                                                                        nullptr, nullptr));
-    drawTarget->drawBatch(pipelineBuilder, clip, batch);
+void GrClipMaskManager::DrawNonAARect(GrDrawContext* drawContext,
+                                      const GrFixedClip& clip,
+                                      const SkMatrix& viewMatrix,
+                                      const SkRect& rect,
+                                      bool doAA,
+                                      const GrUserStencilSettings* stencilSettings) {
+    drawContext->drawContextPriv().stencilRect(clip, stencilSettings, doAA, viewMatrix, rect);
 }
 
 // Does the path in 'element' require SW rendering? If so, return true (and,
@@ -66,7 +65,7 @@
 // 'prOut' to the non-SW path renderer that will do the job).
 bool GrClipMaskManager::PathNeedsSWRenderer(GrContext* context,
                                             bool hasUserStencilSettings,
-                                            const GrRenderTarget* rt,
+                                            const GrDrawContext* drawContext,
                                             const SkMatrix& viewMatrix,
                                             const Element* element,
                                             GrPathRenderer** prOut,
@@ -108,7 +107,7 @@
         canDrawArgs.fStyle = &GrStyle::SimpleFill();
         canDrawArgs.fAntiAlias = element->isAA();
         canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings;
-        canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampled();
+        canDrawArgs.fIsStencilBufferMSAA = drawContext->isStencilBufferMultisampled();
 
         // the 'false' parameter disallows use of the SW path renderer
         GrPathRenderer* pr = context->drawingManager()->getPathRenderer(canDrawArgs, false, type);
@@ -119,37 +118,6 @@
     }
 }
 
-// Determines whether it is possible to draw the element to both the stencil buffer and the
-// alpha mask simultaneously. If so and the element is a path a compatible path renderer is
-// also returned.
-GrPathRenderer* GrClipMaskManager::GetPathRenderer(GrContext* context,
-                                                   GrTexture* texture,
-                                                   const SkMatrix& viewMatrix,
-                                                   const SkClipStack::Element* element) {
-    GrPathRenderer* pr;
-    constexpr bool kNeedsStencil = true;
-    constexpr bool kHasUserStencilSettings = false;
-    PathNeedsSWRenderer(context,
-                        kHasUserStencilSettings,
-                        texture->asRenderTarget(),
-                        viewMatrix,
-                        element,
-                        &pr,
-                        kNeedsStencil);
-    return pr;
-}
-
-GrContext* GrClipMaskManager::getContext() {
-    return fDrawTarget->cmmAccess().context();
-}
-
-const GrCaps* GrClipMaskManager::caps() const {
-    return fDrawTarget->caps();
-}
-
-GrResourceProvider* GrClipMaskManager::resourceProvider() {
-    return fDrawTarget->cmmAccess().resourceProvider();
-}
 /*
  * This method traverses the clip stack to see if the GrSoftwarePathRenderer
  * will be used on any element. If so, it returns true to indicate that the
@@ -157,7 +125,7 @@
  */
 bool GrClipMaskManager::UseSWOnlyPath(GrContext* context,
                                       const GrPipelineBuilder& pipelineBuilder,
-                                      const GrRenderTarget* rt,
+                                      const GrDrawContext* drawContext,
                                       const SkVector& clipToMaskOffset,
                                       const GrReducedClip::ElementList& elements) {
     // TODO: generalize this function so that when
@@ -177,18 +145,18 @@
                             SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op;
 
         if (PathNeedsSWRenderer(context, pipelineBuilder.hasUserStencilSettings(),
-                                rt, translate, element, nullptr, needsStencil)) {
+                                drawContext, translate, element, nullptr, needsStencil)) {
             return true;
         }
     }
     return false;
 }
 
-bool GrClipMaskManager::getAnalyticClipProcessor(const GrReducedClip::ElementList& elements,
-                                                 bool abortIfAA,
-                                                 SkVector& clipToRTOffset,
-                                                 const SkRect* drawBounds,
-                                                 sk_sp<const GrFragmentProcessor>* resultFP) {
+static bool get_analytic_clip_processor(const GrReducedClip::ElementList& elements,
+                                        bool abortIfAA,
+                                        SkVector& clipToRTOffset,
+                                        const SkRect* drawBounds,
+                                        sk_sp<const GrFragmentProcessor>* resultFP) {
     SkRect boundsInClipSpace;
     if (drawBounds) {
         boundsInClipSpace = *drawBounds;
@@ -284,7 +252,9 @@
 ////////////////////////////////////////////////////////////////////////////////
 // sort out what kind of clip mask needs to be created: alpha, stencil,
 // scissor, or entirely software
-bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
+bool GrClipMaskManager::SetupClipping(GrContext* context,
+                                      const GrPipelineBuilder& pipelineBuilder,
+                                      GrDrawContext* drawContext,
                                       const GrClipStackClip& clip,
                                       const SkRect* devBounds,
                                       GrAppliedClip* out) {
@@ -297,12 +267,8 @@
     GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialState;
     SkIRect clipSpaceIBounds;
     bool requiresAA = false;
-    GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
 
-    // GrDrawTarget should have filtered this for us
-    SkASSERT(rt);
-
-    SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
+    SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(drawContext->width(), drawContext->height());
     clipSpaceRTIBounds.offset(clip.origin());
 
     SkIRect clipSpaceReduceQueryBounds;
@@ -346,8 +312,8 @@
                                     SkIntToScalar(-clip.origin().fY) };
         // When there are multiple samples we want to do per-sample clipping, not compute a
         // fractional pixel coverage.
-        bool disallowAnalyticAA = rt->isStencilBufferMultisampled();
-        if (disallowAnalyticAA && !rt->numColorSamples()) {
+        bool disallowAnalyticAA = drawContext->isStencilBufferMultisampled();
+        if (disallowAnalyticAA && !drawContext->numColorSamples()) {
             // With a single color sample, any coverage info is lost from color once it hits the
             // color buffer anyway, so we may as well use coverage AA if nothing else in the pipe
             // is multisampled.
@@ -357,12 +323,11 @@
         sk_sp<const GrFragmentProcessor> clipFP;
         if (elements.isEmpty() ||
             (requiresAA &&
-             this->getAnalyticClipProcessor(elements, disallowAnalyticAA, clipToRTOffset, devBounds,
-                                            &clipFP))) {
+             get_analytic_clip_processor(elements, disallowAnalyticAA, clipToRTOffset, devBounds,
+                                         &clipFP))) {
             SkIRect scissorSpaceIBounds(clipSpaceIBounds);
             scissorSpaceIBounds.offset(-clip.origin());
-            if (nullptr == devBounds ||
-                !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) {
+            if (!devBounds || !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) {
                 out->makeScissoredFPBased(clipFP, scissorSpaceIBounds);
                 return true;
             }
@@ -372,7 +337,7 @@
     }
 
     // If the stencil buffer is multisampled we can use it to do everything.
-    if (!rt->isStencilBufferMultisampled() && requiresAA) {
+    if (!drawContext->isStencilBufferMultisampled() && requiresAA) {
         sk_sp<GrTexture> result;
 
         // The top-left of the mask corresponds to the top-left corner of the bounds.
@@ -381,17 +346,18 @@
             SkIntToScalar(-clipSpaceIBounds.fTop)
         };
 
-        if (UseSWOnlyPath(this->getContext(), pipelineBuilder, rt, clipToMaskOffset, elements)) {
+        if (UseSWOnlyPath(context, pipelineBuilder, drawContext,
+                          clipToMaskOffset, elements)) {
             // The clip geometry is complex enough that it will be more efficient to create it
             // entirely in software
-            result = CreateSoftwareClipMask(this->getContext()->textureProvider(),
+            result = CreateSoftwareClipMask(context->textureProvider(),
                                             genID,
                                             initialState,
                                             elements,
                                             clipToMaskOffset,
                                             clipSpaceIBounds);
         } else {
-            result = CreateAlphaClipMask(this->getContext(),
+            result = CreateAlphaClipMask(context,
                                          genID,
                                          initialState,
                                          elements,
@@ -414,12 +380,13 @@
 
     // use the stencil clip if we can't represent the clip as a rectangle.
     SkIPoint clipSpaceToStencilSpaceOffset = -clip.origin();
-    this->createStencilClipMask(rt,
-                                genID,
-                                initialState,
-                                elements,
-                                clipSpaceIBounds,
-                                clipSpaceToStencilSpaceOffset);
+    CreateStencilClipMask(context,
+                          drawContext,
+                          genID,
+                          initialState,
+                          elements,
+                          clipSpaceIBounds,
+                          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
@@ -609,19 +576,22 @@
 ////////////////////////////////////////////////////////////////////////////////
 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device
 // (as opposed to canvas) coordinates
-bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
+bool GrClipMaskManager::CreateStencilClipMask(GrContext* context,
+                                              GrDrawContext* drawContext,
                                               int32_t elementsGenID,
                                               GrReducedClip::InitialState initialState,
                                               const GrReducedClip::ElementList& elements,
                                               const SkIRect& clipSpaceIBounds,
                                               const SkIPoint& clipSpaceToStencilOffset) {
-    SkASSERT(rt);
+    SkASSERT(drawContext);
 
-    GrStencilAttachment* stencilAttachment = this->resourceProvider()->attachStencilAttachment(rt);
+    GrStencilAttachment* stencilAttachment = context->resourceProvider()->attachStencilAttachment(
+                                                    drawContext->accessRenderTarget());
     if (nullptr == stencilAttachment) {
         return false;
     }
 
+    // TODO: these need to be swapped over to using a StencilAttachmentProxy
     if (stencilAttachment->mustRenderClip(elementsGenID, clipSpaceIBounds, clipSpaceToStencilOffset)) {
         stencilAttachment->setLastClip(elementsGenID, clipSpaceIBounds, clipSpaceToStencilOffset);
         // Set the matrix so that rendered clip elements are transformed from clip to stencil space.
@@ -637,24 +607,15 @@
         stencilSpaceIBounds.offset(clipSpaceToStencilOffset);
         GrFixedClip clip(stencilSpaceIBounds);
 
-        fDrawTarget->cmmAccess().clearStencilClip(stencilSpaceIBounds,
-            GrReducedClip::kAllIn_InitialState == initialState, rt);
+        drawContext->drawContextPriv().clearStencilClip(
+                                            stencilSpaceIBounds,
+                                            GrReducedClip::kAllIn_InitialState == initialState);
 
         // walk through each clip element and perform its set op
         // with the existing clip.
         for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) {
             const Element* element = iter.get();
 
-            GrPipelineBuilder pipelineBuilder;
-            pipelineBuilder.setRenderTarget(rt);
-
-            pipelineBuilder.setDisableColorXPFactory();
-
-            // if the target is MSAA then we want MSAA enabled when the clip is soft
-            if (rt->isStencilBufferMultisampled()) {
-                pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, element->isAA());
-            }
-
             bool fillInverted = false;
             // enabled at bottom of loop
             clip.enableStencilClip(false);
@@ -677,21 +638,19 @@
                     clipPath.toggleInverseFillType();
                 }
 
-                SkASSERT(!pipelineBuilder.hasUserStencilSettings());
-
                 GrPathRenderer::CanDrawPathArgs canDrawArgs;
-                canDrawArgs.fShaderCaps = this->getContext()->caps()->shaderCaps();
+                canDrawArgs.fShaderCaps = context->caps()->shaderCaps();
                 canDrawArgs.fViewMatrix = &viewMatrix;
                 canDrawArgs.fPath = &clipPath;
                 canDrawArgs.fStyle = &GrStyle::SimpleFill();
                 canDrawArgs.fAntiAlias = false;
-                canDrawArgs.fHasUserStencilSettings = pipelineBuilder.hasUserStencilSettings();
-                canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampled();
+                canDrawArgs.fHasUserStencilSettings = false;
+                canDrawArgs.fIsStencilBufferMSAA = drawContext->isStencilBufferMultisampled();
 
-                pr = this->getContext()->drawingManager()->getPathRenderer(canDrawArgs, false,
-                                                                           GrPathRendererChain::kStencilOnly_DrawType,
-                                                                           &stencilSupport);
-                if (nullptr == pr) {
+                pr = context->drawingManager()->getPathRenderer(canDrawArgs, false,
+                                                                GrPathRendererChain::kStencilOnly_DrawType,
+                                                                &stencilSupport);
+                if (!pr) {
                     return false;
                 }
             }
@@ -718,19 +677,20 @@
                          0xffff>()
                 );
                 if (Element::kRect_Type == element->getType()) {
-                    pipelineBuilder.setUserStencil(&kDrawToStencil);
-
-                    draw_non_aa_rect(fDrawTarget, pipelineBuilder, clip, GrColor_WHITE, viewMatrix,
-                                     element->getRect());
+                    DrawNonAARect(drawContext, clip, viewMatrix,
+                                  element->getRect(), element->isAA(), &kDrawToStencil);
                 } else {
                     if (!clipPath.isEmpty()) {
                         if (canRenderDirectToStencil) {
-                            pipelineBuilder.setUserStencil(&kDrawToStencil);
+                            GrPaint paint;
+                            paint.setXPFactory(GrDisableColorXPFactory::Create());
+                            paint.setAntiAlias(element->isAA());
 
                             GrPathRenderer::DrawPathArgs args;
-                            args.fTarget = fDrawTarget;
-                            args.fResourceProvider = this->getContext()->resourceProvider();
-                            args.fPipelineBuilder = &pipelineBuilder;
+                            args.fResourceProvider = context->resourceProvider();
+                            args.fPaint = &paint;
+                            args.fUserStencilSettings = &kDrawToStencil;
+                            args.fDrawContext = drawContext;
                             args.fClip = &clip;
                             args.fColor = GrColor_WHITE;
                             args.fViewMatrix = &viewMatrix;
@@ -741,12 +701,12 @@
                             pr->drawPath(args);
                         } else {
                             GrPathRenderer::StencilPathArgs args;
-                            args.fTarget = fDrawTarget;
-                            args.fResourceProvider = this->getContext()->resourceProvider();
-                            args.fPipelineBuilder = &pipelineBuilder;
+                            args.fResourceProvider = context->resourceProvider();
+                            args.fDrawContext = drawContext;
                             args.fClip = &clip;
                             args.fViewMatrix = &viewMatrix;
                             args.fPath = &clipPath;
+                            args.fIsAA = element->isAA();
                             pr->stencilPath(args);
                         }
                     }
@@ -757,17 +717,21 @@
             // element directly or a bounding rect of the entire clip.
             clip.enableStencilClip(true);
             for (GrUserStencilSettings const* const* pass = stencilPasses; *pass; ++pass) {
-                pipelineBuilder.setUserStencil(*pass);
 
                 if (drawDirectToClip) {
                     if (Element::kRect_Type == element->getType()) {
-                        draw_non_aa_rect(fDrawTarget, pipelineBuilder, clip, GrColor_WHITE,
-                                         viewMatrix, element->getRect());
+                        DrawNonAARect(drawContext, clip,
+                                      viewMatrix, element->getRect(), element->isAA(), *pass);
                     } else {
+                        GrPaint paint;
+                        paint.setXPFactory(GrDisableColorXPFactory::Create());
+                        paint.setAntiAlias(element->isAA());
+
                         GrPathRenderer::DrawPathArgs args;
-                        args.fTarget = fDrawTarget;
-                        args.fResourceProvider = this->getContext()->resourceProvider();
-                        args.fPipelineBuilder = &pipelineBuilder;
+                        args.fResourceProvider = context->resourceProvider();
+                        args.fPaint = &paint;
+                        args.fUserStencilSettings = *pass;
+                        args.fDrawContext = drawContext;
                         args.fClip = &clip;
                         args.fColor = GrColor_WHITE;
                         args.fViewMatrix = &viewMatrix;
@@ -780,8 +744,8 @@
                 } else {
                     // The view matrix is setup to do clip space -> stencil space translation, so
                     // draw rect in clip space.
-                    draw_non_aa_rect(fDrawTarget, pipelineBuilder, clip, GrColor_WHITE, viewMatrix,
-                                     SkRect::Make(clipSpaceIBounds));
+                    DrawNonAARect(drawContext, clip, viewMatrix,
+                                  SkRect::Make(clipSpaceIBounds), false, *pass);
                 }
             }
         }