diff --git a/src/core/SkTInternalLList.h b/src/core/SkTInternalLList.h index df06d8a255..ef4b74f633 100644 --- a/src/core/SkTInternalLList.h +++ b/src/core/SkTInternalLList.h @@ -45,11 +45,6 @@ public: , fTail(nullptr) { } - void reset() { - fHead = nullptr; - fTail = nullptr; - } - void remove(T* entry) { SkASSERT(fHead && fTail); SkASSERT(this->isInList(entry)); diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 9abf953abd..ba26cc844e 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -205,7 +205,6 @@ bool GrContext::init(const GrContextOptions& options) { fDrawingManager.reset(new GrDrawingManager(this, prcOptions, &fSingleOwner)); fAtlasGlyphCache = new GrAtlasGlyphCache(this, options.fGlyphCacheTextureMaximumBytes); - this->contextPriv().addOnFlushCallbackObject(fAtlasGlyphCache); fTextBlobCache.reset(new GrTextBlobCache(TextBlobCacheOverBudgetCB, this)); diff --git a/src/gpu/GrDrawOpAtlas.cpp b/src/gpu/GrDrawOpAtlas.cpp index ed57b46b3f..22def06212 100644 --- a/src/gpu/GrDrawOpAtlas.cpp +++ b/src/gpu/GrDrawOpAtlas.cpp @@ -36,7 +36,6 @@ GrDrawOpAtlas::Plot::Plot(int pageIndex, int plotIndex, uint64_t genID, int offX int width, int height, GrPixelConfig config) : fLastUpload(GrDrawOpUploadToken::AlreadyFlushedToken()) , fLastUse(GrDrawOpUploadToken::AlreadyFlushedToken()) - , fFlushesSinceLastUse(0) , fPageIndex(pageIndex) , fPlotIndex(plotIndex) , fGenID(genID) @@ -148,7 +147,6 @@ GrDrawOpAtlas::GrDrawOpAtlas(GrContext* context, GrPixelConfig config, int width , fTextureWidth(width) , fTextureHeight(height) , fAtlasGeneration(kInvalidAtlasGeneration + 1) - , fPrevFlushToken(GrDrawOpUploadToken::AlreadyFlushedToken()) , fNumPages(0) { fPlotWidth = fTextureWidth / numPlotsX; @@ -310,84 +308,6 @@ bool GrDrawOpAtlas::addToAtlas(AtlasID* id, GrDrawOp::Target* target, int width, return true; } -void GrDrawOpAtlas::compact(GrDrawOpUploadToken startTokenForNextFlush) { - // Number of atlas-related flushes beyond which we consider a plot to no longer be in use. - // - // This value is somewhat arbitrary -- the idea is to keep it low enough that - // a page with unused plots will get removed reasonably quickly, but allow it - // to hang around for a bit in case it's needed. The assumption is that flushes - // are rare; i.e., we are not continually refreshing the frame. - static constexpr auto kRecentlyUsedCount = 8; - - if (fNumPages <= 1) { - fPrevFlushToken = startTokenForNextFlush; - return; - } - - // For all plots, update number of flushes since used, and check to see if there - // are any in the first pages that the last page can safely upload to. - PlotList::Iter plotIter; - int availablePlots = 0; - uint32_t lastPageIndex = fNumPages-1; - bool atlasUsedThisFlush = false; - for (uint32_t pageIndex = 0; pageIndex < fNumPages; ++pageIndex) { - plotIter.init(fPages[pageIndex].fPlotList, PlotList::Iter::kHead_IterStart); - while (Plot* plot = plotIter.get()) { - // Update number of flushes since plot was last used - if (plot->lastUseToken().inInterval(fPrevFlushToken, startTokenForNextFlush)) { - plot->resetFlushesSinceLastUsed(); - atlasUsedThisFlush = true; - } else { - plot->incFlushesSinceLastUsed(); - } - - // Count plots we can potentially upload to in all pages except the last one - // (the potential compactee). - if (pageIndex < lastPageIndex && plot->flushesSinceLastUsed() > kRecentlyUsedCount) { - ++availablePlots; - } - - plotIter.next(); - } - } - - // We only try to compact if the atlas was used in the recently completed flush. - // TODO: consider if we should also do this if it's been a long time since the last atlas use - if (atlasUsedThisFlush) { - // Count recently used plots in the last page and evict them if there's available space - // in earlier pages. Since we prioritize uploading to the first pages, this will eventually - // clear out usage of this page unless we have a large need. - plotIter.init(fPages[lastPageIndex].fPlotList, PlotList::Iter::kHead_IterStart); - int usedPlots = 0; - while (Plot* plot = plotIter.get()) { - // If this plot was used recently - if (plot->flushesSinceLastUsed() <= kRecentlyUsedCount) { - usedPlots++; - // see if there's room in an earlier page and if so evict. - // We need to be somewhat harsh here so that one plot that is consistently in use - // doesn't end up locking the page in memory. - if (availablePlots) { - this->processEviction(plot->id()); - plot->resetRects(); - --availablePlots; - } - } else { - // otherwise if aged out just evict it. - this->processEviction(plot->id()); - plot->resetRects(); - } - plotIter.next(); - } - - // If none of the plots in the last page have been used recently, delete it. - if (!usedPlots) { - this->deleteLastPage(); - } - } - - fPrevFlushToken = startTokenForNextFlush; -} - bool GrDrawOpAtlas::createNewPage() { if (fNumPages == kMaxPages) { return false; @@ -440,13 +360,3 @@ bool GrDrawOpAtlas::createNewPage() { fNumPages++; return true; } - -inline void GrDrawOpAtlas::deleteLastPage() { - uint32_t lastPageIndex = fNumPages - 1; - // clean out the plots - fPages[lastPageIndex].fPlotList.reset(); - fPages[lastPageIndex].fPlotArray.reset(nullptr); - // remove ref to texture proxy - fProxies[lastPageIndex].reset(nullptr); - --fNumPages; -} diff --git a/src/gpu/GrDrawOpAtlas.h b/src/gpu/GrDrawOpAtlas.h index d4a81a0106..87d9c5b619 100644 --- a/src/gpu/GrDrawOpAtlas.h +++ b/src/gpu/GrDrawOpAtlas.h @@ -26,29 +26,14 @@ struct GrDrawOpAtlasConfig { }; /** - * This class manages one or more atlas textures on behalf of GrDrawOps. The draw ops that use the - * atlas perform texture uploads when preparing their draws during flush. The class provides - * facilities for using GrDrawOpUploadToken to detect data hazards. Op's uploads are performed in - * "asap" mode until it is impossible to add data without overwriting texels read by draws that - * have not yet executed on the gpu. At that point, the atlas will attempt to allocate a new - * atlas texture (or "page") of the same size, up to a maximum number of textures, and upload - * to that texture. If that's not possible, the uploads are performed "inline" between draws. If a - * single draw would use enough subimage space to overflow the atlas texture then the atlas will - * fail to add a subimage. This gives the op the chance to end the draw and begin a new one. - * Additional uploads will then succeed in inline mode. - * - * When the atlas has multiple pages, new uploads are prioritized to the lower index pages, i.e., - * it will try to upload to page 0 before page 1 or 2. To keep the atlas from continually using - * excess space, periodic garbage collection is needed to shift data from the higher index pages to - * the lower ones, and then eventually remove any pages that are no longer in use. "In use" is - * determined by using the GrDrawUploadToken system: After a flush each subarea of the page - * is checked to see whether it was used in that flush; if it is not, a counter is incremented. - * Once that counter reaches a threshold that subarea is considered to be no longer in use. - * - * Garbage collection is initiated by the GrDrawOpAtlas's client via the compact() method. One - * solution is to make the client a subclass of GrOnFlushCallbackObject, register it with the - * GrContext via addOnFlushCallbackObject(), and the client's postFlush() method calls compact() - * and passes in the given GrDrawUploadToken. + * This class manages an atlas texture on behalf of GrDrawOps. The draw ops that use the atlas + * perform texture uploads when preparing their draws during flush. The class provides facilities + * for using GrDrawOpUploadToken to detect data hazards. Op's uploads are performed in "asap" mode + * until it is impossible to add data without overwriting texels read by draws that have not yet + * executed on the gpu. At that point the uploads are performed "inline" between draws. If a single + * draw would use enough subimage space to overflow the atlas texture then the atlas will fail to + * add a subimage. This gives the op the chance to end the draw and begin a new one. Additional + * uploads will then succeed in inline mode. */ class GrDrawOpAtlas { public: @@ -201,8 +186,6 @@ public: } } - void compact(GrDrawOpUploadToken startTokenForNextFlush); - static constexpr auto kGlyphMaxDim = 256; static bool GlyphTooLargeForAtlas(int width, int height) { return width > kGlyphMaxDim || height > kGlyphMaxDim; @@ -257,10 +240,6 @@ private: void uploadToTexture(GrDrawOp::WritePixelsFn&, GrTextureProxy*); void resetRects(); - int flushesSinceLastUsed() { return fFlushesSinceLastUse; } - void resetFlushesSinceLastUsed() { fFlushesSinceLastUse = 0; } - void incFlushesSinceLastUsed() { fFlushesSinceLastUse++; } - private: Plot(int pageIndex, int plotIndex, uint64_t genID, int offX, int offY, int width, int height, GrPixelConfig config); @@ -286,8 +265,6 @@ private: GrDrawOpUploadToken fLastUpload; GrDrawOpUploadToken fLastUse; - // the number of flushes since this plot has been last used - int fFlushesSinceLastUse; struct { const uint32_t fPageIndex : 16; @@ -333,12 +310,10 @@ private: fPages[pageIdx].fPlotList.remove(plot); fPages[pageIdx].fPlotList.addToHead(plot); - // No MRU update for pages -- since we will always try to add from - // the front and remove from the back there is no need for MRU. + // TODO: make page MRU } bool createNewPage(); - void deleteLastPage(); inline void processEviction(AtlasID); @@ -351,8 +326,6 @@ private: SkDEBUGCODE(uint32_t fNumPlots;) uint64_t fAtlasGeneration; - // nextTokenToFlush() value at the end of the previous flush - GrDrawOpUploadToken fPrevFlushToken; struct EvictionData { EvictionFunc fFunc; diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp index eb035597a1..c229a2a1eb 100644 --- a/src/gpu/GrDrawingManager.cpp +++ b/src/gpu/GrDrawingManager.cpp @@ -214,7 +214,7 @@ GrSemaphoresSubmitted GrDrawingManager::internalFlush(GrSurfaceProxy*, fContext->getResourceCache()->notifyFlushOccurred(type); } for (GrOnFlushCallbackObject* onFlushCBObject : fOnFlushCBObjects) { - onFlushCBObject->postFlush(fFlushState.nextTokenToFlush()); + onFlushCBObject->postFlush(); } fFlushing = false; diff --git a/src/gpu/GrOnFlushResourceProvider.h b/src/gpu/GrOnFlushResourceProvider.h index 08dd012c99..e2c0b73075 100644 --- a/src/gpu/GrOnFlushResourceProvider.h +++ b/src/gpu/GrOnFlushResourceProvider.h @@ -9,7 +9,6 @@ #define GrOnFlushResourceProvider_DEFINED #include "GrTypes.h" -#include "GrOpFlushState.h" #include "GrResourceProvider.h" #include "SkRefCnt.h" #include "SkTArray.h" @@ -44,9 +43,9 @@ public: /** * Called once flushing is complete and all ops indicated by preFlush have been executed and - * released. startTokenForNextFlush can be used to track resources used in the current flush. + * released. */ - virtual void postFlush(GrDrawOpUploadToken startTokenForNextFlush) {} + virtual void postFlush() {} private: typedef SkRefCnt INHERITED; diff --git a/src/gpu/GrPathRendererChain.cpp b/src/gpu/GrPathRendererChain.cpp index 843d712c5c..466f90a890 100644 --- a/src/gpu/GrPathRendererChain.cpp +++ b/src/gpu/GrPathRendererChain.cpp @@ -63,9 +63,7 @@ GrPathRendererChain::GrPathRendererChain(GrContext* context, const Options& opti fChain.push_back(sk_make_sp()); } if (options.fGpuPathRenderers & GpuPathRenderers::kSmall) { - auto spr = sk_make_sp(); - context->contextPriv().addOnFlushCallbackObject(spr.get()); - fChain.push_back(spr); + fChain.push_back(sk_make_sp()); } if (options.fGpuPathRenderers & GpuPathRenderers::kTessellating) { fChain.push_back(sk_make_sp()); diff --git a/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp b/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp index 46467bc9ac..9b2e956f9e 100644 --- a/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp +++ b/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp @@ -387,7 +387,7 @@ void DrawPathsOp::onExecute(GrOpFlushState* flushState) { SkASSERT(baseInstance == fBaseInstance + fDebugInstanceCount - fDebugSkippedInstances); } -void GrCoverageCountingPathRenderer::postFlush(GrDrawOpUploadToken) { +void GrCoverageCountingPathRenderer::postFlush() { SkASSERT(fFlushing); fPerFlushAtlases.reset(); fPerFlushInstanceBuffer.reset(); diff --git a/src/gpu/ccpr/GrCoverageCountingPathRenderer.h b/src/gpu/ccpr/GrCoverageCountingPathRenderer.h index 6025581da8..ee73cb3d18 100644 --- a/src/gpu/ccpr/GrCoverageCountingPathRenderer.h +++ b/src/gpu/ccpr/GrCoverageCountingPathRenderer.h @@ -44,7 +44,7 @@ public: // GrOnFlushCallbackObject overrides. void preFlush(GrOnFlushResourceProvider*, const uint32_t* opListIDs, int numOpListIDs, SkTArray>* results) override; - void postFlush(GrDrawOpUploadToken) override; + void postFlush() override; // This is the Op that ultimately draws a path into its final destination, using the atlas we // generate at flush time. diff --git a/src/gpu/ops/GrDrawOp.h b/src/gpu/ops/GrDrawOp.h index ecd92498ae..145d2e2981 100644 --- a/src/gpu/ops/GrDrawOp.h +++ b/src/gpu/ops/GrDrawOp.h @@ -33,10 +33,6 @@ public: return fSequenceNumber == that.fSequenceNumber; } bool operator!=(const GrDrawOpUploadToken& that) const { return !(*this == that); } - bool inInterval(const GrDrawOpUploadToken& start, const GrDrawOpUploadToken& finish) { - return fSequenceNumber >= start.fSequenceNumber && - fSequenceNumber <= finish.fSequenceNumber; - } private: GrDrawOpUploadToken(); diff --git a/src/gpu/ops/GrSmallPathRenderer.h b/src/gpu/ops/GrSmallPathRenderer.h index 9c3104b136..b958baa843 100644 --- a/src/gpu/ops/GrSmallPathRenderer.h +++ b/src/gpu/ops/GrSmallPathRenderer.h @@ -9,7 +9,6 @@ #define GrSmallPathRenderer_DEFINED #include "GrDrawOpAtlas.h" -#include "GrOnFlushResourceProvider.h" #include "GrPathRenderer.h" #include "GrRect.h" #include "GrShape.h" @@ -19,7 +18,7 @@ class GrContext; -class GrSmallPathRenderer : public GrPathRenderer, public GrOnFlushCallbackObject { +class GrSmallPathRenderer : public GrPathRenderer { public: GrSmallPathRenderer(); ~GrSmallPathRenderer() override; @@ -27,15 +26,6 @@ public: class SmallPathOp; struct PathTestStruct; - void preFlush(GrOnFlushResourceProvider*, const uint32_t*, int, - SkTArray>*) override {} - - void postFlush(GrDrawOpUploadToken startTokenForNextFlush) override { - if (fAtlas) { - fAtlas->compact(startTokenForNextFlush); - } - } - private: StencilSupport onGetStencilSupport(const GrShape&) const override { return GrPathRenderer::kNoSupport_StencilSupport; diff --git a/src/gpu/text/GrAtlasGlyphCache.h b/src/gpu/text/GrAtlasGlyphCache.h index 071ce0f96f..78b743e2f4 100644 --- a/src/gpu/text/GrAtlasGlyphCache.h +++ b/src/gpu/text/GrAtlasGlyphCache.h @@ -11,7 +11,6 @@ #include "GrCaps.h" #include "GrDrawOpAtlas.h" #include "GrGlyph.h" -#include "GrOnFlushResourceProvider.h" #include "SkArenaAlloc.h" #include "SkGlyphCache.h" #include "SkTDynamicHash.h" @@ -109,10 +108,10 @@ private: * though this is more or less transparent to the client(aside from atlasGeneration, described * below). */ -class GrAtlasGlyphCache : public GrOnFlushCallbackObject { +class GrAtlasGlyphCache { public: GrAtlasGlyphCache(GrContext*, float maxTextureBytes); - ~GrAtlasGlyphCache() override; + ~GrAtlasGlyphCache(); // The user of the cache may hold a long-lived ref to the returned strike. However, actions by // another client of the cache may cause the strike to be purged while it is still reffed. // Therefore, the caller must check GrAtlasTextStrike::isAbandoned() if there are other @@ -182,17 +181,6 @@ public: return this->getAtlas(format)->atlasGeneration(); } - void preFlush(GrOnFlushResourceProvider*, const uint32_t*, int, - SkTArray>*) override {} - - void postFlush(GrDrawOpUploadToken startTokenForNextFlush) override { - for (int i = 0; i < kMaskFormatCount; ++i) { - if (fAtlases[i]) { - fAtlases[i]->compact(startTokenForNextFlush); - } - } - } - /////////////////////////////////////////////////////////////////////////// // Functions intended debug only #ifdef SK_DEBUG