From 3f324321cdd8fde7976d958e2888a1ec4e657e35 Mon Sep 17 00:00:00 2001 From: bsalomon Date: Wed, 8 Apr 2015 11:01:54 -0700 Subject: Add mechanism to proactively purge old resources in GrResourceCache. This change leaves the feature turned off by default. Review URL: https://codereview.chromium.org/1032873002 --- include/gpu/GrGpuResource.h | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) (limited to 'include/gpu/GrGpuResource.h') diff --git a/include/gpu/GrGpuResource.h b/include/gpu/GrGpuResource.h index e2f23e0289..5a35ab794a 100644 --- a/include/gpu/GrGpuResource.h +++ b/include/gpu/GrGpuResource.h @@ -33,8 +33,15 @@ class GrResourceCache; * * The latter two ref types are private and intended only for Gr core code. * - * When an item is purgeable DERIVED:notifyIsPurgeable() will be called (static poly morphism using - * CRTP). GrIORef and GrGpuResource are separate classes for organizational reasons and to be + * When all the ref/io counts reach zero DERIVED::notifyAllCntsAreZero() will be called (static poly + * morphism using CRTP). Similarly when the ref (but not necessarily pending read/write) count + * reaches 0 DERIVED::notifyRefCountIsZero() will be called. In the case when an unref() causes both + * the ref cnt to reach zero and the other counts are zero, notifyRefCountIsZero() will be called + * before notifyIsPurgeable(). Moreover, if notifyRefCountIsZero() returns false then + * notifyAllRefCntsAreZero() won't be called at all. notifyRefCountIsZero() must return false if the + * object may be deleted after notifyRefCntIsZero() returns. + * + * GrIORef and GrGpuResource are separate classes for organizational reasons and to be * able to give access via friendship to only the functions related to pending IO operations. */ template class GrIORef : public SkNoncopyable { @@ -52,8 +59,14 @@ public: void unref() const { this->validate(); - --fRefCnt; - this->didUnref(); + + if (!(--fRefCnt)) { + if (!static_cast(this)->notifyRefCountIsZero()) { + return; + } + } + + this->didRemoveRefOrPendingIO(kRef_CntType); } void validate() const { @@ -68,6 +81,12 @@ public: protected: GrIORef() : fRefCnt(1), fPendingReads(0), fPendingWrites(0) { } + enum CntType { + kRef_CntType, + kPendingRead_CntType, + kPendingWrite_CntType, + }; + bool isPurgeable() const { return !this->internalHasRef() && !this->internalHasPendingIO(); } bool internalHasPendingRead() const { return SkToBool(fPendingReads); } @@ -85,7 +104,7 @@ private: void completedRead() const { this->validate(); --fPendingReads; - this->didUnref(); + this->didRemoveRefOrPendingIO(kPendingRead_CntType); } void addPendingWrite() const { @@ -96,13 +115,13 @@ private: void completedWrite() const { this->validate(); --fPendingWrites; - this->didUnref(); + this->didRemoveRefOrPendingIO(kPendingWrite_CntType); } private: - void didUnref() const { + void didRemoveRefOrPendingIO(CntType cntTypeRemoved) const { if (0 == fPendingReads && 0 == fPendingWrites && 0 == fRefCnt) { - static_cast(this)->notifyIsPurgeable(); + static_cast(this)->notifyAllCntsAreZero(cntTypeRemoved); } } @@ -271,7 +290,8 @@ private: // See comments in CacheAccess and ResourcePriv. void setUniqueKey(const GrUniqueKey&); void removeUniqueKey(); - void notifyIsPurgeable() const; + void notifyAllCntsAreZero(CntType) const; + bool notifyRefCountIsZero() const; void removeScratchKey(); void makeBudgeted(); void makeUnbudgeted(); @@ -304,7 +324,7 @@ private: SkAutoTUnref fData; typedef GrIORef INHERITED; - friend class GrIORef; // to access notifyIsPurgeable. + friend class GrIORef; // to access notifyAllCntsAreZero and notifyRefCntIsZero. }; #endif -- cgit v1.2.3