aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrDrawOpAtlas.cpp
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2018-02-26 16:03:50 +0000
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-02-26 16:03:58 +0000
commit84d823a5e2a03b09f7db4964218b9e04e821c878 (patch)
tree1c62ea7e845f100ffcc6cfa71199eeee5a8084c7 /src/gpu/GrDrawOpAtlas.cpp
parentaad2ec69f32bad4eef0663600d606e4526488f16 (diff)
Revert "Separate creation time & flush time behavior in GrDrawOpAtlas (take 2)"
This reverts commit 96165ebeaa36a2aae0eedaf12d81f53d3caf999a. Reason for revert: DFT GMs w/ LCD text are slightly different Original change's description: > Separate creation time & flush time behavior in GrDrawOpAtlas (take 2) > > 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: Ie9b64b13e261b01ee14be09fbf7e17841b7781dc > Reviewed-on: https://skia-review.googlesource.com/109749 > Reviewed-by: Jim Van Verth <jvanverth@google.com> > Commit-Queue: Robert Phillips <robertphillips@google.com> TBR=jvanverth@google.com,robertphillips@google.com Change-Id: I62efc61c8394477e54d6e79fa2f65180c91a4515 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://skia-review.googlesource.com/110220 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.cpp167
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;
}