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>
This commit is contained in:
Adlai Holler 2021-04-15 11:01:46 -04:00 committed by Skia Commit-Bot
parent e6f1d8c2df
commit b51dd577b9
4 changed files with 32 additions and 12 deletions

View File

@ -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);

View File

@ -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();

View File

@ -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<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 @@ 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<kInitialArenaSize> fInternalAllocator; // intervals & registers live here
bool fFailedInstantiation = false;
SkSTArenaAllocWithReset<kInitialArenaSize> fInternalAllocator; // intervals & registers
bool fFailedInstantiation = false;
};
#endif // GrResourceAllocator_DEFINED

View File

@ -155,7 +155,7 @@ static sk_sp<GrSurfaceProxy> make_proxy(GrDirectContext* dContext, const ProxyPa
static void overlap_test(skiatest::Reporter* reporter, GrDirectContext* dContext,
sk_sp<GrSurfaceProxy> p1, sk_sp<GrSurfaceProxy> 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<GrSurfaceProxy> p1, sk_sp<GrSurfaceProxy> 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();