Remove GrClipTarget

Review URL: https://codereview.chromium.org/1330353006
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index 6294c35..0f32839 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -76,14 +76,14 @@
 }
 }
 
-GrClipMaskManager::GrClipMaskManager(GrClipTarget* clipTarget)
+GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget)
     : fCurrClipMaskType(kNone_ClipMaskType)
-    , fAACache(clipTarget->getContext()->resourceProvider())
-    , fClipTarget(clipTarget)
+    , fAACache(drawTarget->cmmAccess().resourceProvider())
+    , fDrawTarget(drawTarget)
     , fClipMode(kIgnoreClip_StencilClipMode) {
 }
 
-GrContext* GrClipMaskManager::getContext() { return fClipTarget->getContext(); }
+GrContext* GrClipMaskManager::getContext() { return fDrawTarget->cmmAccess().context(); }
 
 /*
  * This method traverses the clip stack to see if the GrSoftwarePathRenderer
@@ -110,7 +110,7 @@
         if (Element::kRect_Type != element->getType()) {
             SkPath path;
             element->asPath(&path);
-            if (path_needs_SW_renderer(this->getContext(), fClipTarget, pipelineBuilder, translate,
+            if (path_needs_SW_renderer(this->getContext(), fDrawTarget, pipelineBuilder, translate,
                                        path, stroke, element->isAA())) {
                 return true;
             }
@@ -405,10 +405,10 @@
                 SkRect devRect = element->getRect();
                 viewMatrix.mapRect(&devRect);
 
-                fClipTarget->drawAARect(*pipelineBuilder, color, viewMatrix,
+                fDrawTarget->drawAARect(*pipelineBuilder, color, viewMatrix,
                                         element->getRect(), devRect);
             } else {
-                fClipTarget->drawNonAARect(*pipelineBuilder, color, viewMatrix,
+                fDrawTarget->drawNonAARect(*pipelineBuilder, color, viewMatrix,
                                            element->getRect());
             }
             return true;
@@ -424,14 +424,14 @@
                 GrPathRendererChain::DrawType type;
                 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_DrawType :
                                          GrPathRendererChain::kColor_DrawType;
-                pr = this->getContext()->getPathRenderer(fClipTarget, pipelineBuilder, viewMatrix,
+                pr = this->getContext()->getPathRenderer(fDrawTarget, pipelineBuilder, viewMatrix,
                                                          path, stroke, false, type);
             }
             if (nullptr == pr) {
                 return false;
             }
             GrPathRenderer::DrawPathArgs args;
-            args.fTarget = fClipTarget;
+            args.fTarget = fDrawTarget;
             args.fResourceProvider = this->getContext()->resourceProvider();
             args.fPipelineBuilder = pipelineBuilder;
             args.fColor = color;
@@ -466,7 +466,7 @@
         GrPathRendererChain::DrawType type = element->isAA() ?
             GrPathRendererChain::kStencilAndColorAntiAlias_DrawType :
             GrPathRendererChain::kStencilAndColor_DrawType;
-        *pr = this->getContext()->getPathRenderer(fClipTarget, pipelineBuilder, SkMatrix::I(), path,
+        *pr = this->getContext()->getPathRenderer(fDrawTarget, pipelineBuilder, SkMatrix::I(), path,
                                                   stroke, false, type);
         return SkToBool(*pr);
     }
@@ -495,7 +495,7 @@
                                       GrTextureParams::kNone_FilterMode))->unref();
 
     // The color passed in here does not matter since the coverageSetOpXP won't read it.
-    fClipTarget->drawNonAARect(*pipelineBuilder,
+    fDrawTarget->drawNonAARect(*pipelineBuilder,
                                GrColor_WHITE,
                                SkMatrix::I(),
                                SkRect::Make(dstBound));
@@ -586,7 +586,7 @@
 
     // The scratch texture that we are drawing into can be substantially larger than the mask. Only
     // clear the part that we care about.
-    fClipTarget->clear(&maskSpaceIBounds,
+    fDrawTarget->clear(&maskSpaceIBounds,
                        GrReducedClip::kAllIn_InitialState == initialState ? 0xffffffff : 0x00000000,
                        true,
                        result->asRenderTarget());
@@ -635,7 +635,7 @@
                 }
                 dst = temp;
                 // clear the temp target and set blend to replace
-                fClipTarget->clear(&maskSpaceElementIBounds,
+                fDrawTarget->clear(&maskSpaceElementIBounds,
                                    invert ? 0xffffffff : 0x00000000,
                                    true,
                                    dst->asRenderTarget());
@@ -688,7 +688,7 @@
                 backgroundPipelineBuilder.setStencil(kDrawOutsideElement);
 
                 // The color passed in here does not matter since the coverageSetOpXP won't read it.
-                fClipTarget->drawNonAARect(backgroundPipelineBuilder, GrColor_WHITE, translate,
+                fDrawTarget->drawNonAARect(backgroundPipelineBuilder, GrColor_WHITE, translate,
                                            clipSpaceIBounds);
             }
         } else {
@@ -741,9 +741,8 @@
         SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil buffers");
         clipBit = (1 << (clipBit-1));
 
-        fClipTarget->clearStencilClip(stencilSpaceIBounds,
-                                      GrReducedClip::kAllIn_InitialState == initialState,
-                                      rt);
+        fDrawTarget->cmmAccess().clearStencilClip(stencilSpaceIBounds,
+            GrReducedClip::kAllIn_InitialState == initialState, rt);
 
         // walk through each clip element and perform its set op
         // with the existing clip.
@@ -783,7 +782,7 @@
                 if (fillInverted) {
                     clipPath.toggleInverseFillType();
                 }
-                pr = this->getContext()->getPathRenderer(fClipTarget,
+                pr = this->getContext()->getPathRenderer(fDrawTarget,
                                                          &pipelineBuilder,
                                                          viewMatrix,
                                                          clipPath,
@@ -825,7 +824,7 @@
                     *pipelineBuilder.stencil() = gDrawToStencil;
 
                     // We need this AGP until everything is in GrBatch
-                    fClipTarget->drawNonAARect(pipelineBuilder,
+                    fDrawTarget->drawNonAARect(pipelineBuilder,
                                                GrColor_WHITE,
                                                viewMatrix,
                                                element->getRect());
@@ -835,7 +834,7 @@
                             *pipelineBuilder.stencil() = gDrawToStencil;
 
                             GrPathRenderer::DrawPathArgs args;
-                            args.fTarget = fClipTarget;
+                            args.fTarget = fDrawTarget;
                             args.fResourceProvider = this->getContext()->resourceProvider();
                             args.fPipelineBuilder = &pipelineBuilder;
                             args.fColor = GrColor_WHITE;
@@ -846,7 +845,7 @@
                             pr->drawPath(args);
                         } else {
                             GrPathRenderer::StencilPathArgs args;
-                            args.fTarget = fClipTarget;
+                            args.fTarget = fDrawTarget;
                             args.fResourceProvider = this->getContext()->resourceProvider();
                             args.fPipelineBuilder = &pipelineBuilder;
                             args.fViewMatrix = &viewMatrix;
@@ -867,13 +866,13 @@
                 if (canDrawDirectToClip) {
                     if (Element::kRect_Type == element->getType()) {
                         // We need this AGP until everything is in GrBatch
-                        fClipTarget->drawNonAARect(pipelineBuilder,
+                        fDrawTarget->drawNonAARect(pipelineBuilder,
                                                    GrColor_WHITE,
                                                    viewMatrix,
                                                    element->getRect());
                     } else {
                         GrPathRenderer::DrawPathArgs args;
-                        args.fTarget = fClipTarget;
+                        args.fTarget = fDrawTarget;
                         args.fResourceProvider = this->getContext()->resourceProvider();
                         args.fPipelineBuilder = &pipelineBuilder;
                         args.fColor = GrColor_WHITE;
@@ -886,7 +885,7 @@
                 } else {
                     // The view matrix is setup to do clip space -> stencil space translation, so
                     // draw rect in clip space.
-                    fClipTarget->drawNonAARect(pipelineBuilder,
+                    fDrawTarget->drawNonAARect(pipelineBuilder,
                                                GrColor_WHITE,
                                                viewMatrix,
                                                SkRect::Make(clipSpaceIBounds));
@@ -983,8 +982,8 @@
         stencilBits = stencilAttachment->bits();
     }
 
-    SkASSERT(fClipTarget->caps()->stencilWrapOpsSupport() || !settings.usesWrapOp());
-    SkASSERT(fClipTarget->caps()->twoSidedStencilSupport() || !settings.isTwoSided());
+    SkASSERT(fDrawTarget->caps()->stencilWrapOpsSupport() || !settings.usesWrapOp());
+    SkASSERT(fDrawTarget->caps()->twoSidedStencilSupport() || !settings.isTwoSided());
     this->adjustStencilParams(&settings, fClipMode, stencilBits);
     ars->set(&pipelineBuilder);
     ars->setStencil(settings);
@@ -1005,7 +1004,7 @@
     unsigned int userBits = clipBit - 1;
 
     GrStencilSettings::Face face = GrStencilSettings::kFront_Face;
-    bool twoSided = fClipTarget->caps()->twoSidedStencilSupport();
+    bool twoSided = fDrawTarget->caps()->twoSidedStencilSupport();
 
     bool finished = false;
     while (!finished) {
diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h
index a70ebce..26afd2c 100644
--- a/src/gpu/GrClipMaskManager.h
+++ b/src/gpu/GrClipMaskManager.h
@@ -19,7 +19,7 @@
 #include "SkTLList.h"
 #include "SkTypes.h"
 
-class GrClipTarget;
+class GrDrawTarget;
 class GrPathRenderer;
 class GrPathRendererChain;
 class GrTexture;
@@ -34,7 +34,7 @@
  */
 class GrClipMaskManager : SkNoncopyable {
 public:
-    GrClipMaskManager(GrClipTarget* owner);
+    GrClipMaskManager(GrDrawTarget* owner);
 
     /**
      * Creates a clip mask if necessary as a stencil buffer or alpha texture
@@ -51,7 +51,7 @@
 
     /**
      * Purge resources to free up memory. TODO: This class shouldn't hold any long lived refs
-     * which will allow Resourcecache to automatically purge anything this class has created.
+     * which will allow GrResourceCache to automatically purge anything this class has created.
      */
     void purgeResources();
 
@@ -63,8 +63,6 @@
         return kAlpha_ClipMaskType == fCurrClipMaskType;
     }
 
-    void setClipTarget(GrClipTarget*);
-
     void adjustPathStencilParams(const GrStencilAttachment*, GrStencilSettings*);
 
 private:
@@ -184,7 +182,7 @@
     } fCurrClipMaskType;
 
     GrClipMaskCache fAACache;       // cache for the AA path
-    GrClipTarget*   fClipTarget;    // This is our owning clip target.
+    GrDrawTarget*   fDrawTarget;    // This is our owning draw target.
     StencilClipMode fClipMode;
 
     typedef SkNoncopyable INHERITED;
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index c125dd9..c7e6ca9 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -60,7 +60,7 @@
 
 void GrContext::DrawingMgr::init(GrContext* context) {
     fContext = context;
-    fDrawTarget = new GrClipTarget(context);
+    fDrawTarget = new GrDrawTarget(context->getGpu(), context->resourceProvider());
 }
 
 void GrContext::DrawingMgr::cleanup() {
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 85a9af4..6c9c386 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -34,15 +34,15 @@
 
 GrDrawTarget::GrDrawTarget(GrGpu* gpu, GrResourceProvider* resourceProvider)
     : fGpu(SkRef(gpu))
-    , fCaps(SkRef(gpu->caps()))
     , fResourceProvider(resourceProvider)
     , fFlushing(false)
     , fLastFlushToken(0) {
+    // TODO: Stop extracting the context (currently needed by GrClipMaskManager)
+    fContext = fGpu->getContext();
 }
 
 GrDrawTarget::~GrDrawTarget() {
     fGpu->unref();
-    fCaps->unref();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -78,8 +78,8 @@
     bounds.roundOut(&drawIBounds);
     if (!copyRect.intersect(drawIBounds)) {
 #ifdef SK_DEBUG
-        GrCapsDebugf(fCaps, "Missed an early reject. "
-                        "Bailing on draw from setupDstReadIfNecessary.\n");
+        GrCapsDebugf(this->caps(), "Missed an early reject. "
+                                   "Bailing on draw from setupDstReadIfNecessary.\n");
 #endif
         return false;
     }
@@ -87,7 +87,7 @@
     // MSAA consideration: When there is support for reading MSAA samples in the shader we could
     // have per-sample dst values by making the copy multisampled.
     GrSurfaceDesc desc;
-    if (!this->getGpu()->initCopySurfaceDstDesc(rt, &desc)) {
+    if (!fGpu->initCopySurfaceDstDesc(rt, &desc)) {
         desc.fOrigin = kDefault_GrSurfaceOrigin;
         desc.fFlags = kRenderTarget_GrSurfaceFlag;
         desc.fConfig = rt->config();
@@ -146,7 +146,8 @@
     GrScissorState scissorState;
     GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
     GrPipelineBuilder::AutoRestoreStencil ars;
-    if (!this->setupClip(pipelineBuilder, &arfps, &ars, &scissorState, &batch->bounds())) {
+    if (!fClipMaskManager->setupClipping(pipelineBuilder, &arfps, &ars, &scissorState,
+                                         &batch->bounds())) {
         return;
     }
 
@@ -190,7 +191,7 @@
             *outStencilSettings = even_odd_path_stencil_settings();
             break;
     }
-    this->clipMaskManager()->adjustPathStencilParams(sb, outStencilSettings);
+    fClipMaskManager->adjustPathStencilParams(sb, outStencilSettings);
 }
 
 void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder,
@@ -205,7 +206,8 @@
     GrScissorState scissorState;
     GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
     GrPipelineBuilder::AutoRestoreStencil ars;
-    if (!this->setupClip(pipelineBuilder, &arfps, &ars, &scissorState, nullptr)) {
+
+    if (!fClipMaskManager->setupClipping(pipelineBuilder, &arfps, &ars, &scissorState, nullptr)) {
         return;
     }
 
@@ -252,13 +254,15 @@
                                  GrDrawPathBatchBase* batch,
                                  GrPathRendering::FillType fill) {
     // This looks like drawBatch() but there is an added wrinkle that stencil settings get inserted
-    // after setupClip() but before onDrawBatch(). TODO: Figure out a better model for handling
-    // stencil settings WRT interactions between pipeline(builder), clipmaskmanager, and batches.
+    // after setting up clipping but before onDrawBatch(). TODO: Figure out a better model for
+    // handling stencil settings WRT interactions between pipeline(builder), clipmaskmanager, and
+    // batches.
 
     GrScissorState scissorState;
     GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
     GrPipelineBuilder::AutoRestoreStencil ars;
-    if (!this->setupClip(pipelineBuilder, &arfps, &ars, &scissorState, &batch->bounds())) {
+    if (!fClipMaskManager->setupClipping(pipelineBuilder, &arfps, &ars, &scissorState,
+                                         &batch->bounds())) {
         return;
     }
 
@@ -335,7 +339,7 @@
         rect = &clippedRect;
     }
 
-    if (fCaps->useDrawInsteadOfClear()) {
+    if (this->caps()->useDrawInsteadOfClear()) {
         // This works around a driver bug with clear by drawing a rect instead.
         // The driver will ignore a clear if it is the only thing rendered to a
         // target before the target is read.
@@ -455,33 +459,7 @@
     return true;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-GrClipTarget::GrClipTarget(GrContext* context)
-    : INHERITED(context->getGpu(), context->resourceProvider())
-    , fContext(context) {
-    fClipMaskManager.reset(new GrClipMaskManager(this));
-}
-
-
-bool GrClipTarget::setupClip(const GrPipelineBuilder& pipelineBuilder,
-                             GrPipelineBuilder::AutoRestoreFragmentProcessorState* arfps,
-                             GrPipelineBuilder::AutoRestoreStencil* ars,
-                             GrScissorState* scissorState,
-                             const SkRect* devBounds) {
-    return fClipMaskManager->setupClipping(pipelineBuilder,
-                                           arfps,
-                                           ars,
-                                           scissorState,
-                                           devBounds);
-}
-
-void GrClipTarget::purgeResources() {
-    // The clip mask manager can rebuild all its clip masks so just
-    // get rid of them all.
-    fClipMaskManager->purgeResources();
-};
-
-void GrClipTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRenderTarget* rt) {
+void GrDrawTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRenderTarget* rt) {
     GrBatch* batch = new GrClearStencilClipBatch(rect, insideClip, rt);
     this->recordBatch(batch);
     batch->unref();
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index 63d6378..cae1552 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -37,7 +37,7 @@
 class GrDrawPathBatchBase;
 class GrPathRangeDraw;
 
-class GrDrawTarget : public SkRefCnt {
+class GrDrawTarget final : public SkRefCnt {
 public:
     // The context may not be fully constructed and should not be used during GrDrawTarget
     // construction.
@@ -59,7 +59,7 @@
     /**
      * Gets the capabilities of the draw target.
      */
-    const GrCaps* caps() const { return fCaps; }
+    const GrCaps* caps() const { return fGpu->caps(); }
 
     void drawBatch(const GrPipelineBuilder&, GrDrawBatch*);
 
@@ -172,20 +172,35 @@
     /**
      * Release any resources that are cached but not currently in use. This
      * is intended to give an application some recourse when resources are low.
+     * TODO: Stop holding on to resources.
      */
-    virtual void purgeResources() {};
+    virtual void purgeResources() {
+        // The clip mask manager can rebuild all its clip masks so just get rid of them all.
+        fClipMaskManager->purgeResources();
+    };
 
     bool programUnitTest(GrContext* owner, int maxStages);
 
-protected:
-    GrGpu* getGpu() { return fGpu; }
-    const GrGpu* getGpu() const { return fGpu; }
+    /** Provides access to internal functions to GrClipMaskManager without friending all of
+        GrDrawTarget to CMM. */
+    class CMMAccess {
+    public:
+        CMMAccess(GrDrawTarget* drawTarget) : fDrawTarget(drawTarget) {}
+    private:
+        void clearStencilClip(const SkIRect& rect, bool insideClip, GrRenderTarget* rt) const {
+            fDrawTarget->clearStencilClip(rect, insideClip, rt);
+        }
 
-    void recordBatch(GrBatch*);
+        GrContext* context() const { return fDrawTarget->fContext; }
+        GrResourceProvider* resourceProvider() const { return fDrawTarget->fResourceProvider; }
+        GrDrawTarget* fDrawTarget;
+        friend class GrClipMaskManager;
+    };
+
+    const CMMAccess cmmAccess() { return CMMAccess(this); }
 
 private:
-    SkSTArray<256, SkAutoTUnref<GrBatch>, true> fBatches;
-
+    void recordBatch(GrBatch*);
     bool installPipelineInDrawBatch(const GrPipelineBuilder* pipelineBuilder,
                                     const GrScissorState* scissor,
                                     GrDrawBatch* batch);
@@ -205,63 +220,25 @@
     void getPathStencilSettingsForFilltype(GrPathRendering::FillType,
                                            const GrStencilAttachment*,
                                            GrStencilSettings*);
-    virtual GrClipMaskManager* clipMaskManager() = 0;
-    virtual bool setupClip(const GrPipelineBuilder&,
+    bool setupClip(const GrPipelineBuilder&,
                            GrPipelineBuilder::AutoRestoreFragmentProcessorState*,
                            GrPipelineBuilder::AutoRestoreStencil*,
                            GrScissorState*,
-                           const SkRect* devBounds) = 0;
+                           const SkRect* devBounds);
 
-    GrGpu*                  fGpu;
-    const GrCaps*           fCaps;
-    GrResourceProvider*     fResourceProvider;
-    bool                    fFlushing;
-    GrBatchToken            fLastFlushToken;
-
-    typedef SkRefCnt INHERITED;
-};
-
-/*
- * This class is JUST for clip mask manager.  Everyone else should just use draw target above.
- */
-class GrClipTarget : public GrDrawTarget {
-public:
-    GrClipTarget(GrContext*);
-
-    /* Clip mask manager needs access to the context.
-     * TODO we only need a very small subset of context in the CMM.
-     */
-    GrContext* getContext() { return fContext; }
-    const GrContext* getContext() const { return fContext; }
-
-    /**
-     * Clip Mask Manager(and no one else) needs to clear private stencil bits.
-     * ClipTarget subclass sets clip bit in the stencil buffer. The subclass
-     * is free to clear the remaining bits to zero if masked clears are more
-     * expensive than clearing all bits.
-     */
+    // Used only by CMM.
     void clearStencilClip(const SkIRect&, bool insideClip, GrRenderTarget*);
 
-    /**
-     * Release any resources that are cached but not currently in use. This
-     * is intended to give an application some recourse when resources are low.
-     */
-    void purgeResources() override;
+    SkSTArray<256, SkAutoTUnref<GrBatch>, true> fBatches;
+    SkAutoTDelete<GrClipMaskManager>            fClipMaskManager;
+    // The context is only in service of the clip mask manager, remove once CMM doesn't need this.
+    GrContext*                                  fContext;
+    GrGpu*                                      fGpu;
+    GrResourceProvider*                         fResourceProvider;
+    bool                                        fFlushing;
+    GrBatchToken                                fLastFlushToken;
 
-protected:
-    SkAutoTDelete<GrClipMaskManager> fClipMaskManager;
-    GrContext*                       fContext;
-
-private:
-    GrClipMaskManager* clipMaskManager() override { return fClipMaskManager; }
-
-    bool setupClip(const GrPipelineBuilder&,
-                   GrPipelineBuilder::AutoRestoreFragmentProcessorState*,
-                   GrPipelineBuilder::AutoRestoreStencil*,
-                   GrScissorState* scissorState,
-                   const SkRect* devBounds) override;
-
-    typedef GrDrawTarget INHERITED;
+    typedef SkRefCnt INHERITED;
 };
 
 #endif