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:
parent
3af7f6e2ce
commit
40a29d7705
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user