Index: include/gpu/GrGpuResource.h |
diff --git a/include/gpu/GrGpuResource.h b/include/gpu/GrGpuResource.h |
index 61849e7232fd9f23df1219429d7355580a2606ef..0d523249e9cbd7c933b65d1557ccf02c69140e77 100644 |
--- a/include/gpu/GrGpuResource.h |
+++ b/include/gpu/GrGpuResource.h |
@@ -8,9 +8,10 @@ |
#ifndef GrGpuResource_DEFINED |
#define GrGpuResource_DEFINED |
+#include "GrResourceKey.h" |
+#include "GrTypesPriv.h" |
#include "SkInstCnt.h" |
#include "SkTInternalLList.h" |
-#include "GrResourceKey.h" |
class GrResourceCacheEntry; |
class GrResourceCache2; |
@@ -26,50 +27,39 @@ class GrContext; |
* 1) Normal ref (+ by ref(), - by unref()): These are used by code that is issuing draw calls |
* that read and write the resource via GrDrawTarget and by any object that must own a |
* GrGpuResource and is itself owned (directly or indirectly) by Skia-client code. |
- * 2) Pending read (+ by addPendingRead(), - by readCompleted()): GrContext has scheduled a read |
+ * 2) Pending read (+ by addPendingRead(), - by completedRead()): GrContext has scheduled a read |
* of the resource by the GPU as a result of a skia API call but hasn't executed it yet. |
- * 3) Pending write (+ by addPendingWrite(), - by writeCompleted()): GrContext has scheduled a |
+ * 3) Pending write (+ by addPendingWrite(), - by completedWrite()): GrContext has scheduled a |
* write to the resource by the GPU as a result of a skia API call but hasn't executed it yet. |
* |
* The latter two ref types are private and intended only for Gr core code. |
+ * |
+ * When an item is purgable DERIVED:notifyIsPurgable() will be called (static poly morphism using |
+ * CRTP). 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. |
*/ |
-class GrIORef : public SkNoncopyable { |
+template <typename DERIVED> class GrIORef : public SkNoncopyable { |
public: |
SK_DECLARE_INST_COUNT_ROOT(GrIORef) |
- |
- enum IOType { |
- kRead_IOType, |
- kWrite_IOType, |
- kRW_IOType |
- }; |
- |
virtual ~GrIORef(); |
// Some of the signatures are written to mirror SkRefCnt so that GrGpuResource can work with |
// templated helper classes (e.g. SkAutoTUnref). However, we have different categories of |
// refs (e.g. pending reads). We also don't require thread safety as GrCacheable objects are |
// not intended to cross thread boundaries. |
- // internal_dispose() exists because of GrTexture's reliance on it. It will be removed |
- // soon. |
void ref() const { |
- ++fRefCnt; |
- // pre-validate once internal_dispose is removed (and therefore 0 ref cnt is not allowed). |
this->validate(); |
+ ++fRefCnt; |
} |
void unref() const { |
this->validate(); |
--fRefCnt; |
- if (0 == fRefCnt && 0 == fPendingReads && 0 == fPendingWrites) { |
- this->internal_dispose(); |
- } |
+ this->didUnref(); |
} |
- virtual void internal_dispose() const { SkDELETE(this); } |
- |
- /** This is exists to service the old mechanism for recycling scratch textures. It will |
- be removed soon. */ |
- bool unique() const { return 1 == (fRefCnt + fPendingReads + fPendingWrites); } |
+ bool isPurgable() const { return this->reffedOnlyByCache() && !this->internalHasPendingIO(); } |
+ bool reffedOnlyByCache() const { return 1 == fRefCnt; } |
void validate() const { |
#ifdef SK_DEBUG |
@@ -80,9 +70,8 @@ public: |
#endif |
} |
- |
protected: |
- GrIORef() : fRefCnt(1), fPendingReads(0), fPendingWrites(0) {} |
+ GrIORef() : fRefCnt(1), fPendingReads(0), fPendingWrites(0), fIsScratch(kNo_IsScratch) { } |
bool internalHasPendingRead() const { return SkToBool(fPendingReads); } |
bool internalHasPendingWrite() const { return SkToBool(fPendingWrites); } |
@@ -97,9 +86,7 @@ private: |
void completedRead() const { |
this->validate(); |
--fPendingReads; |
- if (0 == fRefCnt && 0 == fPendingReads && 0 == fPendingWrites) { |
- this->internal_dispose(); |
- } |
+ this->didUnref(); |
} |
void addPendingWrite() const { |
@@ -110,25 +97,45 @@ private: |
void completedWrite() const { |
this->validate(); |
--fPendingWrites; |
- if (0 == fRefCnt && 0 == fPendingReads && 0 == fPendingWrites) { |
- this->internal_dispose(); |
- } |
+ this->didUnref(); |
} |
private: |
+ void didUnref() const { |
+ if (0 == fPendingReads && 0 == fPendingWrites) { |
+ if (0 == fRefCnt) { |
+ SkDELETE(this); |
+ } else if (1 == fRefCnt) { |
+ // The one ref is the cache's |
+ static_cast<const DERIVED*>(this)->notifyIsPurgable(); |
+ } |
+ } |
+ } |
+ |
mutable int32_t fRefCnt; |
mutable int32_t fPendingReads; |
mutable int32_t fPendingWrites; |
// This class is used to manage conversion of refs to pending reads/writes. |
friend class GrGpuResourceRef; |
- template <typename, IOType> friend class GrPendingIOResource; |
+ |
+ // This is temporary until GrResourceCache is fully replaced by GrResourceCache2. |
+ enum IsScratch { |
+ kNo_IsScratch, |
+ kYes_IsScratch |
+ } fIsScratch; |
+ |
+ friend class GrContext; // to set the above field. |
+ friend class GrResourceCache; // to check the above field. |
+ friend class GrResourceCache2; // to check the above field. |
+ |
+ template <typename, GrIOType> friend class GrPendingIOResource; |
}; |
/** |
* Base class for objects that can be kept in the GrResourceCache. |
*/ |
-class GrGpuResource : public GrIORef { |
+class GrGpuResource : public GrIORef<GrGpuResource> { |
public: |
SK_DECLARE_INST_COUNT(GrGpuResource) |
@@ -175,7 +182,7 @@ public: |
virtual size_t gpuMemorySize() const = 0; |
void setCacheEntry(GrResourceCacheEntry* cacheEntry) { fCacheEntry = cacheEntry; } |
- GrResourceCacheEntry* getCacheEntry() { return fCacheEntry; } |
+ GrResourceCacheEntry* getCacheEntry() const { return fCacheEntry; } |
/** |
* If this resource can be used as a scratch resource this returns a valid |
@@ -224,6 +231,8 @@ protected: |
void setScratchKey(const GrResourceKey& scratchKey); |
private: |
+ void notifyIsPurgable() const; |
+ |
#ifdef SK_DEBUG |
friend class GrGpu; // for assert in GrGpu to access getGpu |
#endif |
@@ -253,7 +262,8 @@ private: |
GrResourceKey fScratchKey; |
- typedef GrIORef INHERITED; |
+ typedef GrIORef<GrGpuResource> INHERITED; |
+ friend class GrIORef<GrGpuResource>; // to access notifyIsPurgable. |
}; |
#endif |