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 <adlai@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp
index a85436a..99c8e69 100644
--- a/src/gpu/GrDrawingManager.cpp
+++ b/src/gpu/GrDrawingManager.cpp
@@ -205,7 +205,7 @@
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 1dff77d..68b36d2 100644
--- a/src/gpu/GrResourceAllocator.cpp
+++ b/src/gpu/GrResourceAllocator.cpp
@@ -387,7 +387,25 @@
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 8175dca..348d9b4 100644
--- a/src/gpu/GrResourceAllocator.h
+++ b/src/gpu/GrResourceAllocator.h
@@ -68,7 +68,7 @@
*/
class GrResourceAllocator {
public:
- GrResourceAllocator(GrDirectContext* dContext SkDEBUGCODE(, int numOpsTasks))
+ GrResourceAllocator(GrDirectContext* dContext)
: fDContext(dContext) {}
~GrResourceAllocator();
@@ -91,6 +91,8 @@
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 @@
// 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 @@
};
typedef SkTMultiMap<Register, GrScratchKey, FreePoolTraits> FreePoolMultiMap;
- typedef SkTHashMap<uint32_t, Interval*, GrCheapHash> IntvlHash;
+ typedef SkTHashMap<uint32_t, Interval*, GrCheapHash> IntvlHash;
struct UniqueKeyHash {
uint32_t operator()(const GrUniqueKey& key) const { return key.hash(); }
@@ -235,10 +240,7 @@
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 @@
SkDEBUGCODE(bool fPlanned = false;)
SkDEBUGCODE(bool fAssigned = false;)
- SkSTArenaAlloc<kInitialArenaSize> fInternalAllocator; // intervals & registers live here
- bool fFailedInstantiation = false;
+ SkSTArenaAllocWithReset<kInitialArenaSize> fInternalAllocator; // intervals & registers
+ bool fFailedInstantiation = false;
};
#endif // GrResourceAllocator_DEFINED