diff options
author | Robert Phillips <robertphillips@google.com> | 2017-11-16 07:52:08 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-11-16 16:35:57 +0000 |
commit | eafd48af63aef270cbea139547bb4fa8a591748d (patch) | |
tree | c59febed663b2e00ab9af5eb8ad239a3efded290 /src/gpu/GrResourceAllocator.cpp | |
parent | 5627d65146cb92624b682389e017d488872228c7 (diff) |
Add overbudget handling to GrResourceAllocator
Change-Id: I5536c908310e907c77b5d55441a0edac6a74bf0e
Reviewed-on: https://skia-review.googlesource.com/71182
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src/gpu/GrResourceAllocator.cpp')
-rw-r--r-- | src/gpu/GrResourceAllocator.cpp | 76 |
1 files changed, 63 insertions, 13 deletions
diff --git a/src/gpu/GrResourceAllocator.cpp b/src/gpu/GrResourceAllocator.cpp index 3e34a713d9..5cb882f61c 100644 --- a/src/gpu/GrResourceAllocator.cpp +++ b/src/gpu/GrResourceAllocator.cpp @@ -9,6 +9,8 @@ #include "GrGpuResourcePriv.h" #include "GrOpList.h" +#include "GrRenderTargetProxy.h" +#include "GrResourceCache.h" #include "GrResourceProvider.h" #include "GrSurfacePriv.h" #include "GrSurfaceProxy.h" @@ -21,6 +23,18 @@ void GrResourceAllocator::Interval::assign(sk_sp<GrSurface> s) { fProxy->priv().assign(std::move(s)); } + +void GrResourceAllocator::markEndOfOpList(int opListIndex) { + SkASSERT(!fAssigned); // We shouldn't be adding any opLists after (or during) assignment + + SkASSERT(fEndOfOpListOpIndices.count() == opListIndex); + if (!fEndOfOpListOpIndices.empty()) { + SkASSERT(fEndOfOpListOpIndices.back() < this->curOp()); + } + + fEndOfOpListOpIndices.push_back(this->curOp()); // This is the first op index of the next opList +} + GrResourceAllocator::~GrResourceAllocator() { #ifndef SK_DISABLE_EXPLICIT_GPU_RESOURCE_ALLOCATION SkASSERT(fIntvlList.empty()); @@ -36,11 +50,8 @@ void GrResourceAllocator::addInterval(GrSurfaceProxy* proxy, if (Interval* intvl = fIntvlHash.find(proxy->uniqueID().asUInt())) { // Revise the interval for an existing use - // TODO: this assert is failing on the copy_on_write_retain GM! - SkASSERT(intvl->end() <= start); - if (intvl->end() < end) { - intvl->extendEnd(end); - } + SkASSERT(intvl->end() <= start && intvl->end() <= end); + intvl->extendEnd(end); return; } @@ -122,8 +133,8 @@ void GrResourceAllocator::freeUpSurface(sk_sp<GrSurface> surface) { // First try to reuse one of the recently allocated/used GrSurfaces in the free pool. // If we can't find a useable one, create a new one. -// TODO: handle being overbudget -sk_sp<GrSurface> GrResourceAllocator::findSurfaceFor(const GrSurfaceProxy* proxy) { +sk_sp<GrSurface> GrResourceAllocator::findSurfaceFor(const GrSurfaceProxy* proxy, + bool needsStencil) { // First look in the free pool GrScratchKey key; @@ -141,6 +152,7 @@ sk_sp<GrSurface> GrResourceAllocator::findSurfaceFor(const GrSurfaceProxy* proxy surface->resourcePriv().makeBudgeted(); } + GrSurfaceProxyPriv::AttachStencilIfNeeded(fResourceProvider, surface.get(), needsStencil); return surface; } @@ -164,20 +176,48 @@ void GrResourceAllocator::expire(unsigned int curIndex) { } } -void GrResourceAllocator::assign() { - fIntvlHash.reset(); // we don't need this anymore +bool GrResourceAllocator::assign(int* startIndex, int* stopIndex) { + fIntvlHash.reset(); // we don't need the interval hash anymore + if (fIntvlList.empty()) { + return false; // nothing to render + } + + *startIndex = fCurOpListIndex; + *stopIndex = fEndOfOpListOpIndices.count(); + SkDEBUGCODE(fAssigned = true;) while (Interval* cur = fIntvlList.popHead()) { + if (fEndOfOpListOpIndices[fCurOpListIndex] < cur->start()) { + fCurOpListIndex++; + } + this->expire(cur->start()); + bool needsStencil = cur->proxy()->asRenderTargetProxy() + ? cur->proxy()->asRenderTargetProxy()->needsStencil() + : false; + if (cur->proxy()->priv().isInstantiated()) { + GrSurfaceProxyPriv::AttachStencilIfNeeded(fResourceProvider, + cur->proxy()->priv().peekSurface(), + needsStencil); + fActiveIntvls.insertByIncreasingEnd(cur); + + if (fResourceProvider->overBudget()) { + // Only force intermediate draws on opList boundaries + if (!fIntvlList.empty() && + fEndOfOpListOpIndices[fCurOpListIndex] < fIntvlList.peekHead()->start()) { + *stopIndex = fCurOpListIndex+1; + return true; + } + } + continue; } - // TODO: add over budget handling here? - sk_sp<GrSurface> surface = this->findSurfaceFor(cur->proxy()); + sk_sp<GrSurface> surface = this->findSurfaceFor(cur->proxy(), needsStencil); if (surface) { // TODO: make getUniqueKey virtual on GrSurfaceProxy GrTextureProxy* tex = cur->proxy()->asTextureProxy(); @@ -188,11 +228,21 @@ void GrResourceAllocator::assign() { cur->assign(std::move(surface)); } - // TODO: handle resouce allocation failure upstack + + // TODO: handle resource allocation failure upstack fActiveIntvls.insertByIncreasingEnd(cur); + + if (fResourceProvider->overBudget()) { + // Only force intermediate draws on opList boundaries + if (!fIntvlList.empty() && + fEndOfOpListOpIndices[fCurOpListIndex] < fIntvlList.peekHead()->start()) { + *stopIndex = fCurOpListIndex+1; + return true; + } + } } // expire all the remaining intervals to drain the active interval list this->expire(std::numeric_limits<unsigned int>::max()); + return true; } - |