| 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 |