OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 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 | 9 |
10 | 10 |
11 #ifndef GrResourceCache_DEFINED | 11 #ifndef GrResourceCache_DEFINED |
12 #define GrResourceCache_DEFINED | 12 #define GrResourceCache_DEFINED |
13 | 13 |
14 #include "GrConfig.h" | 14 #include "GrConfig.h" |
15 #include "GrTypes.h" | 15 #include "GrTypes.h" |
16 #include "GrTMultiMap.h" | 16 #include "GrTMultiMap.h" |
17 #include "GrBinHashKey.h" | 17 #include "GrBinHashKey.h" |
18 #include "SkMessageBus.h" | 18 #include "SkMessageBus.h" |
19 #include "SkTInternalLList.h" | 19 #include "SkTInternalLList.h" |
20 | 20 |
21 class GrResource; | 21 class GrCacheable; |
22 class GrResourceEntry; | 22 class GrResourceCacheEntry; |
23 | 23 |
24 class GrResourceKey { | 24 class GrResourceKey { |
25 public: | 25 public: |
26 static GrCacheID::Domain ScratchDomain() { | 26 static GrCacheID::Domain ScratchDomain() { |
27 static const GrCacheID::Domain gDomain = GrCacheID::GenerateDomain(); | 27 static const GrCacheID::Domain gDomain = GrCacheID::GenerateDomain(); |
28 return gDomain; | 28 return gDomain; |
29 } | 29 } |
30 | 30 |
31 /** Uniquely identifies the GrResource subclass in the key to avoid collisio
ns | 31 /** Uniquely identifies the GrCacheable subclass in the key to avoid collisi
ons |
32 across resource types. */ | 32 across resource types. */ |
33 typedef uint8_t ResourceType; | 33 typedef uint8_t ResourceType; |
34 | 34 |
35 /** Flags set by the GrResource subclass. */ | 35 /** Flags set by the GrCacheable subclass. */ |
36 typedef uint8_t ResourceFlags; | 36 typedef uint8_t ResourceFlags; |
37 | 37 |
38 /** Generate a unique ResourceType */ | 38 /** Generate a unique ResourceType */ |
39 static ResourceType GenerateResourceType(); | 39 static ResourceType GenerateResourceType(); |
40 | 40 |
41 /** Creates a key for resource */ | 41 /** Creates a key for resource */ |
42 GrResourceKey(const GrCacheID& id, ResourceType type, ResourceFlags flags) { | 42 GrResourceKey(const GrCacheID& id, ResourceType type, ResourceFlags flags) { |
43 this->init(id.getDomain(), id.getKey(), type, flags); | 43 this->init(id.getDomain(), id.getKey(), type, flags); |
44 }; | 44 }; |
45 | 45 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 GrBinHashKey<kKeySize> fKey; | 108 GrBinHashKey<kKeySize> fKey; |
109 }; | 109 }; |
110 | 110 |
111 // The cache listens for these messages to purge junk resources proactively. | 111 // The cache listens for these messages to purge junk resources proactively. |
112 struct GrResourceInvalidatedMessage { | 112 struct GrResourceInvalidatedMessage { |
113 GrResourceKey key; | 113 GrResourceKey key; |
114 }; | 114 }; |
115 | 115 |
116 /////////////////////////////////////////////////////////////////////////////// | 116 /////////////////////////////////////////////////////////////////////////////// |
117 | 117 |
118 class GrResourceEntry { | 118 class GrResourceCacheEntry { |
119 public: | 119 public: |
120 GrResource* resource() const { return fResource; } | 120 GrCacheable* resource() const { return fResource; } |
121 const GrResourceKey& key() const { return fKey; } | 121 const GrResourceKey& key() const { return fKey; } |
122 | 122 |
123 static const GrResourceKey& GetKey(const GrResourceEntry& e) { return e.key(
); } | 123 static const GrResourceKey& GetKey(const GrResourceCacheEntry& e) { return e
.key(); } |
124 static uint32_t Hash(const GrResourceKey& key) { return key.getHash(); } | 124 static uint32_t Hash(const GrResourceKey& key) { return key.getHash(); } |
125 #ifdef SK_DEBUG | 125 #ifdef SK_DEBUG |
126 void validate() const; | 126 void validate() const; |
127 #else | 127 #else |
128 void validate() const {} | 128 void validate() const {} |
129 #endif | 129 #endif |
130 | 130 |
131 private: | 131 private: |
132 GrResourceEntry(const GrResourceKey& key, GrResource* resource); | 132 GrResourceCacheEntry(const GrResourceKey& key, GrCacheable* resource); |
133 ~GrResourceEntry(); | 133 ~GrResourceCacheEntry(); |
134 | 134 |
135 GrResourceKey fKey; | 135 GrResourceKey fKey; |
136 GrResource* fResource; | 136 GrCacheable* fResource; |
137 | 137 |
138 // Linked list for the LRU ordering. | 138 // Linked list for the LRU ordering. |
139 SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrResourceEntry); | 139 SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrResourceCacheEntry); |
140 | 140 |
141 friend class GrResourceCache; | 141 friend class GrResourceCache; |
142 }; | 142 }; |
143 | 143 |
144 /////////////////////////////////////////////////////////////////////////////// | 144 /////////////////////////////////////////////////////////////////////////////// |
145 | 145 |
146 /** | 146 /** |
147 * Cache of GrResource objects. | 147 * Cache of GrCacheable objects. |
148 * | 148 * |
149 * These have a corresponding GrResourceKey, built from 128bits identifying the | 149 * These have a corresponding GrResourceKey, built from 128bits identifying the |
150 * resource. Multiple resources can map to same GrResourceKey. | 150 * resource. Multiple resources can map to same GrResourceKey. |
151 * | 151 * |
152 * The cache stores the entries in a double-linked list, which is its LRU. | 152 * The cache stores the entries in a double-linked list, which is its LRU. |
153 * When an entry is "locked" (i.e. given to the caller), it is moved to the | 153 * When an entry is "locked" (i.e. given to the caller), it is moved to the |
154 * head of the list. If/when we must purge some of the entries, we walk the | 154 * head of the list. If/when we must purge some of the entries, we walk the |
155 * list backwards from the tail, since those are the least recently used. | 155 * list backwards from the tail, since those are the least recently used. |
156 * | 156 * |
157 * For fast searches, we maintain a hash map based on the GrResourceKey. | 157 * For fast searches, we maintain a hash map based on the GrResourceKey. |
158 * | 158 * |
159 * It is a goal to make the GrResourceCache the central repository and bookkeep
er | 159 * It is a goal to make the GrResourceCache the central repository and bookkeep
er |
160 * of all resources. It should replace the linked list of GrResources that | 160 * of all resources. It should replace the linked list of GrGpuObjects that |
161 * GrGpu uses to call abandon/release. | 161 * GrGpu uses to call abandon/release. |
162 */ | 162 */ |
163 class GrResourceCache { | 163 class GrResourceCache { |
164 public: | 164 public: |
165 GrResourceCache(int maxCount, size_t maxBytes); | 165 GrResourceCache(int maxCount, size_t maxBytes); |
166 ~GrResourceCache(); | 166 ~GrResourceCache(); |
167 | 167 |
168 /** | 168 /** |
169 * Return the current resource cache limits. | 169 * Return the current resource cache limits. |
170 * | 170 * |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 * Search for an entry with the same Key. If found, return it. | 226 * Search for an entry with the same Key. If found, return it. |
227 * If not found, return null. | 227 * If not found, return null. |
228 * If ownershipFlags includes kNoOtherOwners and a resource is returned | 228 * If ownershipFlags includes kNoOtherOwners and a resource is returned |
229 * then that resource has no other refs to it. | 229 * then that resource has no other refs to it. |
230 * If ownershipFlags includes kHide and a resource is returned then that | 230 * If ownershipFlags includes kHide and a resource is returned then that |
231 * resource will not be returned from future 'find' calls until it is | 231 * resource will not be returned from future 'find' calls until it is |
232 * 'freed' (and recycled) or makeNonExclusive is called. | 232 * 'freed' (and recycled) or makeNonExclusive is called. |
233 * For a resource to be completely exclusive to a caller both kNoOtherOwner
s | 233 * For a resource to be completely exclusive to a caller both kNoOtherOwner
s |
234 * and kHide must be specified. | 234 * and kHide must be specified. |
235 */ | 235 */ |
236 GrResource* find(const GrResourceKey& key, | 236 GrCacheable* find(const GrResourceKey& key, |
237 uint32_t ownershipFlags = 0); | 237 uint32_t ownershipFlags = 0); |
238 | 238 |
239 /** | 239 /** |
240 * Add the new resource to the cache (by creating a new cache entry based | 240 * Add the new resource to the cache (by creating a new cache entry based |
241 * on the provided key and resource). | 241 * on the provided key and resource). |
242 * | 242 * |
243 * Ownership of the resource is transferred to the resource cache, | 243 * Ownership of the resource is transferred to the resource cache, |
244 * which will unref() it when it is purged or deleted. | 244 * which will unref() it when it is purged or deleted. |
245 * | 245 * |
246 * If ownershipFlags includes kHide, subsequent calls to 'find' will not | 246 * If ownershipFlags includes kHide, subsequent calls to 'find' will not |
247 * return 'resource' until it is 'freed' (and recycled) or makeNonExclusive | 247 * return 'resource' until it is 'freed' (and recycled) or makeNonExclusive |
248 * is called. | 248 * is called. |
249 */ | 249 */ |
250 void addResource(const GrResourceKey& key, | 250 void addResource(const GrResourceKey& key, |
251 GrResource* resource, | 251 GrCacheable* resource, |
252 uint32_t ownershipFlags = 0); | 252 uint32_t ownershipFlags = 0); |
253 | 253 |
254 /** | 254 /** |
255 * Determines if the cache contains an entry matching a key. If a matching | 255 * Determines if the cache contains an entry matching a key. If a matching |
256 * entry exists but was detached then it will not be found. | 256 * entry exists but was detached then it will not be found. |
257 */ | 257 */ |
258 bool hasKey(const GrResourceKey& key) const { return NULL != fCache.find(key
); } | 258 bool hasKey(const GrResourceKey& key) const { return NULL != fCache.find(key
); } |
259 | 259 |
260 /** | 260 /** |
261 * Hide 'entry' so that future searches will not find it. Such | 261 * Hide 'entry' so that future searches will not find it. Such |
262 * hidden entries will not be purged. The entry still counts against | 262 * hidden entries will not be purged. The entry still counts against |
263 * the cache's budget and should be made non-exclusive when exclusive access | 263 * the cache's budget and should be made non-exclusive when exclusive access |
264 * is no longer needed. | 264 * is no longer needed. |
265 */ | 265 */ |
266 void makeExclusive(GrResourceEntry* entry); | 266 void makeExclusive(GrResourceCacheEntry* entry); |
267 | 267 |
268 /** | 268 /** |
269 * Restore 'entry' so that it can be found by future searches. 'entry' | 269 * Restore 'entry' so that it can be found by future searches. 'entry' |
270 * will also be purgeable (provided its lock count is now 0.) | 270 * will also be purgeable (provided its lock count is now 0.) |
271 */ | 271 */ |
272 void makeNonExclusive(GrResourceEntry* entry); | 272 void makeNonExclusive(GrResourceCacheEntry* entry); |
273 | 273 |
274 /** | 274 /** |
275 * Remove a resource from the cache and delete it! | 275 * Remove a resource from the cache and delete it! |
276 */ | 276 */ |
277 void deleteResource(GrResourceEntry* entry); | 277 void deleteResource(GrResourceCacheEntry* entry); |
278 | 278 |
279 /** | 279 /** |
280 * Removes every resource in the cache that isn't locked. | 280 * Removes every resource in the cache that isn't locked. |
281 */ | 281 */ |
282 void purgeAllUnlocked(); | 282 void purgeAllUnlocked(); |
283 | 283 |
284 /** | 284 /** |
285 * Allow cache to purge unused resources to obey resource limitations | 285 * Allow cache to purge unused resources to obey resource limitations |
286 * Note: this entry point will be hidden (again) once totally ref-driven | 286 * Note: this entry point will be hidden (again) once totally ref-driven |
287 * cache maintenance is implemented. Note that the overbudget callback | 287 * cache maintenance is implemented. Note that the overbudget callback |
(...skipping 15 matching lines...) Expand all Loading... |
303 #if GR_CACHE_STATS | 303 #if GR_CACHE_STATS |
304 void printStats(); | 304 void printStats(); |
305 #endif | 305 #endif |
306 | 306 |
307 private: | 307 private: |
308 enum BudgetBehaviors { | 308 enum BudgetBehaviors { |
309 kAccountFor_BudgetBehavior, | 309 kAccountFor_BudgetBehavior, |
310 kIgnore_BudgetBehavior | 310 kIgnore_BudgetBehavior |
311 }; | 311 }; |
312 | 312 |
313 void internalDetach(GrResourceEntry*, BudgetBehaviors behavior = kAccountFor
_BudgetBehavior); | 313 void internalDetach(GrResourceCacheEntry*, BudgetBehaviors behavior = kAccou
ntFor_BudgetBehavior); |
314 void attachToHead(GrResourceEntry*, BudgetBehaviors behavior = kAccountFor_B
udgetBehavior); | 314 void attachToHead(GrResourceCacheEntry*, BudgetBehaviors behavior = kAccount
For_BudgetBehavior); |
315 | 315 |
316 void removeInvalidResource(GrResourceEntry* entry); | 316 void removeInvalidResource(GrResourceCacheEntry* entry); |
317 | 317 |
318 GrTMultiMap<GrResourceEntry, GrResourceKey> fCache; | 318 GrTMultiMap<GrResourceCacheEntry, GrResourceKey> fCache; |
319 | 319 |
320 // We're an internal doubly linked list | 320 // We're an internal doubly linked list |
321 typedef SkTInternalLList<GrResourceEntry> EntryList; | 321 typedef SkTInternalLList<GrResourceCacheEntry> EntryList; |
322 EntryList fList; | 322 EntryList fList; |
323 | 323 |
324 #ifdef SK_DEBUG | 324 #ifdef SK_DEBUG |
325 // These objects cannot be returned by a search | 325 // These objects cannot be returned by a search |
326 EntryList fExclusiveList; | 326 EntryList fExclusiveList; |
327 #endif | 327 #endif |
328 | 328 |
329 // our budget, used in purgeAsNeeded() | 329 // our budget, used in purgeAsNeeded() |
330 int fMaxCount; | 330 int fMaxCount; |
331 size_t fMaxBytes; | 331 size_t fMaxBytes; |
(...skipping 17 matching lines...) Expand all Loading... |
349 PFOverbudgetCB fOverbudgetCB; | 349 PFOverbudgetCB fOverbudgetCB; |
350 void* fOverbudgetData; | 350 void* fOverbudgetData; |
351 | 351 |
352 void internalPurge(int extraCount, size_t extraBytes); | 352 void internalPurge(int extraCount, size_t extraBytes); |
353 | 353 |
354 // Listen for messages that a resource has been invalidated and purge cached
junk proactively. | 354 // Listen for messages that a resource has been invalidated and purge cached
junk proactively. |
355 SkMessageBus<GrResourceInvalidatedMessage>::Inbox fInvalidationInbox; | 355 SkMessageBus<GrResourceInvalidatedMessage>::Inbox fInvalidationInbox; |
356 void purgeInvalidated(); | 356 void purgeInvalidated(); |
357 | 357 |
358 #ifdef SK_DEBUG | 358 #ifdef SK_DEBUG |
359 static size_t countBytes(const SkTInternalLList<GrResourceEntry>& list); | 359 static size_t countBytes(const SkTInternalLList<GrResourceCacheEntry>& list)
; |
360 #endif | 360 #endif |
361 }; | 361 }; |
362 | 362 |
363 /////////////////////////////////////////////////////////////////////////////// | 363 /////////////////////////////////////////////////////////////////////////////// |
364 | 364 |
365 #ifdef SK_DEBUG | 365 #ifdef SK_DEBUG |
366 class GrAutoResourceCacheValidate { | 366 class GrAutoResourceCacheValidate { |
367 public: | 367 public: |
368 GrAutoResourceCacheValidate(GrResourceCache* cache) : fCache(cache) { | 368 GrAutoResourceCacheValidate(GrResourceCache* cache) : fCache(cache) { |
369 cache->validate(); | 369 cache->validate(); |
370 } | 370 } |
371 ~GrAutoResourceCacheValidate() { | 371 ~GrAutoResourceCacheValidate() { |
372 fCache->validate(); | 372 fCache->validate(); |
373 } | 373 } |
374 private: | 374 private: |
375 GrResourceCache* fCache; | 375 GrResourceCache* fCache; |
376 }; | 376 }; |
377 #else | 377 #else |
378 class GrAutoResourceCacheValidate { | 378 class GrAutoResourceCacheValidate { |
379 public: | 379 public: |
380 GrAutoResourceCacheValidate(GrResourceCache*) {} | 380 GrAutoResourceCacheValidate(GrResourceCache*) {} |
381 }; | 381 }; |
382 #endif | 382 #endif |
383 | 383 |
384 #endif | 384 #endif |
OLD | NEW |