OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2014 Google Inc. | 3 * Copyright 2014 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #ifndef GrResourceCache_DEFINED | 9 #ifndef GrResourceCache_DEFINED |
10 #define GrResourceCache_DEFINED | 10 #define GrResourceCache_DEFINED |
(...skipping 11 matching lines...) Expand all Loading... |
22 | 22 |
23 class SkString; | 23 class SkString; |
24 | 24 |
25 /** | 25 /** |
26 * Manages the lifetime of all GrGpuResource instances. | 26 * Manages the lifetime of all GrGpuResource instances. |
27 * | 27 * |
28 * Resources may have optionally have two types of keys: | 28 * Resources may have optionally have two types of keys: |
29 * 1) A scratch key. This is for resources whose allocations are cached but
not their contents. | 29 * 1) A scratch key. This is for resources whose allocations are cached but
not their contents. |
30 * Multiple resources can share the same scratch key. This is so a calle
r can have two | 30 * Multiple resources can share the same scratch key. This is so a calle
r can have two |
31 * resource instances with the same properties (e.g. multipass rendering
that ping-pongs | 31 * resource instances with the same properties (e.g. multipass rendering
that ping-pongs |
32 * between two temporary surfaces. The scratch key is set at resource cr
eation time and | 32 * between two temporary surfaces). The scratch key is set at resource c
reation time and |
33 * should never change. Resources need not have a scratch key. | 33 * should never change. Resources need not have a scratch key. |
34 * 2) A content key. This key represents the contents of the resource rathe
r than just its | 34 * 2) A unique key. This key's meaning is specific to the domain that creat
ed the key. Only one |
35 * allocation properties. They may not collide. The content key can be s
et after resource | 35 * resource may have a given unique key. The unique key can be set after
resource creation |
36 * creation. Currently it may only be set once and cannot be cleared. Th
is restriction will | 36 * creation. Currently it may only be set once and cannot be cleared. Th
is restriction will |
37 * be removed. | 37 * be removed. |
| 38 * A unique key always takes precedence over a scratch key when a resource has b
oth types of keys. |
38 * If a resource has neither key type then it will be deleted as soon as the las
t reference to it | 39 * If a resource has neither key type then it will be deleted as soon as the las
t reference to it |
39 * is dropped. If a key has both keys the content key takes precedence. | 40 * is dropped. |
40 */ | 41 */ |
41 class GrResourceCache { | 42 class GrResourceCache { |
42 public: | 43 public: |
43 GrResourceCache(); | 44 GrResourceCache(); |
44 ~GrResourceCache(); | 45 ~GrResourceCache(); |
45 | 46 |
46 /** Used to access functionality needed by GrGpuResource for lifetime manage
ment. */ | 47 /** Used to access functionality needed by GrGpuResource for lifetime manage
ment. */ |
47 class ResourceAccess; | 48 class ResourceAccess; |
48 ResourceAccess resourceAccess(); | 49 ResourceAccess resourceAccess(); |
49 | 50 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 GrGpuResource* findAndRefScratchResource(const GrScratchKey& scratchKey, uin
t32_t flags = 0); | 110 GrGpuResource* findAndRefScratchResource(const GrScratchKey& scratchKey, uin
t32_t flags = 0); |
110 | 111 |
111 #ifdef SK_DEBUG | 112 #ifdef SK_DEBUG |
112 // This is not particularly fast and only used for validation, so debug only
. | 113 // This is not particularly fast and only used for validation, so debug only
. |
113 int countScratchEntriesForKey(const GrScratchKey& scratchKey) const { | 114 int countScratchEntriesForKey(const GrScratchKey& scratchKey) const { |
114 return fScratchMap.countForKey(scratchKey); | 115 return fScratchMap.countForKey(scratchKey); |
115 } | 116 } |
116 #endif | 117 #endif |
117 | 118 |
118 /** | 119 /** |
119 * Find a resource that matches a content key. | 120 * Find a resource that matches a unique key. |
120 */ | 121 */ |
121 GrGpuResource* findAndRefContentResource(const GrContentKey& contentKey) { | 122 GrGpuResource* findAndRefUniqueResource(const GrUniqueKey& key) { |
122 GrGpuResource* resource = fContentHash.find(contentKey); | 123 GrGpuResource* resource = fUniqueHash.find(key); |
123 if (resource) { | 124 if (resource) { |
124 this->refAndMakeResourceMRU(resource); | 125 this->refAndMakeResourceMRU(resource); |
125 } | 126 } |
126 return resource; | 127 return resource; |
127 } | 128 } |
128 | 129 |
129 /** | 130 /** |
130 * Query whether a content key exists in the cache. | 131 * Query whether a unique key exists in the cache. |
131 */ | 132 */ |
132 bool hasContentKey(const GrContentKey& contentKey) const { | 133 bool hasUniqueKey(const GrUniqueKey& key) const { |
133 return SkToBool(fContentHash.find(contentKey)); | 134 return SkToBool(fUniqueHash.find(key)); |
134 } | 135 } |
135 | 136 |
136 /** Purges resources to become under budget and processes resources with inv
alidated content | 137 /** Purges resources to become under budget and processes resources with inv
alidated unique |
137 keys. */ | 138 keys. */ |
138 void purgeAsNeeded() { | 139 void purgeAsNeeded() { |
139 SkTArray<GrContentKeyInvalidatedMessage> invalidKeyMsgs; | 140 SkTArray<GrUniqueKeyInvalidatedMessage> invalidKeyMsgs; |
140 fInvalidContentKeyInbox.poll(&invalidKeyMsgs); | 141 fInvalidUniqueKeyInbox.poll(&invalidKeyMsgs); |
141 if (invalidKeyMsgs.count()) { | 142 if (invalidKeyMsgs.count()) { |
142 this->processInvalidContentKeys(invalidKeyMsgs); | 143 this->processInvalidUniqueKeys(invalidKeyMsgs); |
143 } | 144 } |
144 if (fBudgetedCount <= fMaxCount && fBudgetedBytes <= fMaxBytes) { | 145 if (fBudgetedCount <= fMaxCount && fBudgetedBytes <= fMaxBytes) { |
145 return; | 146 return; |
146 } | 147 } |
147 this->internalPurgeAsNeeded(); | 148 this->internalPurgeAsNeeded(); |
148 } | 149 } |
149 | 150 |
150 /** Purges all resources that don't have external owners. */ | 151 /** Purges all resources that don't have external owners. */ |
151 void purgeAllUnlocked(); | 152 void purgeAllUnlocked(); |
152 | 153 |
(...skipping 18 matching lines...) Expand all Loading... |
171 #endif | 172 #endif |
172 | 173 |
173 private: | 174 private: |
174 /////////////////////////////////////////////////////////////////////////// | 175 /////////////////////////////////////////////////////////////////////////// |
175 /// @name Methods accessible via ResourceAccess | 176 /// @name Methods accessible via ResourceAccess |
176 //// | 177 //// |
177 void insertResource(GrGpuResource*); | 178 void insertResource(GrGpuResource*); |
178 void removeResource(GrGpuResource*); | 179 void removeResource(GrGpuResource*); |
179 void notifyPurgeable(GrGpuResource*); | 180 void notifyPurgeable(GrGpuResource*); |
180 void didChangeGpuMemorySize(const GrGpuResource*, size_t oldSize); | 181 void didChangeGpuMemorySize(const GrGpuResource*, size_t oldSize); |
181 bool didSetContentKey(GrGpuResource*); | 182 bool didSetUniqueKey(GrGpuResource*); |
182 void willRemoveScratchKey(const GrGpuResource*); | 183 void willRemoveScratchKey(const GrGpuResource*); |
183 void willRemoveContentKey(const GrGpuResource*); | 184 void willRemoveUniqueKey(const GrGpuResource*); |
184 void didChangeBudgetStatus(GrGpuResource*); | 185 void didChangeBudgetStatus(GrGpuResource*); |
185 void refAndMakeResourceMRU(GrGpuResource*); | 186 void refAndMakeResourceMRU(GrGpuResource*); |
186 /// @} | 187 /// @} |
187 | 188 |
188 void internalPurgeAsNeeded(); | 189 void internalPurgeAsNeeded(); |
189 void processInvalidContentKeys(const SkTArray<GrContentKeyInvalidatedMessage
>&); | 190 void processInvalidUniqueKeys(const SkTArray<GrUniqueKeyInvalidatedMessage>&
); |
190 void addToNonpurgeableArray(GrGpuResource*); | 191 void addToNonpurgeableArray(GrGpuResource*); |
191 void removeFromNonpurgeableArray(GrGpuResource*); | 192 void removeFromNonpurgeableArray(GrGpuResource*); |
192 bool overBudget() const { return fBudgetedBytes > fMaxBytes || fBudgetedCoun
t > fMaxCount; } | 193 bool overBudget() const { return fBudgetedBytes > fMaxBytes || fBudgetedCoun
t > fMaxCount; } |
193 | 194 |
194 #ifdef SK_DEBUG | 195 #ifdef SK_DEBUG |
195 bool isInCache(const GrGpuResource* r) const; | 196 bool isInCache(const GrGpuResource* r) const; |
196 void validate() const; | 197 void validate() const; |
197 #else | 198 #else |
198 void validate() const {} | 199 void validate() const {} |
199 #endif | 200 #endif |
200 | 201 |
201 class AutoValidate; | 202 class AutoValidate; |
202 | 203 |
203 class AvailableForScratchUse; | 204 class AvailableForScratchUse; |
204 | 205 |
205 struct ScratchMapTraits { | 206 struct ScratchMapTraits { |
206 static const GrScratchKey& GetKey(const GrGpuResource& r) { | 207 static const GrScratchKey& GetKey(const GrGpuResource& r) { |
207 return r.resourcePriv().getScratchKey(); | 208 return r.resourcePriv().getScratchKey(); |
208 } | 209 } |
209 | 210 |
210 static uint32_t Hash(const GrScratchKey& key) { return key.hash(); } | 211 static uint32_t Hash(const GrScratchKey& key) { return key.hash(); } |
211 }; | 212 }; |
212 typedef SkTMultiMap<GrGpuResource, GrScratchKey, ScratchMapTraits> ScratchMa
p; | 213 typedef SkTMultiMap<GrGpuResource, GrScratchKey, ScratchMapTraits> ScratchMa
p; |
213 | 214 |
214 struct ContentHashTraits { | 215 struct UniqueHashTraits { |
215 static const GrContentKey& GetKey(const GrGpuResource& r) { | 216 static const GrUniqueKey& GetKey(const GrGpuResource& r) { return r.getU
niqueKey(); } |
216 return r.getContentKey(); | |
217 } | |
218 | 217 |
219 static uint32_t Hash(const GrContentKey& key) { return key.hash(); } | 218 static uint32_t Hash(const GrUniqueKey& key) { return key.hash(); } |
220 }; | 219 }; |
221 typedef SkTDynamicHash<GrGpuResource, GrContentKey, ContentHashTraits> Conte
ntHash; | 220 typedef SkTDynamicHash<GrGpuResource, GrUniqueKey, UniqueHashTraits> UniqueH
ash; |
222 | 221 |
223 static bool CompareTimestamp(GrGpuResource* const& a, GrGpuResource* const&
b) { | 222 static bool CompareTimestamp(GrGpuResource* const& a, GrGpuResource* const&
b) { |
224 return a->cacheAccess().timestamp() < b->cacheAccess().timestamp(); | 223 return a->cacheAccess().timestamp() < b->cacheAccess().timestamp(); |
225 } | 224 } |
226 | 225 |
227 static int* AccessResourceIndex(GrGpuResource* const& res) { | 226 static int* AccessResourceIndex(GrGpuResource* const& res) { |
228 return res->cacheAccess().accessCacheIndex(); | 227 return res->cacheAccess().accessCacheIndex(); |
229 } | 228 } |
230 | 229 |
231 typedef SkMessageBus<GrContentKeyInvalidatedMessage>::Inbox InvalidContentKe
yInbox; | 230 typedef SkMessageBus<GrUniqueKeyInvalidatedMessage>::Inbox InvalidUniqueKeyI
nbox; |
232 typedef SkTDPQueue<GrGpuResource*, CompareTimestamp, AccessResourceIndex> Pu
rgeableQueue; | 231 typedef SkTDPQueue<GrGpuResource*, CompareTimestamp, AccessResourceIndex> Pu
rgeableQueue; |
233 typedef SkTDArray<GrGpuResource*> ResourceArray; | 232 typedef SkTDArray<GrGpuResource*> ResourceArray; |
234 | 233 |
235 // Whenever a resource is added to the cache or the result of a cache lookup
, fTimestamp is | 234 // Whenever a resource is added to the cache or the result of a cache lookup
, fTimestamp is |
236 // assigned as the resource's timestamp and then incremented. fPurgeableQueu
e orders the | 235 // assigned as the resource's timestamp and then incremented. fPurgeableQueu
e orders the |
237 // purgeable resources by this value, and thus is used to purge resources in
LRU order. | 236 // purgeable resources by this value, and thus is used to purge resources in
LRU order. |
238 uint32_t fTimestamp; | 237 uint32_t fTimestamp; |
239 PurgeableQueue fPurgeableQueue; | 238 PurgeableQueue fPurgeableQueue; |
240 ResourceArray fNonpurgeableResources; | 239 ResourceArray fNonpurgeableResources; |
241 | 240 |
242 // This map holds all resources that can be used as scratch resources. | 241 // This map holds all resources that can be used as scratch resources. |
243 ScratchMap fScratchMap; | 242 ScratchMap fScratchMap; |
244 // This holds all resources that have content keys. | 243 // This holds all resources that have unique keys. |
245 ContentHash fContentHash; | 244 UniqueHash fUniqueHash; |
246 | 245 |
247 // our budget, used in purgeAsNeeded() | 246 // our budget, used in purgeAsNeeded() |
248 int fMaxCount; | 247 int fMaxCount; |
249 size_t fMaxBytes; | 248 size_t fMaxBytes; |
250 | 249 |
251 #if GR_CACHE_STATS | 250 #if GR_CACHE_STATS |
252 int fHighWaterCount; | 251 int fHighWaterCount; |
253 size_t fHighWaterBytes; | 252 size_t fHighWaterBytes; |
254 int fBudgetedHighWaterCount; | 253 int fBudgetedHighWaterCount; |
255 size_t fBudgetedHighWaterBytes; | 254 size_t fBudgetedHighWaterBytes; |
256 #endif | 255 #endif |
257 | 256 |
258 // our current stats for all resources | 257 // our current stats for all resources |
259 SkDEBUGCODE(int fCount;) | 258 SkDEBUGCODE(int fCount;) |
260 size_t fBytes; | 259 size_t fBytes; |
261 | 260 |
262 // our current stats for resources that count against the budget | 261 // our current stats for resources that count against the budget |
263 int fBudgetedCount; | 262 int fBudgetedCount; |
264 size_t fBudgetedBytes; | 263 size_t fBudgetedBytes; |
265 | 264 |
266 PFOverBudgetCB fOverBudgetCB; | 265 PFOverBudgetCB fOverBudgetCB; |
267 void* fOverBudgetData; | 266 void* fOverBudgetData; |
268 | 267 |
269 InvalidContentKeyInbox fInvalidContentKeyInbox; | 268 InvalidUniqueKeyInbox fInvalidUniqueKeyInbox; |
270 }; | 269 }; |
271 | 270 |
272 class GrResourceCache::ResourceAccess { | 271 class GrResourceCache::ResourceAccess { |
273 private: | 272 private: |
274 ResourceAccess(GrResourceCache* cache) : fCache(cache) { } | 273 ResourceAccess(GrResourceCache* cache) : fCache(cache) { } |
275 ResourceAccess(const ResourceAccess& that) : fCache(that.fCache) { } | 274 ResourceAccess(const ResourceAccess& that) : fCache(that.fCache) { } |
276 ResourceAccess& operator=(const ResourceAccess&); // unimpl | 275 ResourceAccess& operator=(const ResourceAccess&); // unimpl |
277 | 276 |
278 /** | 277 /** |
279 * Insert a resource into the cache. | 278 * Insert a resource into the cache. |
(...skipping 11 matching lines...) Expand all Loading... |
291 void notifyPurgeable(GrGpuResource* resource) { fCache->notifyPurgeable(reso
urce); } | 290 void notifyPurgeable(GrGpuResource* resource) { fCache->notifyPurgeable(reso
urce); } |
292 | 291 |
293 /** | 292 /** |
294 * Called by GrGpuResources when their sizes change. | 293 * Called by GrGpuResources when their sizes change. |
295 */ | 294 */ |
296 void didChangeGpuMemorySize(const GrGpuResource* resource, size_t oldSize) { | 295 void didChangeGpuMemorySize(const GrGpuResource* resource, size_t oldSize) { |
297 fCache->didChangeGpuMemorySize(resource, oldSize); | 296 fCache->didChangeGpuMemorySize(resource, oldSize); |
298 } | 297 } |
299 | 298 |
300 /** | 299 /** |
301 * Called by GrGpuResources when their content keys change. | 300 * Called by GrGpuResources when their unique keys change. |
302 * | 301 * |
303 * This currently returns a bool and fails when an existing resource has a k
ey that collides | 302 * This currently returns a bool and fails when an existing resource has a k
ey that collides |
304 * with the new content key. In the future it will null out the content key
for the existing | 303 * with the new key. In the future it will null out the unique key for the e
xisting resource. |
305 * resource. The failure is a temporary measure taken because duties are spl
it between two | 304 * The failure is a temporary measure which will be fixed soon. |
306 * cache objects currently. | |
307 */ | 305 */ |
308 bool didSetContentKey(GrGpuResource* resource) { return fCache->didSetConten
tKey(resource); } | 306 bool didSetUniqueKey(GrGpuResource* resource) { return fCache->didSetUniqueK
ey(resource); } |
309 | 307 |
310 /** | 308 /** |
311 * Called by a GrGpuResource when it removes its content key. | 309 * Called by a GrGpuResource when it removes its unique key. |
312 */ | 310 */ |
313 void willRemoveContentKey(GrGpuResource* resource) { | 311 void willRemoveUniqueKey(GrGpuResource* resource) { |
314 return fCache->willRemoveContentKey(resource); | 312 return fCache->willRemoveUniqueKey(resource); |
315 } | 313 } |
316 | 314 |
317 /** | 315 /** |
318 * Called by a GrGpuResource when it removes its scratch key. | 316 * Called by a GrGpuResource when it removes its scratch key. |
319 */ | 317 */ |
320 void willRemoveScratchKey(const GrGpuResource* resource) { | 318 void willRemoveScratchKey(const GrGpuResource* resource) { |
321 fCache->willRemoveScratchKey(resource); | 319 fCache->willRemoveScratchKey(resource); |
322 } | 320 } |
323 | 321 |
324 /** | 322 /** |
325 * Called by GrGpuResources when they change from budgeted to unbudgeted or
vice versa. | 323 * Called by GrGpuResources when they change from budgeted to unbudgeted or
vice versa. |
326 */ | 324 */ |
327 void didChangeBudgetStatus(GrGpuResource* resource) { fCache->didChangeBudge
tStatus(resource); } | 325 void didChangeBudgetStatus(GrGpuResource* resource) { fCache->didChangeBudge
tStatus(resource); } |
328 | 326 |
329 // No taking addresses of this type. | 327 // No taking addresses of this type. |
330 const ResourceAccess* operator&() const; | 328 const ResourceAccess* operator&() const; |
331 ResourceAccess* operator&(); | 329 ResourceAccess* operator&(); |
332 | 330 |
333 GrResourceCache* fCache; | 331 GrResourceCache* fCache; |
334 | 332 |
335 friend class GrGpuResource; // To access all the proxy inline methods. | 333 friend class GrGpuResource; // To access all the proxy inline methods. |
336 friend class GrResourceCache; // To create this type. | 334 friend class GrResourceCache; // To create this type. |
337 }; | 335 }; |
338 | 336 |
339 inline GrResourceCache::ResourceAccess GrResourceCache::resourceAccess() { | 337 inline GrResourceCache::ResourceAccess GrResourceCache::resourceAccess() { |
340 return ResourceAccess(this); | 338 return ResourceAccess(this); |
341 } | 339 } |
342 | 340 |
343 #endif | 341 #endif |
OLD | NEW |