From b51dd577b93bb92cb6cea07bd51e09312b739f3b Mon Sep 17 00:00:00 2001 From: Adlai Holler Date: Thu, 15 Apr 2021 11:01:46 -0400 Subject: [PATCH] Add GrResourceAllocator::reset This is used in the fallback code when reordering produces a DAG that goes over our memory budget. Bug: skia:10877 Change-Id: I13772b30e270eb546957b88586ded1cf42d2dbeb Reviewed-on: https://skia-review.googlesource.com/c/skia/+/397136 Commit-Queue: Adlai Holler Reviewed-by: Robert Phillips --- src/gpu/GrDrawingManager.cpp | 2 +- src/gpu/GrResourceAllocator.cpp | 18 ++++++++++++++++++ src/gpu/GrResourceAllocator.h | 18 ++++++++++-------- tests/ResourceAllocatorTest.cpp | 6 +++--- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp index a85436ad0a..99c8e697cc 100644 --- a/src/gpu/GrDrawingManager.cpp +++ b/src/gpu/GrDrawingManager.cpp @@ -205,7 +205,7 @@ bool GrDrawingManager::flush( bool flushed = false; { - GrResourceAllocator alloc(dContext SkDEBUGCODE(, fDAG.count())); + GrResourceAllocator alloc(dContext); for (const auto& task : fDAG) { SkASSERT(task); task->gatherProxyIntervals(&alloc); diff --git a/src/gpu/GrResourceAllocator.cpp b/src/gpu/GrResourceAllocator.cpp index 1dff77dc98..68b36d285a 100644 --- a/src/gpu/GrResourceAllocator.cpp +++ b/src/gpu/GrResourceAllocator.cpp @@ -387,7 +387,25 @@ bool GrResourceAllocator::makeBudgetHeadroom() { return fDContext->priv().getResourceCache()->purgeToMakeHeadroom(additionalBytesNeeded); } +void GrResourceAllocator::reset() { + // NOTE: We do not reset the failedInstantiation flag because we currently do not attempt + // to recover from failed instantiations. The user is responsible for checking this flag and + // bailing early. + SkDEBUGCODE(fPlanned = false;) + SkDEBUGCODE(fAssigned = false;) + SkASSERT(fActiveIntvls.empty()); + fFinishedIntvls = IntervalList(); + fIntvlList = IntervalList(); + fIntvlHash.reset(); + fUniqueKeyRegisters.reset(); + fFreePool.reset(); + fInternalAllocator.reset(); +} + bool GrResourceAllocator::assign() { + if (fFailedInstantiation) { + return false; + } SkASSERT(fPlanned && !fAssigned); SkDEBUGCODE(fAssigned = true;) auto resourceProvider = fDContext->priv().resourceProvider(); diff --git a/src/gpu/GrResourceAllocator.h b/src/gpu/GrResourceAllocator.h index 8175dca6cd..348d9b4683 100644 --- a/src/gpu/GrResourceAllocator.h +++ b/src/gpu/GrResourceAllocator.h @@ -68,7 +68,7 @@ class GrDirectContext; */ class GrResourceAllocator { public: - GrResourceAllocator(GrDirectContext* dContext SkDEBUGCODE(, int numOpsTasks)) + GrResourceAllocator(GrDirectContext* dContext) : fDContext(dContext) {} ~GrResourceAllocator(); @@ -91,6 +91,8 @@ public: void addInterval(GrSurfaceProxy*, unsigned int start, unsigned int end, ActualUse actualUse SkDEBUGCODE(, bool isDirectDstRead = false)); + bool failedInstantiation() const { return fFailedInstantiation; } + // Generate an internal plan for resource allocation. After this you can optionally call // `makeBudgetHeadroom` to check whether that plan would go over our memory budget. // Fully-lazy proxies are also instantiated at this point so that their size can @@ -101,6 +103,9 @@ public: // purge them and return true. Otherwise return false. bool makeBudgetHeadroom(); + // Clear all internal state in preparation for a new set of intervals. + void reset(); + // Instantiate and assign resources to all proxies. bool assign(); @@ -129,7 +134,7 @@ private: }; typedef SkTMultiMap FreePoolMultiMap; - typedef SkTHashMap IntvlHash; + typedef SkTHashMap IntvlHash; struct UniqueKeyHash { uint32_t operator()(const GrUniqueKey& key) const { return key.hash(); } @@ -235,10 +240,7 @@ private: class IntervalList { public: IntervalList() = default; - ~IntervalList() { - // The only time we delete an IntervalList is in the GrResourceAllocator dtor. - // Since the arena allocator will clean up for us we don't bother here. - } + // N.B. No need for a destructor – the arena allocator will clean up for us. bool empty() const { SkASSERT(SkToBool(fHead) == SkToBool(fTail)); @@ -275,8 +277,8 @@ private: SkDEBUGCODE(bool fPlanned = false;) SkDEBUGCODE(bool fAssigned = false;) - SkSTArenaAlloc fInternalAllocator; // intervals & registers live here - bool fFailedInstantiation = false; + SkSTArenaAllocWithReset fInternalAllocator; // intervals & registers + bool fFailedInstantiation = false; }; #endif // GrResourceAllocator_DEFINED diff --git a/tests/ResourceAllocatorTest.cpp b/tests/ResourceAllocatorTest.cpp index 3f45bd3227..89649d1ebc 100644 --- a/tests/ResourceAllocatorTest.cpp +++ b/tests/ResourceAllocatorTest.cpp @@ -155,7 +155,7 @@ static sk_sp make_proxy(GrDirectContext* dContext, const ProxyPa static void overlap_test(skiatest::Reporter* reporter, GrDirectContext* dContext, sk_sp p1, sk_sp p2, bool expectedResult) { - GrResourceAllocator alloc(dContext SkDEBUGCODE(, 1)); + GrResourceAllocator alloc(dContext); alloc.addInterval(p1.get(), 0, 4, GrResourceAllocator::ActualUse::kYes); alloc.incOps(); @@ -177,7 +177,7 @@ static void overlap_test(skiatest::Reporter* reporter, GrDirectContext* dContext static void non_overlap_test(skiatest::Reporter* reporter, GrDirectContext* dContext, sk_sp p1, sk_sp p2, bool expectedResult) { - GrResourceAllocator alloc(dContext SkDEBUGCODE(, 1)); + GrResourceAllocator alloc(dContext); alloc.incOps(); alloc.incOps(); @@ -394,7 +394,7 @@ static void memory_budget_test(skiatest::Reporter* reporter, "%zu", unpurgeableBytes); // Add intervals and test. - GrResourceAllocator alloc(dContext SkDEBUGCODE(, 1)); + GrResourceAllocator alloc(dContext); for (auto& interval : test.fIntervals) { for (int i = interval.fStart; i <= interval.fEnd; i++) { alloc.incOps();