Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | List of all members
GrResourceAllocator Class Reference

#include <GrResourceAllocator.h>

Public Types

enum class  ActualUse : bool { kNo = false , kYes = true }
 
enum class  AllowRecycling : bool { kNo = false , kYes = true }
 

Public Member Functions

 GrResourceAllocator (GrDirectContext *dContext)
 
 ~GrResourceAllocator ()
 
unsigned int curOp () const
 
void incOps ()
 
void addInterval (GrSurfaceProxy *, unsigned int start, unsigned int end, ActualUse actualUse, AllowRecycling SkDEBUGCODE(, bool isDirectDstRead=false))
 
bool failedInstantiation () const
 
bool planAssignment ()
 
bool makeBudgetHeadroom ()
 
void reset ()
 
bool assign ()
 

Detailed Description

Definition at line 78 of file GrResourceAllocator.h.

Member Enumeration Documentation

◆ ActualUse

enum class GrResourceAllocator::ActualUse : bool
strong

Indicates whether a given call to addInterval represents an actual usage of the provided proxy. This is mainly here to accommodate deferred proxies attached to opsTasks. In that case we need to create an extra long interval for them (due to the upload) but don't want to count that usage/reference towards the proxy's recyclability.

Enumerator
kNo 
kYes 

Definition at line 93 of file GrResourceAllocator.h.

93 : bool {
94 kNo = false,
95 kYes = true
96 };

◆ AllowRecycling

enum class GrResourceAllocator::AllowRecycling : bool
strong

Indicates whether we allow a gpu texture assigned to a register to be recycled or not. This comes up when dealing with with Vulkan Secondary CommandBuffers since offscreens sampled into the scb will all be drawn before being sampled in the scb. This is because the scb will get submitted in a later command buffer. Thus offscreens cannot share an allocation or later reuses will overwrite earlier ones.

Enumerator
kNo 
kYes 

Definition at line 104 of file GrResourceAllocator.h.

104 : bool {
105 kNo = false,
106 kYes = true
107 };

Constructor & Destructor Documentation

◆ GrResourceAllocator()

GrResourceAllocator::GrResourceAllocator ( GrDirectContext dContext)
inline

Definition at line 80 of file GrResourceAllocator.h.

81 : fDContext(dContext) {}

◆ ~GrResourceAllocator()

GrResourceAllocator::~GrResourceAllocator ( )

Definition at line 41 of file GrResourceAllocator.cpp.

41 {
42 SkASSERT(fFailedInstantiation || fIntvlList.empty());
43 SkASSERT(fActiveIntvls.empty());
44 SkASSERT(!fIntvlHash.count());
45}
#define SkASSERT(cond)
Definition SkAssert.h:116
int count() const
Definition SkTHash.h:460

Member Function Documentation

◆ addInterval()

void GrResourceAllocator::addInterval ( GrSurfaceProxy ,
unsigned int  start,
unsigned int  end,
ActualUse  actualUse,
AllowRecycling   SkDEBUGCODE, bool isDirectDstRead=false 
)

Definition at line 47 of file GrResourceAllocator.cpp.

49 {
50 SkASSERT(start <= end);
51 SkASSERT(!fAssigned); // We shouldn't be adding any intervals after (or during) assignment
52
53 if (proxy->canSkipResourceAllocator()) {
54 return;
55 }
56
57 // If a proxy is read only it must refer to a texture with specific content that cannot be
58 // recycled. We don't need to assign a texture to it and no other proxy can be instantiated
59 // with the same texture.
60 if (proxy->readOnly()) {
61 auto resourceProvider = fDContext->priv().resourceProvider();
62 if (proxy->isLazy() && !proxy->priv().doLazyInstantiation(resourceProvider)) {
63 fFailedInstantiation = true;
64 } else {
65 // Since we aren't going to add an interval we won't revisit this proxy in assign(). So
66 // must already be instantiated or it must be a lazy proxy that we instantiated above.
67 SkASSERT(proxy->isInstantiated());
68 }
69 return;
70 }
71 uint32_t proxyID = proxy->uniqueID().asUInt();
72 if (Interval** intvlPtr = fIntvlHash.find(proxyID)) {
73 // Revise the interval for an existing use
74 Interval* intvl = *intvlPtr;
75#ifdef SK_DEBUG
76 if (0 == start && 0 == end) {
77 // This interval is for the initial upload to a deferred proxy. Due to the vagaries
78 // of how deferred proxies are collected they can appear as uploads multiple times
79 // in a single opsTasks' list and as uploads in several opsTasks.
80 SkASSERT(0 == intvl->start());
81 } else if (isDirectDstRead) {
82 // Direct reads from the render target itself should occur w/in the existing
83 // interval
84 SkASSERT(intvl->start() <= start && intvl->end() >= end);
85 } else {
86 SkASSERT(intvl->end() <= start && intvl->end() <= end);
87 }
88#endif
89 if (ActualUse::kYes == actualUse) {
90 intvl->addUse();
91 }
92 if (allowRecycling == AllowRecycling::kNo) {
93 // In this case, a preexisting interval is made non-reuseable since its proxy is sampled
94 // into a secondary command buffer.
95 intvl->disallowRecycling();
96 }
97 intvl->extendEnd(end);
98 return;
99 }
100 Interval* newIntvl = fInternalAllocator.make<Interval>(proxy, start, end);
101
102 if (ActualUse::kYes == actualUse) {
103 newIntvl->addUse();
104 }
105 if (allowRecycling == AllowRecycling::kNo) {
106 newIntvl->disallowRecycling();
107 }
108 fIntvlList.insertByIncreasingStart(newIntvl);
109 fIntvlHash.set(proxyID, newIntvl);
110}
GrResourceProvider * resourceProvider()
GrDirectContextPriv priv()
auto make(Ctor &&ctor) -> decltype(ctor(nullptr))
V * find(const K &key) const
Definition SkTHash.h:479
V * set(K key, V val)
Definition SkTHash.h:472
glong glong end

◆ assign()

bool GrResourceAllocator::assign ( )

Definition at line 423 of file GrResourceAllocator.cpp.

423 {
424 if (fFailedInstantiation) {
425 return false;
426 }
427 SkASSERT(fPlanned && !fAssigned);
428 SkDEBUGCODE(fAssigned = true;)
429 auto resourceProvider = fDContext->priv().resourceProvider();
430 while (Interval* cur = fFinishedIntvls.popHead()) {
431 if (fFailedInstantiation) {
432 break;
433 }
434 if (cur->proxy()->isInstantiated()) {
435 continue;
436 }
437 if (cur->proxy()->isLazy()) {
438 fFailedInstantiation = !cur->proxy()->priv().doLazyInstantiation(resourceProvider);
439 continue;
440 }
441 Register* r = cur->getRegister();
442 SkASSERT(r);
443 fFailedInstantiation = !r->instantiateSurface(cur->proxy(), resourceProvider);
444 }
445 return !fFailedInstantiation;
446}
#define SkDEBUGCODE(...)
Definition SkDebug.h:23

◆ curOp()

unsigned int GrResourceAllocator::curOp ( ) const
inline

Definition at line 85 of file GrResourceAllocator.h.

85{ return fNumOps; }

◆ failedInstantiation()

bool GrResourceAllocator::failedInstantiation ( ) const
inline

Definition at line 114 of file GrResourceAllocator.h.

114{ return fFailedInstantiation; }

◆ incOps()

void GrResourceAllocator::incOps ( )
inline

Definition at line 86 of file GrResourceAllocator.h.

86{ fNumOps++; }

◆ makeBudgetHeadroom()

bool GrResourceAllocator::makeBudgetHeadroom ( )

Definition at line 383 of file GrResourceAllocator.cpp.

383 {
384 SkASSERT(fPlanned);
385 SkASSERT(!fFailedInstantiation);
386 size_t additionalBytesNeeded = 0;
387 for (Interval* cur = fFinishedIntvls.peekHead(); cur; cur = cur->next()) {
388 GrSurfaceProxy* proxy = cur->proxy();
389 if (skgpu::Budgeted::kNo == proxy->isBudgeted() || proxy->isInstantiated()) {
390 continue;
391 }
392
393 // N.B Fully-lazy proxies were already instantiated in planAssignment
394 if (proxy->isLazy()) {
395 additionalBytesNeeded += proxy->gpuMemorySize();
396 } else {
397 Register* r = cur->getRegister();
398 SkASSERT(r);
399 if (!r->accountedForInBudget() && !r->existingSurface()) {
400 additionalBytesNeeded += proxy->gpuMemorySize();
401 }
402 r->setAccountedForInBudget();
403 }
404 }
405 return fDContext->priv().getResourceCache()->purgeToMakeHeadroom(additionalBytesNeeded);
406}
GrResourceCache * getResourceCache()
bool purgeToMakeHeadroom(size_t desiredHeadroomBytes)
size_t gpuMemorySize() const
bool isLazy() const
skgpu::Budgeted isBudgeted() const
bool isInstantiated() const

◆ planAssignment()

bool GrResourceAllocator::planAssignment ( )

Definition at line 336 of file GrResourceAllocator.cpp.

336 {
337 fIntvlHash.reset(); // we don't need the interval hash anymore
338
339 SkASSERT(!fPlanned && !fAssigned);
340 SkDEBUGCODE(fPlanned = true;)
341
343 SkDebugf("assigning %d ops\n", fNumOps);
344 this->dumpIntervals();
345#endif
346
347 auto resourceProvider = fDContext->priv().resourceProvider();
348 while (Interval* cur = fIntvlList.popHead()) {
349 this->expire(cur->start());
350 fActiveIntvls.insertByIncreasingEnd(cur);
351
352 // Already-instantiated proxies and lazy proxies don't use registers.
353 if (cur->proxy()->isInstantiated()) {
354 continue;
355 }
356
357 // Instantiate fully-lazy proxies immediately. Ignore other lazy proxies at this stage.
358 if (cur->proxy()->isLazy()) {
359 if (cur->proxy()->isFullyLazy()) {
360 fFailedInstantiation = !cur->proxy()->priv().doLazyInstantiation(resourceProvider);
361 if (fFailedInstantiation) {
362 break;
363 }
364 }
365 continue;
366 }
367
368 Register* r = this->findOrCreateRegisterFor(cur->proxy());
369#if GR_ALLOCATION_SPEW
370 SkDebugf("Assigning register %d to %d\n",
371 r->uniqueID(),
372 cur->proxy()->uniqueID().asUInt());
373#endif
374 SkASSERT(!cur->proxy()->peekSurface());
375 cur->setRegister(r);
376 }
377
378 // expire all the remaining intervals to drain the active interval list
379 this->expire(std::numeric_limits<unsigned int>::max());
380 return !fFailedInstantiation;
381}
#define GR_ALLOCATION_SPEW
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1

◆ reset()

void GrResourceAllocator::reset ( )

Definition at line 408 of file GrResourceAllocator.cpp.

408 {
409 // NOTE: We do not reset the failedInstantiation flag because we currently do not attempt
410 // to recover from failed instantiations. The user is responsible for checking this flag and
411 // bailing early.
412 SkDEBUGCODE(fPlanned = false;)
413 SkDEBUGCODE(fAssigned = false;)
414 SkASSERT(fActiveIntvls.empty());
415 fFinishedIntvls = IntervalList();
416 fIntvlList = IntervalList();
417 fIntvlHash.reset();
418 fUniqueKeyRegisters.reset();
419 fFreePool.reset();
420 fInternalAllocator.reset();
421}
void reset()
Definition SkTMultiMap.h:35

The documentation for this class was generated from the following files: