Dependencies are now added between the drawTargets in GrPipeline

This CL relies on https://codereview.chromium.org/1414773002/ (Add the machinery to GrDrawTarget to enable topological sorting)

BUG=skia:4094

Committed: https://skia.googlesource.com/skia/+/45a1c34f607a970933e5cd05e1df6cd8090db1be

Committed: https://skia.googlesource.com/skia/+/869c5e82a725a6928a45cd1fa6945ac783b8b3d8

Review URL: https://codereview.chromium.org/1414903002
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 5a3fecc..7b1464c 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -32,7 +32,7 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-GrDrawTarget::GrDrawTarget(GrGpu* gpu, GrResourceProvider* resourceProvider,
+GrDrawTarget::GrDrawTarget(GrRenderTarget* rt, GrGpu* gpu, GrResourceProvider* resourceProvider,
                            const Options& options)
     : fGpu(SkRef(gpu))
     , fResourceProvider(resourceProvider)
@@ -40,7 +40,8 @@
     , fFlushing(false)
     , fFirstUnpreparedBatch(0)
     , fFlags(0)
-    , fOptions(options) {
+    , fOptions(options)
+    , fRenderTarget(rt) {
     // TODO: Stop extracting the context (currently needed by GrClipMaskManager)
     fContext = fGpu->getContext();
     fClipMaskManager.reset(new GrClipMaskManager(this));
@@ -52,6 +53,10 @@
 }
 
 GrDrawTarget::~GrDrawTarget() {
+    if (fRenderTarget && this == fRenderTarget->getLastDrawTarget()) {
+        fRenderTarget->setLastDrawTarget(nullptr);
+    }
+
     fGpu->unref();
 }
 
@@ -184,7 +189,7 @@
     // drawTargets will be created to replace them if the SkGpuDevice(s) write to them again.
     this->makeClosed();
 
-    // Loop over all batches and generate geometry
+    // Loop over the batches that haven't yet generated their geometry
     for (; fFirstUnpreparedBatch < fBatches.count(); ++fFirstUnpreparedBatch) {
         fBatches[fFirstUnpreparedBatch]->prepare(&fFlushState);
     }
@@ -227,6 +232,11 @@
         return;
     }
 
+#ifdef ENABLE_MDB
+    SkASSERT(fRenderTarget);
+    batch->pipeline()->addDependenciesTo(fRenderTarget);
+#endif
+
     this->recordBatch(batch);
 }
 
@@ -455,6 +465,10 @@
                                const SkIPoint& dstPoint) {
     GrBatch* batch = GrCopySurfaceBatch::Create(dst, src, srcRect, dstPoint);
     if (batch) {
+#ifdef ENABLE_MDB
+        this->addDependency(src);
+#endif
+
         this->recordBatch(batch);
         batch->unref();
     }
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index a487785..d77615e 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -33,6 +33,8 @@
 #include "SkTypes.h"
 #include "SkXfermode.h"
 
+//#define ENABLE_MDB 1
+
 class GrBatch;
 class GrBatchFlushState;
 class GrClip;
@@ -49,7 +51,7 @@
 
     // The context may not be fully constructed and should not be used during GrDrawTarget
     // construction.
-    GrDrawTarget(GrGpu* gpu, GrResourceProvider*, const Options& options);
+    GrDrawTarget(GrRenderTarget* rt, GrGpu* gpu, GrResourceProvider*, const Options& options);
 
     ~GrDrawTarget() override;
 
@@ -62,6 +64,10 @@
     }
     bool isClosed() const { return this->isSetFlag(kClosed_Flag); }
 
+    // TODO: this entry point is only needed in the non-MDB world. Remove when
+    // we make the switch to MDB
+    void clearRT() { fRenderTarget = nullptr; }
+
     /*
      * Notify this drawTarget that it relies on the contents of 'dependedOn'
      */
@@ -318,6 +324,7 @@
 
     // 'this' drawTarget relies on the output of the drawTargets in 'fDependencies'
     SkTDArray<GrDrawTarget*>                    fDependencies;
+    GrRenderTarget*                             fRenderTarget;
 
     typedef SkRefCnt INHERITED;
 };
diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp
index 4483a15..bfb586b 100644
--- a/src/gpu/GrDrawingManager.cpp
+++ b/src/gpu/GrDrawingManager.cpp
@@ -14,6 +14,8 @@
 #include "GrStencilAndCoverTextContext.h"
 #include "SkTTopoSort.h"
 
+//#define ENABLE_MDB 1
+
 void GrDrawingManager::cleanup() {
     for (int i = 0; i < fDrawTargets.count(); ++i) {
         fDrawTargets[i]->unref();
@@ -117,7 +119,7 @@
     }
 #endif
 
-    GrDrawTarget* dt = new GrDrawTarget(fContext->getGpu(), fContext->resourceProvider(),
+    GrDrawTarget* dt = new GrDrawTarget(rt, fContext->getGpu(), fContext->resourceProvider(),
                                         fOptions);
 
     *fDrawTargets.append() = dt;
diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp
index 80e3cbd..073349b 100644
--- a/src/gpu/GrPipeline.cpp
+++ b/src/gpu/GrPipeline.cpp
@@ -8,6 +8,7 @@
 #include "GrPipeline.h"
 
 #include "GrCaps.h"
+#include "GrDrawTarget.h"
 #include "GrGpu.h"
 #include "GrPipelineBuilder.h"
 #include "GrProcOptInfo.h"
@@ -130,6 +131,35 @@
     return pipeline;
 }
 
+static void add_dependencies_for_processor(const GrFragmentProcessor* proc, GrRenderTarget* rt) {
+    for (int i = 0; i < proc->numChildProcessors(); ++i) {
+        // need to recurse
+        add_dependencies_for_processor(&proc->childProcessor(i), rt);
+    }
+
+    for (int i = 0; i < proc->numTextures(); ++i) {
+        GrTexture* texture = proc->textureAccess(i).getTexture();
+        SkASSERT(rt->getLastDrawTarget());
+        rt->getLastDrawTarget()->addDependency(texture);
+    }
+}
+
+void GrPipeline::addDependenciesTo(GrRenderTarget* rt) const {
+    for (int i = 0; i < fFragmentProcessors.count(); ++i) {
+        add_dependencies_for_processor(fFragmentProcessors[i].get(), rt);
+    }
+
+    if (fXferProcessor.get()) {
+        const GrXferProcessor* xfer = fXferProcessor.get();
+
+        for (int i = 0; i < xfer->numTextures(); ++i) {
+            GrTexture* texture = xfer->textureAccess(i).getTexture();   
+            SkASSERT(rt->getLastDrawTarget());
+            rt->getLastDrawTarget()->addDependency(texture);
+        }
+    }
+}
+
 void GrPipeline::adjustProgramFromOptimizations(const GrPipelineBuilder& pipelineBuilder,
                                                 GrXferProcessor::OptFlags flags,
                                                 const GrProcOptInfo& colorPOI,
diff --git a/src/gpu/GrPipeline.h b/src/gpu/GrPipeline.h
index df44ba6..8781058 100644
--- a/src/gpu/GrPipeline.h
+++ b/src/gpu/GrPipeline.h
@@ -84,6 +84,9 @@
     ///////////////////////////////////////////////////////////////////////////
     /// @name GrFragmentProcessors
 
+    // Make the renderTarget's drawTarget (if it exists) be dependent on any
+    // drawTargets in this pipeline
+    void addDependenciesTo(GrRenderTarget* rt) const;
 
     int numColorFragmentProcessors() const { return fNumColorProcessors; }
     int numCoverageFragmentProcessors() const {
diff --git a/src/gpu/GrRenderTarget.cpp b/src/gpu/GrRenderTarget.cpp
index ad56cf7..e547021 100644
--- a/src/gpu/GrRenderTarget.cpp
+++ b/src/gpu/GrRenderTarget.cpp
@@ -16,6 +16,13 @@
 #include "GrRenderTargetPriv.h"
 #include "GrStencilAttachment.h"
 
+GrRenderTarget::~GrRenderTarget() {
+    if (fLastDrawTarget) {
+        fLastDrawTarget->clearRT();
+    }
+    SkSafeUnref(fLastDrawTarget);
+}
+
 void GrRenderTarget::discard() {
     // go through context so that all necessary flushing occurs
     GrContext* context = this->getContext();
@@ -57,24 +64,30 @@
 
 void GrRenderTarget::onRelease() {
     SkSafeSetNull(fStencilAttachment);
-    fLastDrawTarget = nullptr;
 
     INHERITED::onRelease();
 }
 
 void GrRenderTarget::onAbandon() {
     SkSafeSetNull(fStencilAttachment);
-    fLastDrawTarget = nullptr;
+
+    // The contents of this renderTarget are gone/invalid. It isn't useful to point back
+    // the creating drawTarget.
+    this->setLastDrawTarget(nullptr);
 
     INHERITED::onAbandon();
 }
 
 void GrRenderTarget::setLastDrawTarget(GrDrawTarget* dt) {
     if (fLastDrawTarget) {
+        // The non-MDB world never closes so we can't check this condition
+#ifdef ENABLE_MDB
         SkASSERT(fLastDrawTarget->isClosed());
+#endif
+        fLastDrawTarget->clearRT();
     }
 
-    fLastDrawTarget = dt;
+    SkRefCnt_SafeAssign(fLastDrawTarget, dt);
 }
 
 ///////////////////////////////////////////////////////////////////////////////