Add the machinery to GrDrawTarget to enable topological sorting
This relies on https://codereview.chromium.org/1414503003/ (Add SkTTopoSort) landing first. BUG=skia:4094 Review URL: https://codereview.chromium.org/1414773002
This commit is contained in:
parent
c84ccb0702
commit
6a18665a7e
@ -45,7 +45,7 @@
|
||||
#include "SkTLazy.h"
|
||||
#include "SkTLS.h"
|
||||
#include "SkTraceEvent.h"
|
||||
|
||||
#include "SkTTopoSort.h"
|
||||
|
||||
#include "batches/GrBatch.h"
|
||||
|
||||
@ -95,9 +95,21 @@ void GrDrawingManager::reset() {
|
||||
}
|
||||
|
||||
void GrDrawingManager::flush() {
|
||||
SkDEBUGCODE(bool result =)
|
||||
SkTTopoSort<GrDrawTarget, GrDrawTarget::TopoSortTraits>(&fDrawTargets);
|
||||
SkASSERT(result);
|
||||
|
||||
for (int i = 0; i < fDrawTargets.count(); ++i) {
|
||||
fDrawTargets[i]->flush();
|
||||
}
|
||||
|
||||
#ifndef ENABLE_MDB
|
||||
// When MDB is disabled we keep reusing the same drawTarget
|
||||
if (fDrawTargets.count()) {
|
||||
SkASSERT(fDrawTargets.count() == 1);
|
||||
fDrawTargets[0]->resetFlag(GrDrawTarget::kWasOutput_Flag);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
GrTextContext* GrDrawingManager::textContext(const SkSurfaceProps& props,
|
||||
@ -131,8 +143,8 @@ GrTextContext* GrDrawingManager::textContext(const SkSurfaceProps& props,
|
||||
GrDrawTarget* GrDrawingManager::newDrawTarget(GrRenderTarget* rt) {
|
||||
SkASSERT(fContext);
|
||||
|
||||
// When MDB is disabled we always just return the single drawTarget
|
||||
#ifndef ENABLE_MDB
|
||||
// When MDB is disabled we always just return the single drawTarget
|
||||
if (fDrawTargets.count()) {
|
||||
SkASSERT(fDrawTargets.count() == 1);
|
||||
// DrawingManager gets the creation ref - this ref is for the caller
|
||||
|
@ -38,7 +38,7 @@ GrDrawTarget::GrDrawTarget(GrGpu* gpu, GrResourceProvider* resourceProvider)
|
||||
, fFlushState(fGpu, fResourceProvider, 0)
|
||||
, fFlushing(false)
|
||||
, fFirstUnpreparedBatch(0)
|
||||
, fClosed(false) {
|
||||
, fFlags(0) {
|
||||
// TODO: Stop extracting the context (currently needed by GrClipMaskManager)
|
||||
fContext = fGpu->getContext();
|
||||
fClipMaskManager.reset(new GrClipMaskManager(this));
|
||||
@ -50,6 +50,35 @@ GrDrawTarget::~GrDrawTarget() {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Add a GrDrawTarget-based dependency
|
||||
void GrDrawTarget::addDependency(GrDrawTarget* dependedOn) {
|
||||
SkASSERT(!dependedOn->dependsOn(this)); // loops are bad
|
||||
|
||||
if (this->dependsOn(dependedOn)) {
|
||||
return; // don't add duplicate dependencies
|
||||
}
|
||||
|
||||
*fDependencies.push() = dependedOn;
|
||||
}
|
||||
|
||||
// Convert from a GrSurface-based dependency to a GrDrawTarget one
|
||||
void GrDrawTarget::addDependency(GrSurface* dependedOn) {
|
||||
if (dependedOn->asRenderTarget() && dependedOn->asRenderTarget()->getLastDrawTarget()) {
|
||||
// If it is still receiving dependencies, this DT shouldn't be closed
|
||||
SkASSERT(!this->isClosed());
|
||||
|
||||
GrDrawTarget* dt = dependedOn->asRenderTarget()->getLastDrawTarget();
|
||||
if (dt == this) {
|
||||
// self-read - presumably for dst reads
|
||||
} else {
|
||||
this->addDependency(dt);
|
||||
|
||||
// Can't make it closed in the self-read case
|
||||
dt->makeClosed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuilder,
|
||||
const GrProcOptInfo& colorPOI,
|
||||
const GrProcOptInfo& coveragePOI,
|
||||
@ -414,7 +443,7 @@ template <class Left, class Right> static bool intersect(const Left& a, const Ri
|
||||
|
||||
void GrDrawTarget::recordBatch(GrBatch* batch) {
|
||||
// A closed drawTarget should never receive new/more batches
|
||||
SkASSERT(!fClosed);
|
||||
SkASSERT(!this->isClosed());
|
||||
|
||||
// Check if there is a Batch Draw we can batch with by linearly searching back until we either
|
||||
// 1) check every draw
|
||||
|
@ -53,10 +53,22 @@ public:
|
||||
// We only close drawTargets When MDB is enabled. When MDB is disabled there is only
|
||||
// ever one drawTarget and all calls will be funnelled into it.
|
||||
#ifdef ENABLE_MDB
|
||||
fClosed = true;
|
||||
this->setFlag(kClosed_Flag);
|
||||
#endif
|
||||
}
|
||||
bool isClosed() const { return fClosed; }
|
||||
bool isClosed() const { return this->isSetFlag(kClosed_Flag); }
|
||||
|
||||
/*
|
||||
* Notify this drawTarget that it relies on the contents of 'dependedOn'
|
||||
*/
|
||||
void addDependency(GrSurface* dependedOn);
|
||||
|
||||
/*
|
||||
* Does this drawTarget depend on 'dependedOn'?
|
||||
*/
|
||||
bool dependsOn(GrDrawTarget* dependedOn) const {
|
||||
return fDependencies.find(dependedOn) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empties the draw buffer of any queued up draws.
|
||||
@ -204,7 +216,53 @@ public:
|
||||
|
||||
const CMMAccess cmmAccess() { return CMMAccess(this); }
|
||||
|
||||
|
||||
private:
|
||||
friend class GrDrawingManager; // for resetFlag & TopoSortTraits
|
||||
|
||||
enum Flags {
|
||||
kClosed_Flag = 0x01, //!< This drawTarget can't accept any more batches
|
||||
|
||||
kWasOutput_Flag = 0x02, //!< Flag for topological sorting
|
||||
kTempMark_Flag = 0x04, //!< Flag for topological sorting
|
||||
};
|
||||
|
||||
void setFlag(uint32_t flag) {
|
||||
fFlags |= flag;
|
||||
}
|
||||
|
||||
void resetFlag(uint32_t flag) {
|
||||
fFlags &= ~flag;
|
||||
}
|
||||
|
||||
bool isSetFlag(uint32_t flag) const {
|
||||
return SkToBool(fFlags & flag);
|
||||
}
|
||||
|
||||
struct TopoSortTraits {
|
||||
static void Output(GrDrawTarget* dt, int /* index */) {
|
||||
dt->setFlag(GrDrawTarget::kWasOutput_Flag);
|
||||
}
|
||||
static bool WasOutput(const GrDrawTarget* dt) {
|
||||
return dt->isSetFlag(GrDrawTarget::kWasOutput_Flag);
|
||||
}
|
||||
static void SetTempMark(GrDrawTarget* dt) {
|
||||
dt->setFlag(GrDrawTarget::kTempMark_Flag);
|
||||
}
|
||||
static void ResetTempMark(GrDrawTarget* dt) {
|
||||
dt->resetFlag(GrDrawTarget::kTempMark_Flag);
|
||||
}
|
||||
static bool IsTempMarked(const GrDrawTarget* dt) {
|
||||
return dt->isSetFlag(GrDrawTarget::kTempMark_Flag);
|
||||
}
|
||||
static int NumDependencies(const GrDrawTarget* dt) {
|
||||
return dt->fDependencies.count();
|
||||
}
|
||||
static GrDrawTarget* Dependency(GrDrawTarget* dt, int index) {
|
||||
return dt->fDependencies[index];
|
||||
}
|
||||
};
|
||||
|
||||
void recordBatch(GrBatch*);
|
||||
bool installPipelineInDrawBatch(const GrPipelineBuilder* pipelineBuilder,
|
||||
const GrScissorState* scissor,
|
||||
@ -231,6 +289,8 @@ private:
|
||||
GrScissorState*,
|
||||
const SkRect* devBounds);
|
||||
|
||||
void addDependency(GrDrawTarget* dependedOn);
|
||||
|
||||
// Used only by CMM.
|
||||
void clearStencilClip(const SkIRect&, bool insideClip, GrRenderTarget*);
|
||||
|
||||
@ -244,7 +304,10 @@ private:
|
||||
bool fFlushing;
|
||||
int fFirstUnpreparedBatch;
|
||||
|
||||
bool fClosed;
|
||||
uint32_t fFlags;
|
||||
|
||||
// 'this' drawTarget relies on the output of the drawTargets in 'fDependencies'
|
||||
SkTDArray<GrDrawTarget*> fDependencies;
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user