diff --git a/src/atlastext/SkInternalAtlasTextContext.cpp b/src/atlastext/SkInternalAtlasTextContext.cpp index 6dde9ae096..fba0cbcdbe 100644 --- a/src/atlastext/SkInternalAtlasTextContext.cpp +++ b/src/atlastext/SkInternalAtlasTextContext.cpp @@ -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(draw.fVertexData); fRenderer->drawSDFGlyphs(draw.fTargetHandle, fDistanceFieldAtlas.fTextureHandle, vertices, draw.fGlyphCnt); - this->flushToken(); + fTokenTracker.flushToken(); } fASAPUploads.reset(); fInlineUploads.reset(); diff --git a/src/atlastext/SkInternalAtlasTextContext.h b/src/atlastext/SkInternalAtlasTextContext.h index ea89435580..49a55cce15 100644 --- a/src/atlastext/SkInternalAtlasTextContext.h +++ b/src/atlastext/SkInternalAtlasTextContext.h @@ -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 fInlineUploads; SkArenaAllocList fDraws; SkArenaAllocList fASAPUploads; diff --git a/src/gpu/GrDeferredUpload.h b/src/gpu/GrDeferredUpload.h index 54f56b7139..cc8de959c5 100644 --- a/src/gpu/GrDeferredUpload.h +++ b/src/gpu/GrDeferredUpload.h @@ -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; /** - * 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 diff --git a/src/gpu/GrDrawOpAtlas.cpp b/src/gpu/GrDrawOpAtlas.cpp index 24e19f5b5e..1d41060eb7 100644 --- a/src/gpu/GrDrawOpAtlas.cpp +++ b/src/gpu/GrDrawOpAtlas.cpp @@ -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 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; } diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp index e60468b0d1..3f6c77379a 100644 --- a/src/gpu/GrDrawingManager.cpp +++ b/src/gpu/GrDrawingManager.cpp @@ -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 diff --git a/src/gpu/GrDrawingManager.h b/src/gpu/GrDrawingManager.h index 0162b4bd74..e9e98af4a7 100644 --- a/src/gpu/GrDrawingManager.h +++ b/src/gpu/GrDrawingManager.h @@ -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 fOnFlushCBObjects; diff --git a/src/gpu/GrOpFlushState.cpp b/src/gpu/GrOpFlushState.cpp index 5245a9d9b2..5e4ed35826 100644 --- a/src/gpu/GrOpFlushState.cpp +++ b/src/gpu/GrOpFlushState.cpp @@ -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; diff --git a/src/gpu/GrOpFlushState.h b/src/gpu/GrOpFlushState.h index a9cf9a070f..1f77c25cb7 100644 --- a/src/gpu/GrOpFlushState.h +++ b/src/gpu/GrOpFlushState.h @@ -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 fAsapUploads; + SkArenaAllocList fASAPUploads; SkArenaAllocList fInlineUploads; SkArenaAllocList 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 diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp index 873ad35def..3e7da52230 100644 --- a/src/gpu/ops/GrSmallPathRenderer.cpp +++ b/src/gpu/ops/GrSmallPathRenderer.cpp @@ -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, diff --git a/src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp b/src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp index 1be5ae330c..a49a3ff998 100644 --- a/src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp +++ b/src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp @@ -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(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; }