Move GrOpFlushState out of GrDrawingManager and onto the stack

Change-Id: If1b3481af7637bfed8a73d75be41c6422319951f
Reviewed-on: https://skia-review.googlesource.com/96540
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Robert Phillips 2018-01-18 12:59:22 -05:00 committed by Skia Commit-Bot
parent 3af7f6e2ce
commit 40a29d7705
10 changed files with 81 additions and 57 deletions

View File

@ -51,7 +51,7 @@ GrTextBlobCache* SkInternalAtlasTextContext::textBlobCache() {
GrDeferredUploadToken SkInternalAtlasTextContext::addInlineUpload(
GrDeferredTextureUploadFn&& upload) {
auto token = this->nextDrawToken();
auto token = fTokenTracker.nextDrawToken();
fInlineUploads.append(&fArena, InlineUpload{std::move(upload), token});
return token;
}
@ -59,7 +59,7 @@ GrDeferredUploadToken SkInternalAtlasTextContext::addInlineUpload(
GrDeferredUploadToken SkInternalAtlasTextContext::addASAPUpload(
GrDeferredTextureUploadFn&& upload) {
fASAPUploads.append(&fArena, std::move(upload));
return this->nextTokenToFlush();
return fTokenTracker.nextTokenToFlush();
}
void SkInternalAtlasTextContext::recordDraw(const void* srcVertexData, int glyphCnt,
@ -75,7 +75,8 @@ void SkInternalAtlasTextContext::recordDraw(const void* srcVertexData, int glyph
vertex->fTextureCoord.fY /= 2;
matrix.mapHomogeneousPoints(&vertex->fPosition, &vertex->fPosition, 1);
}
fDraws.append(&fArena, Draw{glyphCnt, this->issueDrawToken(), targetHandle, vertexData});
fDraws.append(&fArena,
Draw{glyphCnt, fTokenTracker.issueDrawToken(), targetHandle, vertexData});
}
void SkInternalAtlasTextContext::flush() {
@ -109,7 +110,7 @@ void SkInternalAtlasTextContext::flush() {
auto vertices = reinterpret_cast<const SkAtlasTextRenderer::SDFVertex*>(draw.fVertexData);
fRenderer->drawSDFGlyphs(draw.fTargetHandle, fDistanceFieldAtlas.fTextureHandle, vertices,
draw.fGlyphCnt);
this->flushToken();
fTokenTracker.flushToken();
}
fASAPUploads.reset();
fInlineUploads.reset();

View File

@ -35,9 +35,9 @@ public:
GrAtlasGlyphCache* atlasGlyphCache();
GrTextBlobCache* textBlobCache();
GrDeferredUploadToken addInlineUpload(GrDeferredTextureUploadFn&&) override;
GrDeferredUploadToken addASAPUpload(GrDeferredTextureUploadFn&&) override;
const GrTokenTracker* tokenTracker() final { return &fTokenTracker; }
GrDeferredUploadToken addInlineUpload(GrDeferredTextureUploadFn&&) final;
GrDeferredUploadToken addASAPUpload(GrDeferredTextureUploadFn&&) final;
void recordDraw(const void* vertexData, int glyphCnt, const SkMatrix&, void* targetHandle);
@ -70,6 +70,7 @@ private:
GrDeferredUploadToken fToken;
};
GrTokenTracker fTokenTracker;
SkArenaAllocList<InlineUpload> fInlineUploads;
SkArenaAllocList<Draw> fDraws;
SkArenaAllocList<GrDeferredTextureUploadFn> fASAPUploads;

View File

@ -81,6 +81,34 @@ private:
uint64_t fSequenceNumber;
};
/*
* The GrTokenTracker encapsulates the incrementing and distribution of tokens.
*/
class GrTokenTracker {
public:
/** Gets the token one beyond the last token that has been flushed. */
GrDeferredUploadToken nextTokenToFlush() const { return fLastFlushedToken.next(); }
/** Gets the next draw token that will be issued by this target. This can be used by an op
to record that the next draw it issues will use a resource (e.g. texture) while preparing
that draw. */
GrDeferredUploadToken nextDrawToken() const { return fLastIssuedToken.next(); }
private:
// Only these two classes get to increment the token counters
friend class SkInternalAtlasTextContext;
friend class GrOpFlushState;
/** Issues the next token for a draw. */
GrDeferredUploadToken issueDrawToken() { return ++fLastIssuedToken; }
/** Advances the last flushed token by one. */
GrDeferredUploadToken flushToken() { return ++fLastFlushedToken; }
GrDeferredUploadToken fLastIssuedToken = GrDeferredUploadToken::AlreadyFlushedToken();
GrDeferredUploadToken fLastFlushedToken = GrDeferredUploadToken::AlreadyFlushedToken();
};
/**
* Passed to a deferred upload when it is executed, this method allows the deferred upload to
* actually write its pixel data into a texture.
@ -97,13 +125,14 @@ using GrDeferredTextureUploadWritePixelsFn =
using GrDeferredTextureUploadFn = std::function<void(GrDeferredTextureUploadWritePixelsFn&)>;
/**
* An interface for scheduling deferred uploads. It provides sequence tokens and accepts asap and
* deferred inline uploads.
* An interface for scheduling deferred uploads. It accepts asap and deferred inline uploads.
*/
class GrDeferredUploadTarget {
public:
virtual ~GrDeferredUploadTarget() {}
virtual const GrTokenTracker* tokenTracker() = 0;
/** Returns the token of the draw that this upload will occur before. */
virtual GrDeferredUploadToken addInlineUpload(GrDeferredTextureUploadFn&&) = 0;
@ -111,28 +140,6 @@ public:
are done first during a flush, this will be the first token since the most recent
flush. */
virtual GrDeferredUploadToken addASAPUpload(GrDeferredTextureUploadFn&& upload) = 0;
/** Gets the token one beyond the last token that has been flushed. */
GrDeferredUploadToken nextTokenToFlush() const { return fLastFlushedToken.next(); }
/** Gets the next draw token that will be issued by this target. This can be used by an op
to record that the next draw it issues will use a resource (e.g. texture) while preparing
that draw. */
GrDeferredUploadToken nextDrawToken() const { return fLastIssuedToken.next(); }
protected:
// Methods that advance the internal tokens are protected so that the subclass can determine
// access.
/** Issues the next token for a draw. */
GrDeferredUploadToken issueDrawToken() { return ++fLastIssuedToken; }
/** Advances the last flushed token by one. */
GrDeferredUploadToken flushToken() { return ++fLastFlushedToken; }
private:
GrDeferredUploadToken fLastIssuedToken = GrDeferredUploadToken::AlreadyFlushedToken();
GrDeferredUploadToken fLastFlushedToken = GrDeferredUploadToken::AlreadyFlushedToken();
};
#endif

View File

@ -182,7 +182,7 @@ inline bool GrDrawOpAtlas::updatePlot(GrDeferredUploadTarget* target, AtlasID* i
// If our most recent upload has already occurred then we have to insert a new
// upload. Otherwise, we already have a scheduled upload that hasn't yet ocurred.
// This new update will piggy back on that previously scheduled update.
if (plot->lastUploadToken() < target->nextTokenToFlush()) {
if (plot->lastUploadToken() < target->tokenTracker()->nextTokenToFlush()) {
// With c+14 we could move sk_sp into lamba to only ref once.
sk_sp<Plot> plotsp(SkRef(plot));
@ -244,7 +244,8 @@ bool GrDrawOpAtlas::addToAtlas(AtlasID* id, GrDeferredUploadTarget* target, int
for (unsigned int pageIdx = 0; pageIdx < fNumPages; ++pageIdx) {
Plot* plot = fPages[pageIdx].fPlotList.tail();
SkASSERT(plot);
if ((fNumPages == this->maxPages() && plot->lastUseToken() < target->nextTokenToFlush()) ||
if ((fNumPages == this->maxPages() &&
plot->lastUseToken() < target->tokenTracker()->nextTokenToFlush()) ||
plot->flushesSinceLastUsed() >= kRecentlyUsedCount) {
this->processEvictionAndResetRects(plot);
SkASSERT(GrBytesPerPixel(fProxies[pageIdx]->config()) == plot->bpp());
@ -277,7 +278,7 @@ bool GrDrawOpAtlas::addToAtlas(AtlasID* id, GrDeferredUploadTarget* target, int
Plot* plot = nullptr;
for (int pageIdx = (int)(fNumPages-1); pageIdx >= 0; --pageIdx) {
Plot* currentPlot = fPages[pageIdx].fPlotList.tail();
if (currentPlot->lastUseToken() != target->nextDrawToken()) {
if (currentPlot->lastUseToken() != target->tokenTracker()->nextDrawToken()) {
plot = currentPlot;
break;
}

View File

@ -121,6 +121,10 @@ GrSemaphoresSubmitted GrDrawingManager::internalFlush(GrSurfaceProxy*,
SkASSERT(result);
#endif
GrOpFlushState flushState(fContext->getGpu(),
fContext->contextPriv().resourceProvider(),
&fTokenTracker);
GrOnFlushResourceProvider onFlushProvider(this);
// TODO: AFAICT the only reason fFlushState is on GrDrawingManager rather than on the
// stack here is to preserve the flush tokens.
@ -150,7 +154,7 @@ GrSemaphoresSubmitted GrDrawingManager::internalFlush(GrSurfaceProxy*,
});
#endif
onFlushOpList->makeClosed(*fContext->caps());
onFlushOpList->prepare(&fFlushState);
onFlushOpList->prepare(&flushState);
fOnFlushCBOpLists.push_back(std::move(onFlushOpList));
}
renderTargetContexts.reset();
@ -181,7 +185,7 @@ GrSemaphoresSubmitted GrDrawingManager::internalFlush(GrSurfaceProxy*,
while (alloc.assign(&startIndex, &stopIndex))
#endif
{
if (this->executeOpLists(startIndex, stopIndex, &fFlushState)) {
if (this->executeOpLists(startIndex, stopIndex, &flushState)) {
flushed = true;
}
}
@ -197,7 +201,7 @@ GrSemaphoresSubmitted GrDrawingManager::internalFlush(GrSurfaceProxy*,
fContext->contextPriv().getResourceCache()->notifyFlushOccurred(type);
}
for (GrOnFlushCallbackObject* onFlushCBObject : fOnFlushCBObjects) {
onFlushCBObject->postFlush(fFlushState.nextTokenToFlush(), fFlushingOpListIDs.begin(),
onFlushCBObject->postFlush(fTokenTracker.nextTokenToFlush(), fFlushingOpListIDs.begin(),
fFlushingOpListIDs.count());
}
fFlushingOpListIDs.reset();
@ -257,7 +261,7 @@ bool GrDrawingManager::executeOpLists(int startIndex, int stopIndex, GrOpFlushSt
}
SkASSERT(!flushState->commandBuffer());
SkASSERT(flushState->nextDrawToken() == flushState->nextTokenToFlush());
SkASSERT(fTokenTracker.nextDrawToken() == fTokenTracker.nextTokenToFlush());
// We reset the flush state before the OpLists so that the last resources to be freed are those
// that are written to in the OpLists. This helps to make sure the most recently used resources

View File

@ -8,7 +8,6 @@
#ifndef GrDrawingManager_DEFINED
#define GrDrawingManager_DEFINED
#include "GrOpFlushState.h"
#include "GrPathRenderer.h"
#include "GrPathRendererChain.h"
#include "GrRenderTargetOpList.h"
@ -92,7 +91,6 @@ private:
, fAtlasTextContext(nullptr)
, fPathRendererChain(nullptr)
, fSoftwarePathRenderer(nullptr)
, fFlushState(context->getGpu(), context->contextPriv().resourceProvider())
, fFlushing(false) {}
void abandon();
@ -138,7 +136,7 @@ private:
GrPathRendererChain* fPathRendererChain;
GrSoftwarePathRenderer* fSoftwarePathRenderer;
GrOpFlushState fFlushState;
GrTokenTracker fTokenTracker;
bool fFlushing;
SkTArray<GrOnFlushCallbackObject*> fOnFlushCBObjects;

View File

@ -14,8 +14,15 @@
//////////////////////////////////////////////////////////////////////////////
GrOpFlushState::GrOpFlushState(GrGpu* gpu, GrResourceProvider* resourceProvider)
: fVertexPool(gpu), fIndexPool(gpu), fGpu(gpu), fResourceProvider(resourceProvider) {}
GrOpFlushState::GrOpFlushState(GrGpu* gpu,
GrResourceProvider* resourceProvider,
GrTokenTracker* tokenTracker)
: fVertexPool(gpu)
, fIndexPool(gpu)
, fGpu(gpu)
, fResourceProvider(resourceProvider)
, fTokenTracker(tokenTracker) {
}
const GrCaps& GrOpFlushState::caps() const {
return *fGpu->caps();
@ -28,7 +35,7 @@ GrGpuRTCommandBuffer* GrOpFlushState::rtCommandBuffer() {
void GrOpFlushState::executeDrawsAndUploadsForMeshDrawOp(uint32_t opID, const SkRect& opBounds) {
SkASSERT(this->rtCommandBuffer());
while (fCurrDraw != fDraws.end() && fCurrDraw->fOpID == opID) {
GrDeferredUploadToken drawToken = this->nextTokenToFlush();
GrDeferredUploadToken drawToken = fTokenTracker->nextTokenToFlush();
while (fCurrUpload != fInlineUploads.end() &&
fCurrUpload->fUploadBeforeToken == drawToken) {
this->rtCommandBuffer()->inlineUpload(this, fCurrUpload->fUpload);
@ -39,7 +46,7 @@ void GrOpFlushState::executeDrawsAndUploadsForMeshDrawOp(uint32_t opID, const Sk
fMeshes.begin() + fCurrMesh, nullptr, fCurrDraw->fMeshCnt,
opBounds);
fCurrMesh += fCurrDraw->fMeshCnt;
this->flushToken();
fTokenTracker->flushToken();
++fCurrDraw;
}
}
@ -47,7 +54,7 @@ void GrOpFlushState::executeDrawsAndUploadsForMeshDrawOp(uint32_t opID, const Sk
void GrOpFlushState::preExecuteDraws() {
fVertexPool.unmap();
fIndexPool.unmap();
for (auto& upload : fAsapUploads) {
for (auto& upload : fASAPUploads) {
this->doUpload(upload);
}
// Setup execution iterators.
@ -62,7 +69,7 @@ void GrOpFlushState::reset() {
fVertexPool.reset();
fIndexPool.reset();
fArena.reset();
fAsapUploads.reset();
fASAPUploads.reset();
fInlineUploads.reset();
fDraws.reset();
fMeshes.reset();
@ -104,13 +111,13 @@ void GrOpFlushState::doUpload(GrDeferredTextureUploadFn& upload) {
}
GrDeferredUploadToken GrOpFlushState::addInlineUpload(GrDeferredTextureUploadFn&& upload) {
return fInlineUploads.append(&fArena, std::move(upload), this->nextDrawToken())
return fInlineUploads.append(&fArena, std::move(upload), fTokenTracker->nextDrawToken())
.fUploadBeforeToken;
}
GrDeferredUploadToken GrOpFlushState::addASAPUpload(GrDeferredTextureUploadFn&& upload) {
fAsapUploads.append(&fArena, std::move(upload));
return this->nextTokenToFlush();
fASAPUploads.append(&fArena, std::move(upload));
return fTokenTracker->nextTokenToFlush();
}
void GrOpFlushState::draw(const GrGeometryProcessor* gp, const GrPipeline* pipeline,
@ -125,14 +132,14 @@ void GrOpFlushState::draw(const GrGeometryProcessor* gp, const GrPipeline* pipel
// uploads, add this mesh to it.
if (lastDraw.fGeometryProcessor == gp && lastDraw.fPipeline == pipeline) {
if (fInlineUploads.begin() == fInlineUploads.end() ||
fInlineUploads.tail()->fUploadBeforeToken != this->nextDrawToken()) {
fInlineUploads.tail()->fUploadBeforeToken != fTokenTracker->nextDrawToken()) {
++lastDraw.fMeshCnt;
return;
}
}
}
auto& draw = fDraws.append(&fArena);
GrDeferredUploadToken token = this->issueDrawToken();
GrDeferredUploadToken token = fTokenTracker->issueDrawToken();
draw.fGeometryProcessor.reset(gp);
draw.fPipeline = pipeline;

View File

@ -24,7 +24,7 @@ class GrResourceProvider;
/** Tracks the state across all the GrOps (really just the GrDrawOps) in a GrOpList flush. */
class GrOpFlushState final : public GrDeferredUploadTarget, public GrMeshDrawOp::Target {
public:
GrOpFlushState(GrGpu*, GrResourceProvider*);
GrOpFlushState(GrGpu*, GrResourceProvider*, GrTokenTracker*);
~GrOpFlushState() final { this->reset(); }
@ -67,6 +67,7 @@ public:
/** Overrides of GrDeferredUploadTarget. */
const GrTokenTracker* tokenTracker() final { return fTokenTracker; }
GrDeferredUploadToken addInlineUpload(GrDeferredTextureUploadFn&&) final;
GrDeferredUploadToken addASAPUpload(GrDeferredTextureUploadFn&&) final;
@ -119,7 +120,7 @@ private:
GrIndexBufferAllocPool fIndexPool;
// Data stored on behalf of the ops being flushed.
SkArenaAllocList<GrDeferredTextureUploadFn> fAsapUploads;
SkArenaAllocList<GrDeferredTextureUploadFn> fASAPUploads;
SkArenaAllocList<InlineUpload> fInlineUploads;
SkArenaAllocList<Draw> fDraws;
// TODO: These should go in the arena. However, GrGpuCommandBuffer and other classes currently
@ -136,6 +137,7 @@ private:
GrGpu* fGpu;
GrResourceProvider* fResourceProvider;
GrTokenTracker* fTokenTracker;
GrGpuCommandBuffer* fCommandBuffer = nullptr;
// Variables that are used to track where we are in lists as ops are executed

View File

@ -381,7 +381,8 @@ private:
}
}
atlas->setLastUseToken(shapeData->fID, target->deferredUploadTarget()->nextDrawToken());
auto uploadTarget = target->deferredUploadTarget();
atlas->setLastUseToken(shapeData->fID, uploadTarget->tokenTracker()->nextDrawToken());
this->writePathVertices(atlas,
offset,

View File

@ -241,8 +241,9 @@ Regenerator::Result Regenerator::doRegen() {
result.fFinished = false;
return result;
}
auto tokenTracker = fUploadTarget->tokenTracker();
fGlyphCache->addGlyphToBulkAndSetUseToken(fSubRun->bulkUseToken(), glyph,
fUploadTarget->nextDrawToken());
tokenTracker->nextDrawToken());
}
regen_vertices<regenPos, regenCol, regenTexCoords>(currVertex, glyph, vertexStride,
@ -310,7 +311,8 @@ Regenerator::Result Regenerator::regenerate() {
// set use tokens for all of the glyphs in our subrun. This is only valid if we
// have a valid atlas generation
fGlyphCache->setUseTokenBulk(*fSubRun->bulkUseToken(), fUploadTarget->nextDrawToken(),
fGlyphCache->setUseTokenBulk(*fSubRun->bulkUseToken(),
fUploadTarget->tokenTracker()->nextDrawToken(),
fSubRun->maskFormat());
return result;
}