diff options
author | Robert Phillips <robertphillips@google.com> | 2018-02-21 21:56:35 +0000 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-02-21 21:56:47 +0000 |
commit | 59ddc6d5ee39c026e78bf39361cc788e30ca0afa (patch) | |
tree | 541d9b0d7cc94d11fc043e0ec9eb3455b41d0d2a /src/gpu/GrDrawOpAtlas.cpp | |
parent | 7630dcd794d909cc76ea577d4bbdb19b6f735b27 (diff) |
Revert "Separate creation time & flush time behavior in GrDrawOpAtlas"
This reverts commit 056c1a821afcfbe606615ad1a7d1b554549d0846.
Reason for revert: GM issues
Original change's description:
> Separate creation time & flush time behavior in GrDrawOpAtlas
>
> This CL clarifies what is going on in the GrDrawOpAtlas and GrAtlasGlyphCache.
>
> For the GrDrawOpAtlas:
> At creation time all the allowed pages are created (with their backing GrTextureProxies) but they aren't instantiated.
>
> The GrDrawOpAtlas::instantiate call is called in preFlushCB and allocates any pages known to be needed at the start of flush
>
> GrDrawOpAtlas::addToAtlas is called at flush time and, if a new page is activated, will instantiated it at that time.
>
> During compaction, an unused page will be deInstantiated but its Plots and backing GrTextureProxy will remain alive.
>
> The GrAtlasGlyphCache reflects the changes to the GrDrawOpAtlas
> It now carries a GrProxyProvider for when it needs to create an atlas
> It passes in a GrResourceProvider* at flush time to allow instantiation.
>
> It does not, yet, allocate that GrDrawOpAtlases it might ever require.
>
> Change-Id: I54909b7a3ba4bec2db5f1218f6a2a3a1636f66d6
> Reviewed-on: https://skia-review.googlesource.com/108520
> Commit-Queue: Robert Phillips <robertphillips@google.com>
> Reviewed-by: Jim Van Verth <jvanverth@google.com>
TBR=jvanverth@google.com,bsalomon@google.com,robertphillips@google.com
Change-Id: I36eafe46209380f533aa84e831d1c9d18844b6be
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/109280
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src/gpu/GrDrawOpAtlas.cpp')
-rw-r--r-- | src/gpu/GrDrawOpAtlas.cpp | 167 |
1 files changed, 71 insertions, 96 deletions
diff --git a/src/gpu/GrDrawOpAtlas.cpp b/src/gpu/GrDrawOpAtlas.cpp index 7539a7a05e..622aa229bd 100644 --- a/src/gpu/GrDrawOpAtlas.cpp +++ b/src/gpu/GrDrawOpAtlas.cpp @@ -26,20 +26,20 @@ // must explicitly manage the lifetime of their backing proxies via the onFlushCallback system // (which calls this method). void GrDrawOpAtlas::instantiate(GrOnFlushResourceProvider* onFlushResourceProvider) { - for (uint32_t i = 0; i < fNumActivePages; ++i) { - // All the atlas pages are now instantiated at flush time in the activeNewPage method. - SkASSERT(fProxies[i] && fProxies[i]->priv().isInstantiated()); + for (int i = 0; i < GrDrawOpAtlas::kMaxMultitexturePages; ++i) { + if (fProxies[i] && !fProxies[i]->priv().isInstantiated()) { + // If instantiation fails we expect the ops that rely on the atlas to be dropped + onFlushResourceProvider->instatiateProxy(fProxies[i].get()); + } } } -std::unique_ptr<GrDrawOpAtlas> GrDrawOpAtlas::Make(GrProxyProvider* proxyProvider, - GrPixelConfig config, int width, +std::unique_ptr<GrDrawOpAtlas> GrDrawOpAtlas::Make(GrContext* ctx, GrPixelConfig config, int width, int height, int numPlotsX, int numPlotsY, AllowMultitexturing allowMultitexturing, GrDrawOpAtlas::EvictionFunc func, void* data) { - std::unique_ptr<GrDrawOpAtlas> atlas(new GrDrawOpAtlas(proxyProvider, config, width, height, - numPlotsX, numPlotsY, - allowMultitexturing)); + std::unique_ptr<GrDrawOpAtlas> atlas(new GrDrawOpAtlas(ctx, config, width, height, numPlotsX, + numPlotsY, allowMultitexturing)); if (!atlas->getProxies()[0]) { return nullptr; } @@ -53,6 +53,7 @@ static bool gDumpAtlasData = false; #endif //////////////////////////////////////////////////////////////////////////////// + GrDrawOpAtlas::Plot::Plot(int pageIndex, int plotIndex, uint64_t genID, int offX, int offY, int width, int height, GrPixelConfig config) : fLastUpload(GrDeferredUploadToken::AlreadyFlushedToken()) @@ -177,16 +178,16 @@ void GrDrawOpAtlas::Plot::resetRects() { /////////////////////////////////////////////////////////////////////////////// -GrDrawOpAtlas::GrDrawOpAtlas(GrProxyProvider* proxyProvider, - GrPixelConfig config, int width, int height, +GrDrawOpAtlas::GrDrawOpAtlas(GrContext* context, GrPixelConfig config, int width, int height, int numPlotsX, int numPlotsY, AllowMultitexturing allowMultitexturing) - : fPixelConfig(config) + : fContext(context) + , fPixelConfig(config) , fTextureWidth(width) , fTextureHeight(height) , fAtlasGeneration(kInvalidAtlasGeneration + 1) , fPrevFlushToken(GrDeferredUploadToken::AlreadyFlushedToken()) , fAllowMultitexturing(allowMultitexturing) - , fNumActivePages(0) { + , fNumPages(0) { fPlotWidth = fTextureWidth / numPlotsX; fPlotHeight = fTextureHeight / numPlotsY; SkASSERT(numPlotsX * numPlotsY <= BulkUseTokenUpdater::kMaxPlots); @@ -195,7 +196,7 @@ GrDrawOpAtlas::GrDrawOpAtlas(GrProxyProvider* proxyProvider, fNumPlots = numPlotsX * numPlotsY; - this->createPages(proxyProvider); + this->createNewPage(); } inline void GrDrawOpAtlas::processEviction(AtlasID id) { @@ -216,8 +217,13 @@ inline bool GrDrawOpAtlas::updatePlot(GrDeferredUploadTarget* target, AtlasID* i // With c+14 we could move sk_sp into lamba to only ref once. sk_sp<Plot> plotsp(SkRef(plot)); + // MDB TODO: this is currently fine since the atlas' proxy is always pre-instantiated. + // Once it is deferred more care must be taken upon instantiation failure. + if (!fProxies[pageIdx]->instantiate(fContext->contextPriv().resourceProvider())) { + return false; + } + GrTextureProxy* proxy = fProxies[pageIdx].get(); - SkASSERT(proxy->priv().isInstantiated()); // This is occurring at flush time GrDeferredUploadToken lastUploadToken = target->addASAPUpload( [plotsp, proxy](GrDeferredTextureUploadWritePixelsFn& writePixels) { @@ -237,9 +243,8 @@ inline bool GrDrawOpAtlas::updatePlot(GrDeferredUploadTarget* target, AtlasID* i // are rare; i.e., we are not continually refreshing the frame. static constexpr auto kRecentlyUsedCount = 256; -bool GrDrawOpAtlas::addToAtlas(GrResourceProvider* resourceProvider, - AtlasID* id, GrDeferredUploadTarget* target, - int width, int height, const void* image, SkIPoint16* loc) { +bool GrDrawOpAtlas::addToAtlas(AtlasID* id, GrDeferredUploadTarget* target, int width, int height, + const void* image, SkIPoint16* loc) { if (width > fPlotWidth || height > fPlotHeight) { return false; } @@ -247,7 +252,7 @@ bool GrDrawOpAtlas::addToAtlas(GrResourceProvider* resourceProvider, // Look through each page to see if we can upload without having to flush // We prioritize this upload to the first pages, not the most recently used, to make it easier // to remove unused pages in reverse page order. - for (unsigned int pageIdx = 0; pageIdx < fNumActivePages; ++pageIdx) { + for (unsigned int pageIdx = 0; pageIdx < fNumPages; ++pageIdx) { SkASSERT(fProxies[pageIdx]); // look through all allocated plots for one we can share, in Most Recently Refed order PlotList::Iter plotIter; @@ -267,10 +272,10 @@ bool GrDrawOpAtlas::addToAtlas(GrResourceProvider* resourceProvider, // We wait until we've grown to the full number of pages to begin evicting already flushed // plots so that we can maximize the opportunity for reuse. // As before we prioritize this upload to the first pages, not the most recently used. - for (unsigned int pageIdx = 0; pageIdx < fNumActivePages; ++pageIdx) { + for (unsigned int pageIdx = 0; pageIdx < fNumPages; ++pageIdx) { Plot* plot = fPages[pageIdx].fPlotList.tail(); SkASSERT(plot); - if ((fNumActivePages == this->maxPages() && + if ((fNumPages == this->maxPages() && plot->lastUseToken() < target->tokenTracker()->nextTokenToFlush()) || plot->flushesSinceLastUsed() >= kRecentlyUsedCount) { this->processEvictionAndResetRects(plot); @@ -285,10 +290,9 @@ bool GrDrawOpAtlas::addToAtlas(GrResourceProvider* resourceProvider, } // If the simple cases fail, try to create a new page and add to it - if (this->activateNewPage(resourceProvider)) { - unsigned int pageIdx = fNumActivePages-1; - SkASSERT(fProxies[pageIdx] && fProxies[pageIdx]->priv().isInstantiated()); - + if (this->createNewPage()) { + unsigned int pageIdx = fNumPages-1; + SkASSERT(fProxies[pageIdx]); Plot* plot = fPages[pageIdx].fPlotList.head(); SkASSERT(GrBytesPerPixel(fProxies[pageIdx]->config()) == plot->bpp()); if (plot->addSubImage(width, height, image, loc)) { @@ -303,7 +307,7 @@ bool GrDrawOpAtlas::addToAtlas(GrResourceProvider* resourceProvider, // Try to find a plot that we can perform an inline upload to. // We prioritize this upload in reverse order of pages to counterbalance the order above. Plot* plot = nullptr; - for (int pageIdx = (int)(fNumActivePages-1); pageIdx >= 0; --pageIdx) { + for (int pageIdx = (int)(fNumPages-1); pageIdx >= 0; --pageIdx) { Plot* currentPlot = fPages[pageIdx].fPlotList.tail(); if (currentPlot->lastUseToken() != target->tokenTracker()->nextDrawToken()) { plot = currentPlot; @@ -335,8 +339,11 @@ bool GrDrawOpAtlas::addToAtlas(GrResourceProvider* resourceProvider, // one it displaced most likely was uploaded ASAP. // With c+14 we could move sk_sp into lambda to only ref once. sk_sp<Plot> plotsp(SkRef(newPlot.get())); - - SkASSERT(fProxies[pageIdx]->priv().isInstantiated()); + // MDB TODO: this is currently fine since the atlas' proxy is always pre-instantiated. + // Once it is deferred more care must be taken upon instantiation failure. + if (!fProxies[pageIdx]->instantiate(fContext->contextPriv().resourceProvider())) { + return false; + } GrTextureProxy* proxy = fProxies[pageIdx].get(); GrDeferredUploadToken lastUploadToken = target->addInlineUpload( @@ -351,7 +358,7 @@ bool GrDrawOpAtlas::addToAtlas(GrResourceProvider* resourceProvider, } void GrDrawOpAtlas::compact(GrDeferredUploadToken startTokenForNextFlush) { - if (fNumActivePages <= 1) { + if (fNumPages <= 1) { fPrevFlushToken = startTokenForNextFlush; return; } @@ -359,7 +366,7 @@ void GrDrawOpAtlas::compact(GrDeferredUploadToken startTokenForNextFlush) { // For all plots, reset number of flushes since used if used this frame. PlotList::Iter plotIter; bool atlasUsedThisFlush = false; - for (uint32_t pageIndex = 0; pageIndex < fNumActivePages; ++pageIndex) { + for (uint32_t pageIndex = 0; pageIndex < fNumPages; ++pageIndex) { plotIter.init(fPages[pageIndex].fPlotList, PlotList::Iter::kHead_IterStart); while (Plot* plot = plotIter.get()) { // Reset number of flushes since used @@ -378,7 +385,7 @@ void GrDrawOpAtlas::compact(GrDeferredUploadToken startTokenForNextFlush) { // TODO: consider if we should also do this if it's been a long time since the last atlas use if (atlasUsedThisFlush) { SkTArray<Plot*> availablePlots; - uint32_t lastPageIndex = fNumActivePages - 1; + uint32_t lastPageIndex = fNumPages - 1; // For all plots but the last one, 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. @@ -487,15 +494,19 @@ void GrDrawOpAtlas::compact(GrDeferredUploadToken startTokenForNextFlush) { SkDebugf("delete %d\n", fNumPages-1); } #endif - this->deactivateLastPage(); + this->deleteLastPage(); } } fPrevFlushToken = startTokenForNextFlush; } -bool GrDrawOpAtlas::createPages(GrProxyProvider* proxyProvider) { - SkASSERT(SkIsPow2(fTextureWidth) && SkIsPow2(fTextureHeight)); +bool GrDrawOpAtlas::createNewPage() { + if (fNumPages == this->maxPages()) { + return false; + } + + GrProxyProvider* proxyProvider = fContext->contextPriv().proxyProvider(); GrSurfaceDesc desc; desc.fFlags = kNone_GrSurfaceFlags; @@ -504,83 +515,47 @@ bool GrDrawOpAtlas::createPages(GrProxyProvider* proxyProvider) { desc.fHeight = fTextureHeight; desc.fConfig = fPixelConfig; + SkASSERT(SkIsPow2(fTextureWidth) && SkIsPow2(fTextureHeight)); + fProxies[fNumPages] = proxyProvider->createProxy(desc, SkBackingFit::kExact, SkBudgeted::kYes, + GrResourceProvider::kNoPendingIO_Flag); + if (!fProxies[fNumPages]) { + return false; + } + int numPlotsX = fTextureWidth/fPlotWidth; int numPlotsY = fTextureHeight/fPlotHeight; - for (uint32_t i = 0; i < this->maxPages(); ++i) { - fProxies[i] = proxyProvider->createProxy(desc, SkBackingFit::kExact, SkBudgeted::kYes, - GrResourceProvider::kNoPendingIO_Flag); - if (!fProxies[i]) { - return false; - } + // set up allocated plots + fPages[fNumPages].fPlotArray.reset(new sk_sp<Plot>[ numPlotsX * numPlotsY ]); - // set up allocated plots - fPages[i].fPlotArray.reset(new sk_sp<Plot>[ numPlotsX * numPlotsY ]); - - sk_sp<Plot>* currPlot = fPages[i].fPlotArray.get(); - for (int y = numPlotsY - 1, r = 0; y >= 0; --y, ++r) { - for (int x = numPlotsX - 1, c = 0; x >= 0; --x, ++c) { - uint32_t plotIndex = r * numPlotsX + c; - currPlot->reset(new Plot(i, plotIndex, 1, x, y, fPlotWidth, fPlotHeight, - fPixelConfig)); + sk_sp<Plot>* currPlot = fPages[fNumPages].fPlotArray.get(); + for (int y = numPlotsY - 1, r = 0; y >= 0; --y, ++r) { + for (int x = numPlotsX - 1, c = 0; x >= 0; --x, ++c) { + uint32_t plotIndex = r * numPlotsX + c; + currPlot->reset(new Plot(fNumPages, plotIndex, 1, x, y, fPlotWidth, fPlotHeight, + fPixelConfig)); - // build LRU list - fPages[i].fPlotList.addToHead(currPlot->get()); - ++currPlot; - } + // build LRU list + fPages[fNumPages].fPlotList.addToHead(currPlot->get()); + ++currPlot; } - - } - - return true; -} - - -bool GrDrawOpAtlas::activateNewPage(GrResourceProvider* resourceProvider) { - if (fNumActivePages >= this->maxPages()) { - return false; - } - - if (!fProxies[fNumActivePages]->instantiate(resourceProvider)) { - return false; } #ifdef DUMP_ATLAS_DATA if (gDumpAtlasData) { - SkDebugf("activated page#: %d\n", fNumActivePages); + SkDebugf("created %d\n", fNumPages); } #endif - - ++fNumActivePages; + fNumPages++; return true; } - -inline void GrDrawOpAtlas::deactivateLastPage() { - SkASSERT(fNumActivePages); - - uint32_t lastPageIndex = fNumActivePages - 1; - - int numPlotsX = fTextureWidth/fPlotWidth; - int numPlotsY = fTextureHeight/fPlotHeight; - +inline void GrDrawOpAtlas::deleteLastPage() { + uint32_t lastPageIndex = fNumPages - 1; + // clean out the plots fPages[lastPageIndex].fPlotList.reset(); - for (int y = numPlotsY - 1, r = 0; y >= 0; --y, ++r) { - for (int x = numPlotsX - 1, c = 0; x >= 0; --x, ++c) { - uint32_t plotIndex = r * numPlotsX + c; - - Plot* currPlot = fPages[lastPageIndex].fPlotArray[plotIndex].get(); - currPlot->resetRects(); - currPlot->resetFlushesSinceLastUsed(); - - // rebuild the LRU list - SkDEBUGCODE(currPlot->fPrev = currPlot->fNext = nullptr); - SkDEBUGCODE(currPlot->fList = nullptr); - fPages[lastPageIndex].fPlotList.addToHead(currPlot); - } - } - - // remove ref to the backing texture - fProxies[lastPageIndex]->deInstantiate(); - --fNumActivePages; + fPages[lastPageIndex].fPlotArray.reset(nullptr); + // remove ref to texture proxy + fProxies[lastPageIndex].reset(nullptr); + --fNumPages; } |