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
This commit is contained in:
robertphillips 2015-10-20 13:41:16 -07:00 committed by Commit bot
parent 964eebae2d
commit 45a1c34f60
6 changed files with 55 additions and 5 deletions

View File

@ -32,13 +32,14 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
GrDrawTarget::GrDrawTarget(GrGpu* gpu, GrResourceProvider* resourceProvider) GrDrawTarget::GrDrawTarget(GrRenderTarget* rt, GrGpu* gpu, GrResourceProvider* resourceProvider)
: fGpu(SkRef(gpu)) : fGpu(SkRef(gpu))
, fResourceProvider(resourceProvider) , fResourceProvider(resourceProvider)
, fFlushState(fGpu, fResourceProvider, 0) , fFlushState(fGpu, fResourceProvider, 0)
, fFlushing(false) , fFlushing(false)
, fFirstUnpreparedBatch(0) , fFirstUnpreparedBatch(0)
, fFlags(0) { , fFlags(0)
, fRenderTarget(rt) {
// TODO: Stop extracting the context (currently needed by GrClipMaskManager) // TODO: Stop extracting the context (currently needed by GrClipMaskManager)
fContext = fGpu->getContext(); fContext = fGpu->getContext();
fClipMaskManager.reset(new GrClipMaskManager(this)); fClipMaskManager.reset(new GrClipMaskManager(this));
@ -50,6 +51,10 @@ GrDrawTarget::GrDrawTarget(GrGpu* gpu, GrResourceProvider* resourceProvider)
} }
GrDrawTarget::~GrDrawTarget() { GrDrawTarget::~GrDrawTarget() {
if (fRenderTarget && this == fRenderTarget->getLastDrawTarget()) {
fRenderTarget->setLastDrawTarget(nullptr);
}
fGpu->unref(); fGpu->unref();
} }
@ -182,7 +187,7 @@ void GrDrawTarget::flush() {
// drawTargets will be created to replace them if the SkGpuDevice(s) write to them again. // drawTargets will be created to replace them if the SkGpuDevice(s) write to them again.
this->makeClosed(); 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) { for (; fFirstUnpreparedBatch < fBatches.count(); ++fFirstUnpreparedBatch) {
fBatches[fFirstUnpreparedBatch]->prepare(&fFlushState); fBatches[fFirstUnpreparedBatch]->prepare(&fFlushState);
} }
@ -227,6 +232,10 @@ void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, GrDrawBat
return; return;
} }
#ifdef ENABLE_MDB
batch->pipeline()->addDependenciesTo(fRenderTarget);
#endif
this->recordBatch(batch); this->recordBatch(batch);
} }
@ -458,6 +467,10 @@ void GrDrawTarget::copySurface(GrSurface* dst,
const SkIPoint& dstPoint) { const SkIPoint& dstPoint) {
GrBatch* batch = GrCopySurfaceBatch::Create(dst, src, srcRect, dstPoint); GrBatch* batch = GrCopySurfaceBatch::Create(dst, src, srcRect, dstPoint);
if (batch) { if (batch) {
#ifdef ENABLE_MDB
this->addDependency(src);
#endif
this->recordBatch(batch); this->recordBatch(batch);
batch->unref(); batch->unref();
} }

View File

@ -45,7 +45,7 @@ class GrDrawTarget final : public SkRefCnt {
public: public:
// The context may not be fully constructed and should not be used during GrDrawTarget // The context may not be fully constructed and should not be used during GrDrawTarget
// construction. // construction.
GrDrawTarget(GrGpu* gpu, GrResourceProvider*); GrDrawTarget(GrRenderTarget* rt, GrGpu* gpu, GrResourceProvider*);
~GrDrawTarget() override; ~GrDrawTarget() override;
@ -314,6 +314,7 @@ private:
// 'this' drawTarget relies on the output of the drawTargets in 'fDependencies' // 'this' drawTarget relies on the output of the drawTargets in 'fDependencies'
SkTDArray<GrDrawTarget*> fDependencies; SkTDArray<GrDrawTarget*> fDependencies;
GrRenderTarget* fRenderTarget;
typedef SkRefCnt INHERITED; typedef SkRefCnt INHERITED;
}; };

View File

@ -105,7 +105,7 @@ GrDrawTarget* GrDrawingManager::newDrawTarget(GrRenderTarget* rt) {
} }
#endif #endif
GrDrawTarget* dt = new GrDrawTarget(fContext->getGpu(), fContext->resourceProvider()); GrDrawTarget* dt = new GrDrawTarget(rt, fContext->getGpu(), fContext->resourceProvider());
*fDrawTargets.append() = dt; *fDrawTargets.append() = dt;

View File

@ -8,6 +8,7 @@
#include "GrPipeline.h" #include "GrPipeline.h"
#include "GrCaps.h" #include "GrCaps.h"
#include "GrDrawTarget.h"
#include "GrGpu.h" #include "GrGpu.h"
#include "GrPipelineBuilder.h" #include "GrPipelineBuilder.h"
#include "GrProcOptInfo.h" #include "GrProcOptInfo.h"
@ -130,6 +131,35 @@ GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args,
return pipeline; 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, void GrPipeline::adjustProgramFromOptimizations(const GrPipelineBuilder& pipelineBuilder,
GrXferProcessor::OptFlags flags, GrXferProcessor::OptFlags flags,
const GrProcOptInfo& colorPOI, const GrProcOptInfo& colorPOI,

View File

@ -84,6 +84,9 @@ public:
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
/// @name GrFragmentProcessors /// @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 numColorFragmentProcessors() const { return fNumColorProcessors; }
int numCoverageFragmentProcessors() const { int numCoverageFragmentProcessors() const {

View File

@ -71,7 +71,10 @@ void GrRenderTarget::onAbandon() {
void GrRenderTarget::setLastDrawTarget(GrDrawTarget* dt) { void GrRenderTarget::setLastDrawTarget(GrDrawTarget* dt) {
if (fLastDrawTarget) { if (fLastDrawTarget) {
// The non-MDB world never closes so we can't check this condition
#ifdef ENABLE_MDB
SkASSERT(fLastDrawTarget->isClosed()); SkASSERT(fLastDrawTarget->isClosed());
#endif
} }
fLastDrawTarget = dt; fLastDrawTarget = dt;