OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef GrGpuResource_DEFINED | 8 #ifndef GrGpuResource_DEFINED |
9 #define GrGpuResource_DEFINED | 9 #define GrGpuResource_DEFINED |
10 | 10 |
(...skipping 15 matching lines...) Expand all Loading... |
26 * 1) Normal ref (+ by ref(), - by unref()): These are used by code that is is
suing draw calls | 26 * 1) Normal ref (+ by ref(), - by unref()): These are used by code that is is
suing draw calls |
27 * that read and write the resource via GrDrawTarget and by any object that
must own a | 27 * that read and write the resource via GrDrawTarget and by any object that
must own a |
28 * GrGpuResource and is itself owned (directly or indirectly) by Skia-clien
t code. | 28 * GrGpuResource and is itself owned (directly or indirectly) by Skia-clien
t code. |
29 * 2) Pending read (+ by addPendingRead(), - by completedRead()): GrContext ha
s scheduled a read | 29 * 2) Pending read (+ by addPendingRead(), - by completedRead()): GrContext ha
s scheduled a read |
30 * of the resource by the GPU as a result of a skia API call but hasn't exe
cuted it yet. | 30 * of the resource by the GPU as a result of a skia API call but hasn't exe
cuted it yet. |
31 * 3) Pending write (+ by addPendingWrite(), - by completedWrite()): GrContext
has scheduled a | 31 * 3) Pending write (+ by addPendingWrite(), - by completedWrite()): GrContext
has scheduled a |
32 * write to the resource by the GPU as a result of a skia API call but hasn
't executed it yet. | 32 * write to the resource by the GPU as a result of a skia API call but hasn
't executed it yet. |
33 * | 33 * |
34 * The latter two ref types are private and intended only for Gr core code. | 34 * The latter two ref types are private and intended only for Gr core code. |
35 * | 35 * |
36 * When an item is purgeable DERIVED:notifyIsPurgeable() will be called (static
poly morphism using | 36 * When all the ref/io counts reach zero DERIVED::notifyAllCntsAreZero() will be
called (static poly |
37 * CRTP). GrIORef and GrGpuResource are separate classes for organizational reas
ons and to be | 37 * morphism using CRTP). Similarly when the ref (but not necessarily pending rea
d/write) count |
| 38 * reaches 0 DERIVED::notifyRefCountIsZero() will be called. In the case when an
unref() causes both |
| 39 * the ref cnt to reach zero and the other counts are zero, notifyRefCountIsZero
() will be called |
| 40 * before notifyIsPurgeable(). Moreover, if notifyRefCountIsZero() returns false
then |
| 41 * notifyAllRefCntsAreZero() won't be called at all. notifyRefCountIsZero() must
return false if the |
| 42 * object may be deleted after notifyRefCntIsZero() returns. |
| 43 * |
| 44 * GrIORef and GrGpuResource are separate classes for organizational reasons and
to be |
38 * able to give access via friendship to only the functions related to pending I
O operations. | 45 * able to give access via friendship to only the functions related to pending I
O operations. |
39 */ | 46 */ |
40 template <typename DERIVED> class GrIORef : public SkNoncopyable { | 47 template <typename DERIVED> class GrIORef : public SkNoncopyable { |
41 public: | 48 public: |
42 SK_DECLARE_INST_COUNT(GrIORef) | 49 SK_DECLARE_INST_COUNT(GrIORef) |
43 | 50 |
44 // Some of the signatures are written to mirror SkRefCnt so that GrGpuResour
ce can work with | 51 // Some of the signatures are written to mirror SkRefCnt so that GrGpuResour
ce can work with |
45 // templated helper classes (e.g. SkAutoTUnref). However, we have different
categories of | 52 // templated helper classes (e.g. SkAutoTUnref). However, we have different
categories of |
46 // refs (e.g. pending reads). We also don't require thread safety as GrCache
able objects are | 53 // refs (e.g. pending reads). We also don't require thread safety as GrCache
able objects are |
47 // not intended to cross thread boundaries. | 54 // not intended to cross thread boundaries. |
48 void ref() const { | 55 void ref() const { |
49 this->validate(); | 56 this->validate(); |
50 ++fRefCnt; | 57 ++fRefCnt; |
51 } | 58 } |
52 | 59 |
53 void unref() const { | 60 void unref() const { |
54 this->validate(); | 61 this->validate(); |
55 --fRefCnt; | 62 |
56 this->didUnref(); | 63 if (!(--fRefCnt)) { |
| 64 if (!static_cast<const DERIVED*>(this)->notifyRefCountIsZero()) { |
| 65 return; |
| 66 } |
| 67 } |
| 68 |
| 69 this->didRemoveRefOrPendingIO(kRef_CntType); |
57 } | 70 } |
58 | 71 |
59 void validate() const { | 72 void validate() const { |
60 #ifdef SK_DEBUG | 73 #ifdef SK_DEBUG |
61 SkASSERT(fRefCnt >= 0); | 74 SkASSERT(fRefCnt >= 0); |
62 SkASSERT(fPendingReads >= 0); | 75 SkASSERT(fPendingReads >= 0); |
63 SkASSERT(fPendingWrites >= 0); | 76 SkASSERT(fPendingWrites >= 0); |
64 SkASSERT(fRefCnt + fPendingReads + fPendingWrites >= 0); | 77 SkASSERT(fRefCnt + fPendingReads + fPendingWrites >= 0); |
65 #endif | 78 #endif |
66 } | 79 } |
67 | 80 |
68 protected: | 81 protected: |
69 GrIORef() : fRefCnt(1), fPendingReads(0), fPendingWrites(0) { } | 82 GrIORef() : fRefCnt(1), fPendingReads(0), fPendingWrites(0) { } |
70 | 83 |
| 84 enum CntType { |
| 85 kRef_CntType, |
| 86 kPendingRead_CntType, |
| 87 kPendingWrite_CntType, |
| 88 }; |
| 89 |
71 bool isPurgeable() const { return !this->internalHasRef() && !this->internal
HasPendingIO(); } | 90 bool isPurgeable() const { return !this->internalHasRef() && !this->internal
HasPendingIO(); } |
72 | 91 |
73 bool internalHasPendingRead() const { return SkToBool(fPendingReads); } | 92 bool internalHasPendingRead() const { return SkToBool(fPendingReads); } |
74 bool internalHasPendingWrite() const { return SkToBool(fPendingWrites); } | 93 bool internalHasPendingWrite() const { return SkToBool(fPendingWrites); } |
75 bool internalHasPendingIO() const { return SkToBool(fPendingWrites | fPendin
gReads); } | 94 bool internalHasPendingIO() const { return SkToBool(fPendingWrites | fPendin
gReads); } |
76 | 95 |
77 bool internalHasRef() const { return SkToBool(fRefCnt); } | 96 bool internalHasRef() const { return SkToBool(fRefCnt); } |
78 | 97 |
79 private: | 98 private: |
80 void addPendingRead() const { | 99 void addPendingRead() const { |
81 this->validate(); | 100 this->validate(); |
82 ++fPendingReads; | 101 ++fPendingReads; |
83 } | 102 } |
84 | 103 |
85 void completedRead() const { | 104 void completedRead() const { |
86 this->validate(); | 105 this->validate(); |
87 --fPendingReads; | 106 --fPendingReads; |
88 this->didUnref(); | 107 this->didRemoveRefOrPendingIO(kPendingRead_CntType); |
89 } | 108 } |
90 | 109 |
91 void addPendingWrite() const { | 110 void addPendingWrite() const { |
92 this->validate(); | 111 this->validate(); |
93 ++fPendingWrites; | 112 ++fPendingWrites; |
94 } | 113 } |
95 | 114 |
96 void completedWrite() const { | 115 void completedWrite() const { |
97 this->validate(); | 116 this->validate(); |
98 --fPendingWrites; | 117 --fPendingWrites; |
99 this->didUnref(); | 118 this->didRemoveRefOrPendingIO(kPendingWrite_CntType); |
100 } | 119 } |
101 | 120 |
102 private: | 121 private: |
103 void didUnref() const { | 122 void didRemoveRefOrPendingIO(CntType cntTypeRemoved) const { |
104 if (0 == fPendingReads && 0 == fPendingWrites && 0 == fRefCnt) { | 123 if (0 == fPendingReads && 0 == fPendingWrites && 0 == fRefCnt) { |
105 static_cast<const DERIVED*>(this)->notifyIsPurgeable(); | 124 static_cast<const DERIVED*>(this)->notifyAllCntsAreZero(cntTypeRemov
ed); |
106 } | 125 } |
107 } | 126 } |
108 | 127 |
109 mutable int32_t fRefCnt; | 128 mutable int32_t fRefCnt; |
110 mutable int32_t fPendingReads; | 129 mutable int32_t fPendingReads; |
111 mutable int32_t fPendingWrites; | 130 mutable int32_t fPendingWrites; |
112 | 131 |
113 // This class is used to manage conversion of refs to pending reads/writes. | 132 // This class is used to manage conversion of refs to pending reads/writes. |
114 friend class GrGpuResourceRef; | 133 friend class GrGpuResourceRef; |
115 friend class GrResourceCache; // to check IO ref counts. | 134 friend class GrResourceCache; // to check IO ref counts. |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 /** | 283 /** |
265 * Frees the object in the underlying 3D API. Called by CacheAccess. | 284 * Frees the object in the underlying 3D API. Called by CacheAccess. |
266 */ | 285 */ |
267 void release(); | 286 void release(); |
268 | 287 |
269 virtual size_t onGpuMemorySize() const = 0; | 288 virtual size_t onGpuMemorySize() const = 0; |
270 | 289 |
271 // See comments in CacheAccess and ResourcePriv. | 290 // See comments in CacheAccess and ResourcePriv. |
272 void setUniqueKey(const GrUniqueKey&); | 291 void setUniqueKey(const GrUniqueKey&); |
273 void removeUniqueKey(); | 292 void removeUniqueKey(); |
274 void notifyIsPurgeable() const; | 293 void notifyAllCntsAreZero(CntType) const; |
| 294 bool notifyRefCountIsZero() const; |
275 void removeScratchKey(); | 295 void removeScratchKey(); |
276 void makeBudgeted(); | 296 void makeBudgeted(); |
277 void makeUnbudgeted(); | 297 void makeUnbudgeted(); |
278 | 298 |
279 #ifdef SK_DEBUG | 299 #ifdef SK_DEBUG |
280 friend class GrGpu; // for assert in GrGpu to access getGpu | 300 friend class GrGpu; // for assert in GrGpu to access getGpu |
281 #endif | 301 #endif |
282 | 302 |
283 static uint32_t CreateUniqueID(); | 303 static uint32_t CreateUniqueID(); |
284 | 304 |
(...skipping 12 matching lines...) Expand all Loading... |
297 // is destroyed. Those calls set will this to NULL. | 317 // is destroyed. Those calls set will this to NULL. |
298 GrGpu* fGpu; | 318 GrGpu* fGpu; |
299 mutable size_t fGpuMemorySize; | 319 mutable size_t fGpuMemorySize; |
300 | 320 |
301 LifeCycle fLifeCycle; | 321 LifeCycle fLifeCycle; |
302 const uint32_t fUniqueID; | 322 const uint32_t fUniqueID; |
303 | 323 |
304 SkAutoTUnref<const SkData> fData; | 324 SkAutoTUnref<const SkData> fData; |
305 | 325 |
306 typedef GrIORef<GrGpuResource> INHERITED; | 326 typedef GrIORef<GrGpuResource> INHERITED; |
307 friend class GrIORef<GrGpuResource>; // to access notifyIsPurgeable. | 327 friend class GrIORef<GrGpuResource>; // to access notifyAllCntsAreZero and n
otifyRefCntIsZero. |
308 }; | 328 }; |
309 | 329 |
310 #endif | 330 #endif |
OLD | NEW |