| 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 |
| 11 | 11 |
| 12 #include "GrGpuResource.h" | 12 #include "GrGpuResource.h" |
| 13 #include "GrGpuResourceCacheAccess.h" |
| 13 #include "GrGpuResourcePriv.h" | 14 #include "GrGpuResourcePriv.h" |
| 14 #include "GrResourceKey.h" | 15 #include "GrResourceKey.h" |
| 15 #include "SkMessageBus.h" | 16 #include "SkMessageBus.h" |
| 16 #include "SkRefCnt.h" | 17 #include "SkRefCnt.h" |
| 17 #include "SkTArray.h" | 18 #include "SkTArray.h" |
| 19 #include "SkTDPQueue.h" |
| 18 #include "SkTInternalLList.h" | 20 #include "SkTInternalLList.h" |
| 19 #include "SkTMultiMap.h" | 21 #include "SkTMultiMap.h" |
| 20 | 22 |
| 21 class SkString; | 23 class SkString; |
| 22 | 24 |
| 23 /** | 25 /** |
| 24 * Manages the lifetime of all GrGpuResource instances. | 26 * Manages the lifetime of all GrGpuResource instances. |
| 25 * | 27 * |
| 26 * Resources may have optionally have two types of keys: | 28 * Resources may have optionally have two types of keys: |
| 27 * 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. |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 return fScratchMap.countForKey(scratchKey); | 112 return fScratchMap.countForKey(scratchKey); |
| 111 } | 113 } |
| 112 #endif | 114 #endif |
| 113 | 115 |
| 114 /** | 116 /** |
| 115 * Find a resource that matches a content key. | 117 * Find a resource that matches a content key. |
| 116 */ | 118 */ |
| 117 GrGpuResource* findAndRefContentResource(const GrContentKey& contentKey) { | 119 GrGpuResource* findAndRefContentResource(const GrContentKey& contentKey) { |
| 118 GrGpuResource* resource = fContentHash.find(contentKey); | 120 GrGpuResource* resource = fContentHash.find(contentKey); |
| 119 if (resource) { | 121 if (resource) { |
| 120 resource->ref(); | 122 this->refAndMakeResourceMRU(resource); |
| 121 this->makeResourceMRU(resource); | |
| 122 } | 123 } |
| 123 return resource; | 124 return resource; |
| 124 } | 125 } |
| 125 | 126 |
| 126 /** | 127 /** |
| 127 * Query whether a content key exists in the cache. | 128 * Query whether a content key exists in the cache. |
| 128 */ | 129 */ |
| 129 bool hasContentKey(const GrContentKey& contentKey) const { | 130 bool hasContentKey(const GrContentKey& contentKey) const { |
| 130 return SkToBool(fContentHash.find(contentKey)); | 131 return SkToBool(fContentHash.find(contentKey)); |
| 131 } | 132 } |
| 132 | 133 |
| 133 /** Purges resources to become under budget and processes resources with inv
alidated content | 134 /** Purges resources to become under budget and processes resources with inv
alidated content |
| 134 keys. */ | 135 keys. */ |
| 135 void purgeAsNeeded() { | 136 void purgeAsNeeded() { |
| 136 SkTArray<GrContentKeyInvalidatedMessage> invalidKeyMsgs; | 137 SkTArray<GrContentKeyInvalidatedMessage> invalidKeyMsgs; |
| 137 fInvalidContentKeyInbox.poll(&invalidKeyMsgs); | 138 fInvalidContentKeyInbox.poll(&invalidKeyMsgs); |
| 138 if (invalidKeyMsgs.count()) { | 139 if (invalidKeyMsgs.count()) { |
| 139 this->processInvalidContentKeys(invalidKeyMsgs); | 140 this->processInvalidContentKeys(invalidKeyMsgs); |
| 140 } | 141 } |
| 141 if (fPurging || (fBudgetedCount <= fMaxCount && fBudgetedBytes <= fMaxBy
tes)) { | 142 if (fBudgetedCount <= fMaxCount && fBudgetedBytes <= fMaxBytes) { |
| 142 return; | 143 return; |
| 143 } | 144 } |
| 144 this->internalPurgeAsNeeded(); | 145 this->internalPurgeAsNeeded(); |
| 145 } | 146 } |
| 146 | 147 |
| 147 /** Purges all resources that don't have external owners. */ | 148 /** Purges all resources that don't have external owners. */ |
| 148 void purgeAllUnlocked(); | 149 void purgeAllUnlocked(); |
| 149 | 150 |
| 150 /** | 151 /** |
| 151 * The callback function used by the cache when it is still over budget afte
r a purge. The | 152 * The callback function used by the cache when it is still over budget afte
r a purge. The |
| (...skipping 20 matching lines...) Expand all Loading... |
| 172 /// @name Methods accessible via ResourceAccess | 173 /// @name Methods accessible via ResourceAccess |
| 173 //// | 174 //// |
| 174 void insertResource(GrGpuResource*); | 175 void insertResource(GrGpuResource*); |
| 175 void removeResource(GrGpuResource*); | 176 void removeResource(GrGpuResource*); |
| 176 void notifyPurgeable(GrGpuResource*); | 177 void notifyPurgeable(GrGpuResource*); |
| 177 void didChangeGpuMemorySize(const GrGpuResource*, size_t oldSize); | 178 void didChangeGpuMemorySize(const GrGpuResource*, size_t oldSize); |
| 178 bool didSetContentKey(GrGpuResource*); | 179 bool didSetContentKey(GrGpuResource*); |
| 179 void willRemoveScratchKey(const GrGpuResource*); | 180 void willRemoveScratchKey(const GrGpuResource*); |
| 180 void willRemoveContentKey(const GrGpuResource*); | 181 void willRemoveContentKey(const GrGpuResource*); |
| 181 void didChangeBudgetStatus(GrGpuResource*); | 182 void didChangeBudgetStatus(GrGpuResource*); |
| 182 void makeResourceMRU(GrGpuResource*); | 183 void refAndMakeResourceMRU(GrGpuResource*); |
| 183 /// @} | 184 /// @} |
| 184 | 185 |
| 185 void internalPurgeAsNeeded(); | 186 void internalPurgeAsNeeded(); |
| 186 void processInvalidContentKeys(const SkTArray<GrContentKeyInvalidatedMessage
>&); | 187 void processInvalidContentKeys(const SkTArray<GrContentKeyInvalidatedMessage
>&); |
| 187 | 188 |
| 188 #ifdef SK_DEBUG | 189 #ifdef SK_DEBUG |
| 189 bool isInCache(const GrGpuResource* r) const { return fResources.isInList(r)
; } | 190 bool isInCache(const GrGpuResource* r) const { return fResources.isInList(r)
; } |
| 190 void validate() const; | 191 void validate() const; |
| 191 #else | 192 #else |
| 192 void validate() const {} | 193 void validate() const {} |
| (...skipping 16 matching lines...) Expand all Loading... |
| 209 static const GrContentKey& GetKey(const GrGpuResource& r) { | 210 static const GrContentKey& GetKey(const GrGpuResource& r) { |
| 210 return r.getContentKey(); | 211 return r.getContentKey(); |
| 211 } | 212 } |
| 212 | 213 |
| 213 static uint32_t Hash(const GrContentKey& key) { return key.hash(); } | 214 static uint32_t Hash(const GrContentKey& key) { return key.hash(); } |
| 214 }; | 215 }; |
| 215 typedef SkTDynamicHash<GrGpuResource, GrContentKey, ContentHashTraits> Conte
ntHash; | 216 typedef SkTDynamicHash<GrGpuResource, GrContentKey, ContentHashTraits> Conte
ntHash; |
| 216 | 217 |
| 217 typedef SkTInternalLList<GrGpuResource> ResourceList; | 218 typedef SkTInternalLList<GrGpuResource> ResourceList; |
| 218 | 219 |
| 220 static bool CompareTimestamp(GrGpuResource* const& a, GrGpuResource* const&
b) { |
| 221 return a->cacheAccess().timestamp() < b->cacheAccess().timestamp(); |
| 222 } |
| 223 |
| 224 static int* AccessResourceIndex(GrGpuResource* const& res) { |
| 225 return res->cacheAccess().accessCacheIndex(); |
| 226 } |
| 227 |
| 219 typedef SkMessageBus<GrContentKeyInvalidatedMessage>::Inbox InvalidContentKe
yInbox; | 228 typedef SkMessageBus<GrContentKeyInvalidatedMessage>::Inbox InvalidContentKe
yInbox; |
| 229 typedef SkTDPQueue<GrGpuResource*, CompareTimestamp, AccessResourceIndex> Pu
rgeableQueue; |
| 220 | 230 |
| 231 // Whenever a resource is added to the cache or the result of a cache lookup
, fTimestamp is |
| 232 // assigned as the resource's timestamp and then incremented. fPurgeableQueu
e orders the |
| 233 // purgeable resources by this value, and thus is used to purge resources in
LRU order. |
| 234 uint32_t fTimestamp; |
| 235 PurgeableQueue fPurgeableQueue; |
| 236 |
| 237 // TODO: Replace this with an array of nonpurgeable resources |
| 221 ResourceList fResources; | 238 ResourceList fResources; |
| 239 |
| 222 // This map holds all resources that can be used as scratch resources. | 240 // This map holds all resources that can be used as scratch resources. |
| 223 ScratchMap fScratchMap; | 241 ScratchMap fScratchMap; |
| 224 // This holds all resources that have content keys. | 242 // This holds all resources that have content keys. |
| 225 ContentHash fContentHash; | 243 ContentHash fContentHash; |
| 226 | 244 |
| 227 // our budget, used in purgeAsNeeded() | 245 // our budget, used in purgeAsNeeded() |
| 228 int fMaxCount; | 246 int fMaxCount; |
| 229 size_t fMaxBytes; | 247 size_t fMaxBytes; |
| 230 | 248 |
| 231 #if GR_CACHE_STATS | 249 #if GR_CACHE_STATS |
| 232 int fHighWaterCount; | 250 int fHighWaterCount; |
| 233 size_t fHighWaterBytes; | 251 size_t fHighWaterBytes; |
| 234 int fBudgetedHighWaterCount; | 252 int fBudgetedHighWaterCount; |
| 235 size_t fBudgetedHighWaterBytes; | 253 size_t fBudgetedHighWaterBytes; |
| 236 #endif | 254 #endif |
| 237 | 255 |
| 238 // our current stats for all resources | 256 // our current stats for all resources |
| 239 int fCount; | 257 int fCount; |
| 240 size_t fBytes; | 258 size_t fBytes; |
| 241 | 259 |
| 242 // our current stats for resources that count against the budget | 260 // our current stats for resources that count against the budget |
| 243 int fBudgetedCount; | 261 int fBudgetedCount; |
| 244 size_t fBudgetedBytes; | 262 size_t fBudgetedBytes; |
| 245 | 263 |
| 246 // prevents recursive purging | |
| 247 bool fPurging; | |
| 248 bool fNewlyPurgeableResourceWhilePurging; | |
| 249 | |
| 250 PFOverBudgetCB fOverBudgetCB; | 264 PFOverBudgetCB fOverBudgetCB; |
| 251 void* fOverBudgetData; | 265 void* fOverBudgetData; |
| 252 | 266 |
| 253 InvalidContentKeyInbox fInvalidContentKeyInbox; | 267 InvalidContentKeyInbox fInvalidContentKeyInbox; |
| 254 | |
| 255 }; | 268 }; |
| 256 | 269 |
| 257 class GrResourceCache::ResourceAccess { | 270 class GrResourceCache::ResourceAccess { |
| 258 private: | 271 private: |
| 259 ResourceAccess(GrResourceCache* cache) : fCache(cache) { } | 272 ResourceAccess(GrResourceCache* cache) : fCache(cache) { } |
| 260 ResourceAccess(const ResourceAccess& that) : fCache(that.fCache) { } | 273 ResourceAccess(const ResourceAccess& that) : fCache(that.fCache) { } |
| 261 ResourceAccess& operator=(const ResourceAccess&); // unimpl | 274 ResourceAccess& operator=(const ResourceAccess&); // unimpl |
| 262 | 275 |
| 263 /** | 276 /** |
| 264 * Insert a resource into the cache. | 277 * Insert a resource into the cache. |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 | 332 |
| 320 friend class GrGpuResource; // To access all the proxy inline methods. | 333 friend class GrGpuResource; // To access all the proxy inline methods. |
| 321 friend class GrResourceCache; // To create this type. | 334 friend class GrResourceCache; // To create this type. |
| 322 }; | 335 }; |
| 323 | 336 |
| 324 inline GrResourceCache::ResourceAccess GrResourceCache::resourceAccess() { | 337 inline GrResourceCache::ResourceAccess GrResourceCache::resourceAccess() { |
| 325 return ResourceAccess(this); | 338 return ResourceAccess(this); |
| 326 } | 339 } |
| 327 | 340 |
| 328 #endif | 341 #endif |
| OLD | NEW |