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
This commit is contained in:
robertphillips 2015-10-30 10:11:30 -07:00 committed by Commit bot
parent f93982a477
commit 498d7ac86b
7 changed files with 79 additions and 8 deletions

View File

@ -165,6 +165,8 @@ protected:
fResolveRect.setLargestInverted();
}
~GrRenderTarget() override;
// override of GrResource
void onAbandon() override;
void onRelease() override;

View File

@ -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 @@ GrDrawTarget::GrDrawTarget(GrGpu* gpu, GrResourceProvider* resourceProvider,
, 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(GrGpu* gpu, GrResourceProvider* resourceProvider,
}
GrDrawTarget::~GrDrawTarget() {
if (fRenderTarget && this == fRenderTarget->getLastDrawTarget()) {
fRenderTarget->setLastDrawTarget(nullptr);
}
fGpu->unref();
}
@ -184,7 +189,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,11 @@ void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, GrDrawBat
return;
}
#ifdef ENABLE_MDB
SkASSERT(fRenderTarget);
batch->pipeline()->addDependenciesTo(fRenderTarget);
#endif
this->recordBatch(batch);
}
@ -455,6 +465,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();
}

View File

@ -33,6 +33,8 @@
#include "SkTypes.h"
#include "SkXfermode.h"
//#define ENABLE_MDB 1
class GrBatch;
class GrBatchFlushState;
class GrClip;
@ -49,7 +51,7 @@ public:
// 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 @@ public:
}
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 @@ private:
// 'this' drawTarget relies on the output of the drawTargets in 'fDependencies'
SkTDArray<GrDrawTarget*> fDependencies;
GrRenderTarget* fRenderTarget;
typedef SkRefCnt INHERITED;
};

View File

@ -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 @@ GrDrawTarget* GrDrawingManager::newDrawTarget(GrRenderTarget* rt) {
}
#endif
GrDrawTarget* dt = new GrDrawTarget(fContext->getGpu(), fContext->resourceProvider(),
GrDrawTarget* dt = new GrDrawTarget(rt, fContext->getGpu(), fContext->resourceProvider(),
fOptions);
*fDrawTargets.append() = dt;

View File

@ -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,

View File

@ -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 {

View File

@ -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::overrideResolveRect(const SkIRect rect) {
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);
}
///////////////////////////////////////////////////////////////////////////////