From 45a1c34f607a970933e5cd05e1df6cd8090db1be Mon Sep 17 00:00:00 2001 From: robertphillips Date: Tue, 20 Oct 2015 13:41:16 -0700 Subject: [PATCH] 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 Review URL: https://codereview.chromium.org/1414903002 --- src/gpu/GrDrawTarget.cpp | 19 ++++++++++++++++--- src/gpu/GrDrawTarget.h | 3 ++- src/gpu/GrDrawingManager.cpp | 2 +- src/gpu/GrPipeline.cpp | 30 ++++++++++++++++++++++++++++++ src/gpu/GrPipeline.h | 3 +++ src/gpu/GrRenderTarget.cpp | 3 +++ 6 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index f42ee111ce..8b2267cad6 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -32,13 +32,14 @@ //////////////////////////////////////////////////////////////////////////////// -GrDrawTarget::GrDrawTarget(GrGpu* gpu, GrResourceProvider* resourceProvider) +GrDrawTarget::GrDrawTarget(GrRenderTarget* rt, GrGpu* gpu, GrResourceProvider* resourceProvider) : fGpu(SkRef(gpu)) , fResourceProvider(resourceProvider) , fFlushState(fGpu, fResourceProvider, 0) , fFlushing(false) , fFirstUnpreparedBatch(0) - , fFlags(0) { + , fFlags(0) + , fRenderTarget(rt) { // TODO: Stop extracting the context (currently needed by GrClipMaskManager) fContext = fGpu->getContext(); fClipMaskManager.reset(new GrClipMaskManager(this)); @@ -50,6 +51,10 @@ GrDrawTarget::GrDrawTarget(GrGpu* gpu, GrResourceProvider* resourceProvider) } GrDrawTarget::~GrDrawTarget() { + if (fRenderTarget && this == fRenderTarget->getLastDrawTarget()) { + fRenderTarget->setLastDrawTarget(nullptr); + } + fGpu->unref(); } @@ -182,7 +187,7 @@ void GrDrawTarget::flush() { // 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,10 @@ void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, GrDrawBat return; } +#ifdef ENABLE_MDB + batch->pipeline()->addDependenciesTo(fRenderTarget); +#endif + this->recordBatch(batch); } @@ -458,6 +467,10 @@ void GrDrawTarget::copySurface(GrSurface* dst, 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 ec94da1f0e..32a3fc4fe1 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -45,7 +45,7 @@ class GrDrawTarget final : public SkRefCnt { public: // The context may not be fully constructed and should not be used during GrDrawTarget // construction. - GrDrawTarget(GrGpu* gpu, GrResourceProvider*); + GrDrawTarget(GrRenderTarget* rt, GrGpu* gpu, GrResourceProvider*); ~GrDrawTarget() override; @@ -314,6 +314,7 @@ private: // 'this' drawTarget relies on the output of the drawTargets in 'fDependencies' SkTDArray fDependencies; + GrRenderTarget* fRenderTarget; typedef SkRefCnt INHERITED; }; diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp index 682b15511a..c3cc170a82 100644 --- a/src/gpu/GrDrawingManager.cpp +++ b/src/gpu/GrDrawingManager.cpp @@ -105,7 +105,7 @@ GrDrawTarget* GrDrawingManager::newDrawTarget(GrRenderTarget* rt) { } #endif - GrDrawTarget* dt = new GrDrawTarget(fContext->getGpu(), fContext->resourceProvider()); + GrDrawTarget* dt = new GrDrawTarget(rt, fContext->getGpu(), fContext->resourceProvider()); *fDrawTargets.append() = dt; diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp index 80e3cbdf69..073349be1e 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 @@ GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args, 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 df44ba680c..8781058247 100644 --- a/src/gpu/GrPipeline.h +++ b/src/gpu/GrPipeline.h @@ -84,6 +84,9 @@ public: /////////////////////////////////////////////////////////////////////////// /// @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 ad56cf761f..d519f028f0 100644 --- a/src/gpu/GrRenderTarget.cpp +++ b/src/gpu/GrRenderTarget.cpp @@ -71,7 +71,10 @@ void GrRenderTarget::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 = dt;