Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/gpu/GrResourceCache.h

Issue 2321563006: Make GrResourceCache dynamically change between LRU and random replacement strategies. (Closed)
Patch Set: fix recursive flusing, add asserts Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/GrDrawingManager.cpp ('k') | src/gpu/GrResourceCache.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 GrResourceCache_DEFINED 8 #ifndef GrResourceCache_DEFINED
9 #define GrResourceCache_DEFINED 9 #define GrResourceCache_DEFINED
10 10
11 #include "GrGpuResource.h" 11 #include "GrGpuResource.h"
12 #include "GrGpuResourceCacheAccess.h" 12 #include "GrGpuResourceCacheAccess.h"
13 #include "GrGpuResourcePriv.h" 13 #include "GrGpuResourcePriv.h"
14 #include "GrResourceCache.h" 14 #include "GrResourceCache.h"
15 #include "GrResourceKey.h" 15 #include "GrResourceKey.h"
16 #include "SkChunkAlloc.h"
16 #include "SkMessageBus.h" 17 #include "SkMessageBus.h"
18 #include "SkRandom.h"
17 #include "SkRefCnt.h" 19 #include "SkRefCnt.h"
18 #include "SkTArray.h" 20 #include "SkTArray.h"
19 #include "SkTDPQueue.h" 21 #include "SkTDPQueue.h"
20 #include "SkTInternalLList.h" 22 #include "SkTInternalLList.h"
21 #include "SkTMultiMap.h" 23 #include "SkTMultiMap.h"
22 24
23 class GrCaps; 25 class GrCaps;
24 class SkString; 26 class SkString;
25 class SkTraceMemoryDump; 27 class SkTraceMemoryDump;
26 28
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 #ifdef SK_DEBUG 132 #ifdef SK_DEBUG
131 // This is not particularly fast and only used for validation, so debug only . 133 // This is not particularly fast and only used for validation, so debug only .
132 int countScratchEntriesForKey(const GrScratchKey& scratchKey) const { 134 int countScratchEntriesForKey(const GrScratchKey& scratchKey) const {
133 return fScratchMap.countForKey(scratchKey); 135 return fScratchMap.countForKey(scratchKey);
134 } 136 }
135 #endif 137 #endif
136 138
137 /** 139 /**
138 * Find a resource that matches a unique key. 140 * Find a resource that matches a unique key.
139 */ 141 */
140 GrGpuResource* findAndRefUniqueResource(const GrUniqueKey& key) { 142 GrGpuResource* findAndRefUniqueResource(const GrUniqueKey& key);
141 GrGpuResource* resource = fUniqueHash.find(key);
142 if (resource) {
143 this->refAndMakeResourceMRU(resource);
144 }
145 return resource;
146 }
147 143
148 /** 144 /**
149 * Query whether a unique key exists in the cache. 145 * Query whether a unique key exists in the cache.
150 */ 146 */
151 bool hasUniqueKey(const GrUniqueKey& key) const { 147 bool hasUniqueKey(const GrUniqueKey& key) const {
152 return SkToBool(fUniqueHash.find(key)); 148 return SkToBool(fUniqueHash.find(key));
153 } 149 }
154 150
155 /** Purges resources to become under budget and processes resources with inv alidated unique 151 /** Purges resources to become under budget and processes resources with inv alidated unique
156 keys. */ 152 keys. */
157 void purgeAsNeeded(); 153 void purgeAsNeeded() { this->internalPurgeAsNeeded(false); }
158 154
159 /** Purges all resources that don't have external owners. */ 155 /** Purges all resources that don't have external owners. */
160 void purgeAllUnlocked(); 156 void purgeAllUnlocked();
161 157
162 /** Returns true if the cache would like a flush to occur in order to make m ore resources 158 /** Returns true if the cache would like a flush to occur in order to make m ore resources
163 purgeable. */ 159 purgeable. */
164 bool requestsFlush() const { return fRequestFlush; } 160 bool requestsFlush() const {
161 // When in random replacement mode we request a flush in order to make a s many resources
162 // as possible subject to replacement.
163 return this->overBudget() && (ReplacementStrategy::kRandom == fStrategy ||
164 0 == fPurgeableQueue.count());
165 }
165 166
166 enum FlushType { 167 enum FlushType {
167 kExternal, 168 kExternal,
168 kImmediateMode, 169 kImmediateMode,
169 kCacheRequested, 170 kCacheRequested,
170 }; 171 };
171 void notifyFlushOccurred(FlushType); 172 void notifyFlushOccurred(FlushType);
172 173
173 #if GR_CACHE_STATS 174 #if GR_CACHE_STATS
174 struct Stats { 175 struct Stats {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 void removeResource(GrGpuResource*); 226 void removeResource(GrGpuResource*);
226 void notifyCntReachedZero(GrGpuResource*, uint32_t flags); 227 void notifyCntReachedZero(GrGpuResource*, uint32_t flags);
227 void didChangeGpuMemorySize(const GrGpuResource*, size_t oldSize); 228 void didChangeGpuMemorySize(const GrGpuResource*, size_t oldSize);
228 void changeUniqueKey(GrGpuResource*, const GrUniqueKey&); 229 void changeUniqueKey(GrGpuResource*, const GrUniqueKey&);
229 void removeUniqueKey(GrGpuResource*); 230 void removeUniqueKey(GrGpuResource*);
230 void willRemoveScratchKey(const GrGpuResource*); 231 void willRemoveScratchKey(const GrGpuResource*);
231 void didChangeBudgetStatus(GrGpuResource*); 232 void didChangeBudgetStatus(GrGpuResource*);
232 void refAndMakeResourceMRU(GrGpuResource*); 233 void refAndMakeResourceMRU(GrGpuResource*);
233 /// @} 234 /// @}
234 235
236 void internalPurgeAsNeeded(bool fromFlushNotification);
235 void processInvalidUniqueKeys(const SkTArray<GrUniqueKeyInvalidatedMessage>& ); 237 void processInvalidUniqueKeys(const SkTArray<GrUniqueKeyInvalidatedMessage>& );
236 void addToNonpurgeableArray(GrGpuResource*); 238 void addToNonpurgeableArray(GrGpuResource*);
237 void removeFromNonpurgeableArray(GrGpuResource*); 239 void removeFromNonpurgeableArray(GrGpuResource*);
238 bool overBudget() const { return fBudgetedBytes > fMaxBytes || fBudgetedCoun t > fMaxCount; } 240 bool overBudget() const { return fBudgetedBytes > fMaxBytes || fBudgetedCoun t > fMaxCount; }
241 GrGpuResource* selectResourceUsingStrategy();
242 void recordPurgedKey(GrGpuResource*);
243 void recordKeyMiss(const GrUniqueKey&);
239 244
240 bool wouldFit(size_t bytes) { 245 bool wouldFit(size_t bytes) {
241 return fBudgetedBytes+bytes <= fMaxBytes && fBudgetedCount+1 <= fMaxCoun t; 246 return fBudgetedBytes+bytes <= fMaxBytes && fBudgetedCount+1 <= fMaxCoun t;
242 } 247 }
243 248
244 uint32_t getNextTimestamp(); 249 uint32_t getNextTimestamp();
245 250
246 #ifdef SK_DEBUG 251 #ifdef SK_DEBUG
247 bool isInCache(const GrGpuResource* r) const; 252 bool isInCache(const GrGpuResource* r) const;
248 void validate() const; 253 void validate() const;
249 #else 254 #else
250 void validate() const {} 255 void validate() const {}
251 #endif 256 #endif
252 257
253 class AutoValidate; 258 class AutoValidate;
254 259
255 class AvailableForScratchUse; 260 class AvailableForScratchUse;
256 261
257 struct ScratchMapTraits { 262 struct HashTraitsBase {
263 static uint32_t Hash(const GrResourceKey& key) { return key.hash(); }
264 };
265
266 struct ScratchMapTraits : public HashTraitsBase {
258 static const GrScratchKey& GetKey(const GrGpuResource& r) { 267 static const GrScratchKey& GetKey(const GrGpuResource& r) {
259 return r.resourcePriv().getScratchKey(); 268 return r.resourcePriv().getScratchKey();
260 } 269 }
261
262 static uint32_t Hash(const GrScratchKey& key) { return key.hash(); }
263 }; 270 };
264 typedef SkTMultiMap<GrGpuResource, GrScratchKey, ScratchMapTraits> ScratchMa p; 271 typedef SkTMultiMap<GrGpuResource, GrScratchKey, ScratchMapTraits> ScratchMa p;
265 272
266 struct UniqueHashTraits { 273 struct UniqueHashTraits : public HashTraitsBase {
267 static const GrUniqueKey& GetKey(const GrGpuResource& r) { return r.getU niqueKey(); } 274 static const GrUniqueKey& GetKey(const GrGpuResource& r) { return r.getU niqueKey(); }
268
269 static uint32_t Hash(const GrUniqueKey& key) { return key.hash(); }
270 }; 275 };
271 typedef SkTDynamicHash<GrGpuResource, GrUniqueKey, UniqueHashTraits> UniqueH ash; 276 typedef SkTDynamicHash<GrGpuResource, GrUniqueKey, UniqueHashTraits> UniqueH ash;
272 277
278 struct UniqueSetTraits : public HashTraitsBase {
279 static const GrUniqueKey& GetKey(const GrUniqueKey& key) { return key; }
280 };
281 typedef SkTDynamicHash<GrUniqueKey, GrUniqueKey, UniqueSetTraits> UniqueKeyS et;
282
273 static bool CompareTimestamp(GrGpuResource* const& a, GrGpuResource* const& b) { 283 static bool CompareTimestamp(GrGpuResource* const& a, GrGpuResource* const& b) {
274 return a->cacheAccess().timestamp() < b->cacheAccess().timestamp(); 284 return a->cacheAccess().timestamp() < b->cacheAccess().timestamp();
275 } 285 }
276 286
277 static int* AccessResourceIndex(GrGpuResource* const& res) { 287 static int* AccessResourceIndex(GrGpuResource* const& res) {
278 return res->cacheAccess().accessCacheIndex(); 288 return res->cacheAccess().accessCacheIndex();
279 } 289 }
280 290
291 /**
292 * The resource cache chooses one of these replacement strategies based on a "strategy score"
293 * updated after each external flush based on unique key cache misses.
294 */
295 enum class ReplacementStrategy {
296 kLRU,
297 kRandom
298 };
299 /**
300 * When the current strategy score is >=0 LRU is chosen, when it is < 0 rand om is chosen. The
301 * absolute value of the score moves by 1 each flush.
302 */
303 static constexpr int kStrategyScoreMin = -5;
304 static constexpr int kStrategyScoreMax = 4;
305 static constexpr int kInitialStrategyScore = 2;
306
281 typedef SkMessageBus<GrUniqueKeyInvalidatedMessage>::Inbox InvalidUniqueKeyI nbox; 307 typedef SkMessageBus<GrUniqueKeyInvalidatedMessage>::Inbox InvalidUniqueKeyI nbox;
282 typedef SkTDPQueue<GrGpuResource*, CompareTimestamp, AccessResourceIndex> Pu rgeableQueue; 308 typedef SkTDPQueue<GrGpuResource*, CompareTimestamp, AccessResourceIndex> Pu rgeableQueue;
283 typedef SkTDArray<GrGpuResource*> ResourceArray; 309 typedef SkTDArray<GrGpuResource*> ResourceArray;
284 310
285 // Whenever a resource is added to the cache or the result of a cache lookup , fTimestamp is 311 // Whenever a resource is added to the cache or the result of a cache lookup , fTimestamp is
286 // assigned as the resource's timestamp and then incremented. fPurgeableQueu e orders the 312 // assigned as the resource's timestamp and then incremented. fPurgeableQueu e orders the
287 // purgeable resources by this value, and thus is used to purge resources in LRU order. 313 // purgeable resources by this value, and thus is used to purge resources in LRU order.
288 uint32_t fTimestamp; 314 uint32_t fTimestamp;
289 PurgeableQueue fPurgeableQueue; 315 PurgeableQueue fPurgeableQueue;
290 ResourceArray fNonpurgeableResources; 316 ResourceArray fNonpurgeableResources;
291 317
292 // This map holds all resources that can be used as scratch resources. 318 // This map holds all resources that can be used as scratch resources.
293 ScratchMap fScratchMap; 319 ScratchMap fScratchMap;
294 // This holds all resources that have unique keys. 320 // This holds all resources that have unique keys.
295 UniqueHash fUniqueHash; 321 UniqueHash fUniqueHash;
296 322
297 // our budget, used in purgeAsNeeded() 323 // our budget, used in purgeAsNeeded()
298 int fMaxCount; 324 int fMaxCount;
299 size_t fMaxBytes; 325 size_t fMaxBytes;
300 int fMaxUnusedFlushes; 326 int fMaxUnusedFlushes;
301 327
328 // Data related to replacement strategy.
329 SkRandom fRandom;
330 ReplacementStrategy fStrategy;
331 int fStrategyScore;
332 int fTotalMissesThisFlush;
333 int fMissesThisFlushPurgedRecently;
334 UniqueKeySet fUniqueKeysPurgedThisFlush[2];
335 // These are pointers to SkChunckAlloc because of gcc bug 63707
336 SkChunkAlloc* fUniqueKeysPurgedThisFlushStorage[2];
337 int fFlushParity;
338
302 #if GR_CACHE_STATS 339 #if GR_CACHE_STATS
303 int fHighWaterCount; 340 int fHighWaterCount;
304 size_t fHighWaterBytes; 341 size_t fHighWaterBytes;
305 int fBudgetedHighWaterCount; 342 int fBudgetedHighWaterCount;
306 size_t fBudgetedHighWaterBytes; 343 size_t fBudgetedHighWaterBytes;
307 #endif 344 #endif
308 345
309 // our current stats for all resources 346 // our current stats for all resources
310 SkDEBUGCODE(int fCount;) 347 SkDEBUGCODE(int fCount;)
311 size_t fBytes; 348 size_t fBytes;
312 349
313 // our current stats for resources that count against the budget 350 // our current stats for resources that count against the budget
314 int fBudgetedCount; 351 int fBudgetedCount;
315 size_t fBudgetedBytes; 352 size_t fBudgetedBytes;
316 353
317 bool fRequestFlush;
318 uint32_t fExternalFlushCnt; 354 uint32_t fExternalFlushCnt;
319 355
356 bool fIsPurging;
357
320 InvalidUniqueKeyInbox fInvalidUniqueKeyInbox; 358 InvalidUniqueKeyInbox fInvalidUniqueKeyInbox;
321 359
322 // This resource is allowed to be in the nonpurgeable array for the sake of validate() because 360 // This resource is allowed to be in the nonpurgeable array for the sake of validate() because
323 // we're in the midst of converting it to purgeable status. 361 // we're in the midst of converting it to purgeable status.
324 SkDEBUGCODE(GrGpuResource* fNewlyPurgeableResourceForValidation;) 362 SkDEBUGCODE(GrGpuResource* fNewlyPurgeableResourceForValidation;)
325 363
326 bool fPreferVRAMUseOverFlushes; 364 bool fPreferVRAMUseOverFlushes;
327 }; 365 };
328 366
329 class GrResourceCache::ResourceAccess { 367 class GrResourceCache::ResourceAccess {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 441
404 friend class GrGpuResource; // To access all the proxy inline methods. 442 friend class GrGpuResource; // To access all the proxy inline methods.
405 friend class GrResourceCache; // To create this type. 443 friend class GrResourceCache; // To create this type.
406 }; 444 };
407 445
408 inline GrResourceCache::ResourceAccess GrResourceCache::resourceAccess() { 446 inline GrResourceCache::ResourceAccess GrResourceCache::resourceAccess() {
409 return ResourceAccess(this); 447 return ResourceAccess(this);
410 } 448 }
411 449
412 #endif 450 #endif
OLDNEW
« no previous file with comments | « src/gpu/GrDrawingManager.cpp ('k') | src/gpu/GrResourceCache.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698