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

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

Issue 1032873002: Add mechanism to proactively purge old resources in GrResourceCache. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: rebase to tot Created 5 years, 8 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
OLDNEW
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 26 matching lines...) Expand all
37 * 37 *
38 * A unique key always takes precedence over a scratch key when a resource has b oth types of keys. 38 * A unique key always takes precedence over a scratch key when a resource has b oth types of keys.
39 * 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
40 * is dropped. 40 * is dropped.
41 */ 41 */
42 class GrResourceCache { 42 class GrResourceCache {
43 public: 43 public:
44 GrResourceCache(); 44 GrResourceCache();
45 ~GrResourceCache(); 45 ~GrResourceCache();
46 46
47 // Default maximum number of budgeted resources in the cache.
48 static const int kDefaultMaxCount = 2 * (1 << 12);
49 // Default maximum number of bytes of gpu memory of budgeted resources in th e cache.
50 static const size_t kDefaultMaxSize = 96 * (1 << 20);
51 // Default number of flushes a budgeted resources can go unused in the cache before it is
52 // purged. This is currently set to a large default value until we decide to enable this feature
53 // of the cache.
54 static const int kDefaultMaxUnusedFlushes = 1024;
55
47 /** Used to access functionality needed by GrGpuResource for lifetime manage ment. */ 56 /** Used to access functionality needed by GrGpuResource for lifetime manage ment. */
48 class ResourceAccess; 57 class ResourceAccess;
49 ResourceAccess resourceAccess(); 58 ResourceAccess resourceAccess();
50 59
51 /** 60 /**
52 * Sets the cache limits in terms of number of resources and max gpu memory byte size. 61 * Sets the cache limits in terms of number of resources, max gpu memory byt e size, and number
62 * of GrContext flushes that a resource can be unused before it is evicted. The latter value is
63 * a suggestion and there is no promise that a resource will be purged immed iately after it
64 * hasn't been used in maxUnusedFlushes flushes.
53 */ 65 */
54 void setLimits(int count, size_t bytes); 66 void setLimits(int count, size_t bytes, int maxUnusedFlushes = kDefaultMaxUn usedFlushes);
55 67
56 /** 68 /**
57 * Returns the number of resources. 69 * Returns the number of resources.
58 */ 70 */
59 int getResourceCount() const { 71 int getResourceCount() const {
60 return fPurgeableQueue.count() + fNonpurgeableResources.count(); 72 return fPurgeableQueue.count() + fNonpurgeableResources.count();
61 } 73 }
62 74
63 /** 75 /**
64 * Returns the number of resources that count against the budget. 76 * Returns the number of resources that count against the budget.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 141
130 /** 142 /**
131 * Query whether a unique key exists in the cache. 143 * Query whether a unique key exists in the cache.
132 */ 144 */
133 bool hasUniqueKey(const GrUniqueKey& key) const { 145 bool hasUniqueKey(const GrUniqueKey& key) const {
134 return SkToBool(fUniqueHash.find(key)); 146 return SkToBool(fUniqueHash.find(key));
135 } 147 }
136 148
137 /** Purges resources to become under budget and processes resources with inv alidated unique 149 /** Purges resources to become under budget and processes resources with inv alidated unique
138 keys. */ 150 keys. */
139 void purgeAsNeeded() { 151 void purgeAsNeeded();
140 SkTArray<GrUniqueKeyInvalidatedMessage> invalidKeyMsgs;
141 fInvalidUniqueKeyInbox.poll(&invalidKeyMsgs);
142 if (invalidKeyMsgs.count()) {
143 this->processInvalidUniqueKeys(invalidKeyMsgs);
144 }
145 if (fBudgetedCount <= fMaxCount && fBudgetedBytes <= fMaxBytes) {
146 return;
147 }
148 this->internalPurgeAsNeeded();
149 }
150 152
151 /** Purges all resources that don't have external owners. */ 153 /** Purges all resources that don't have external owners. */
152 void purgeAllUnlocked(); 154 void purgeAllUnlocked();
153 155
154 /** 156 /**
155 * The callback function used by the cache when it is still over budget afte r a purge. The 157 * The callback function used by the cache when it is still over budget afte r a purge. The
156 * passed in 'data' is the same 'data' handed to setOverbudgetCallback. 158 * passed in 'data' is the same 'data' handed to setOverbudgetCallback.
157 */ 159 */
158 typedef void (*PFOverBudgetCB)(void* data); 160 typedef void (*PFOverBudgetCB)(void* data);
159 161
160 /** 162 /**
161 * Set the callback the cache should use when it is still over budget after a purge. The 'data' 163 * Set the callback the cache should use when it is still over budget after a purge. The 'data'
162 * provided here will be passed back to the callback. Note that the cache wi ll attempt to purge 164 * provided here will be passed back to the callback. Note that the cache wi ll attempt to purge
163 * any resources newly freed by the callback. 165 * any resources newly freed by the callback.
164 */ 166 */
165 void setOverBudgetCallback(PFOverBudgetCB overBudgetCB, void* data) { 167 void setOverBudgetCallback(PFOverBudgetCB overBudgetCB, void* data) {
166 fOverBudgetCB = overBudgetCB; 168 fOverBudgetCB = overBudgetCB;
167 fOverBudgetData = data; 169 fOverBudgetData = data;
168 } 170 }
171
172 void notifyFlushOccurred();
169 173
170 #if GR_GPU_STATS 174 #if GR_GPU_STATS
171 void dumpStats(SkString*) const; 175 void dumpStats(SkString*) const;
172 #endif 176 #endif
173 177
174 // This function is for unit testing and is only defined in test tools. 178 // This function is for unit testing and is only defined in test tools.
175 void changeTimestamp(uint32_t newTimestamp); 179 void changeTimestamp(uint32_t newTimestamp);
176 180
177 private: 181 private:
178 /////////////////////////////////////////////////////////////////////////// 182 ///////////////////////////////////////////////////////////////////////////
179 /// @name Methods accessible via ResourceAccess 183 /// @name Methods accessible via ResourceAccess
180 //// 184 ////
181 void insertResource(GrGpuResource*); 185 void insertResource(GrGpuResource*);
182 void removeResource(GrGpuResource*); 186 void removeResource(GrGpuResource*);
183 void notifyPurgeable(GrGpuResource*); 187 void notifyCntReachedZero(GrGpuResource*, uint32_t flags);
184 void didChangeGpuMemorySize(const GrGpuResource*, size_t oldSize); 188 void didChangeGpuMemorySize(const GrGpuResource*, size_t oldSize);
185 void changeUniqueKey(GrGpuResource*, const GrUniqueKey&); 189 void changeUniqueKey(GrGpuResource*, const GrUniqueKey&);
186 void removeUniqueKey(GrGpuResource*); 190 void removeUniqueKey(GrGpuResource*);
187 void willRemoveScratchKey(const GrGpuResource*); 191 void willRemoveScratchKey(const GrGpuResource*);
188 void didChangeBudgetStatus(GrGpuResource*); 192 void didChangeBudgetStatus(GrGpuResource*);
189 void refAndMakeResourceMRU(GrGpuResource*); 193 void refAndMakeResourceMRU(GrGpuResource*);
190 /// @} 194 /// @}
191 195
192 void internalPurgeAsNeeded(); 196 void resetFlushTimestamps();
193 void processInvalidUniqueKeys(const SkTArray<GrUniqueKeyInvalidatedMessage>& ); 197 void processInvalidUniqueKeys(const SkTArray<GrUniqueKeyInvalidatedMessage>& );
194 void addToNonpurgeableArray(GrGpuResource*); 198 void addToNonpurgeableArray(GrGpuResource*);
195 void removeFromNonpurgeableArray(GrGpuResource*); 199 void removeFromNonpurgeableArray(GrGpuResource*);
196 bool overBudget() const { return fBudgetedBytes > fMaxBytes || fBudgetedCoun t > fMaxCount; } 200 bool overBudget() const { return fBudgetedBytes > fMaxBytes || fBudgetedCoun t > fMaxCount; }
197 201
198 uint32_t getNextTimestamp(); 202 uint32_t getNextTimestamp();
199 203
200 #ifdef SK_DEBUG 204 #ifdef SK_DEBUG
201 bool isInCache(const GrGpuResource* r) const; 205 bool isInCache(const GrGpuResource* r) const;
202 void validate() const; 206 void validate() const;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 ResourceArray fNonpurgeableResources; 248 ResourceArray fNonpurgeableResources;
245 249
246 // This map holds all resources that can be used as scratch resources. 250 // This map holds all resources that can be used as scratch resources.
247 ScratchMap fScratchMap; 251 ScratchMap fScratchMap;
248 // This holds all resources that have unique keys. 252 // This holds all resources that have unique keys.
249 UniqueHash fUniqueHash; 253 UniqueHash fUniqueHash;
250 254
251 // our budget, used in purgeAsNeeded() 255 // our budget, used in purgeAsNeeded()
252 int fMaxCount; 256 int fMaxCount;
253 size_t fMaxBytes; 257 size_t fMaxBytes;
258 int fMaxUnusedFlushes;
254 259
255 #if GR_CACHE_STATS 260 #if GR_CACHE_STATS
256 int fHighWaterCount; 261 int fHighWaterCount;
257 size_t fHighWaterBytes; 262 size_t fHighWaterBytes;
258 int fBudgetedHighWaterCount; 263 int fBudgetedHighWaterCount;
259 size_t fBudgetedHighWaterBytes; 264 size_t fBudgetedHighWaterBytes;
260 #endif 265 #endif
261 266
262 // our current stats for all resources 267 // our current stats for all resources
263 SkDEBUGCODE(int fCount;) 268 SkDEBUGCODE(int fCount;)
264 size_t fBytes; 269 size_t fBytes;
265 270
266 // our current stats for resources that count against the budget 271 // our current stats for resources that count against the budget
267 int fBudgetedCount; 272 int fBudgetedCount;
268 size_t fBudgetedBytes; 273 size_t fBudgetedBytes;
269 274
270 PFOverBudgetCB fOverBudgetCB; 275 PFOverBudgetCB fOverBudgetCB;
271 void* fOverBudgetData; 276 void* fOverBudgetData;
272 277
278 // We keep track of the "timestamps" of the last n flushes. If a resource ha sn't been used in
robertphillips 2015/04/06 19:34:51 Delete the parenthetical question? Isn't fMaxUnuse
bsalomon 2015/04/07 20:33:46 Done.
279 // that time then we well preemptively purge it to reduce memory usage. (Mak e this
280 // configurable with other budget parameters?)
281 uint32_t* fFlushTimestamps;
282 int fLastFlushTimestampIndex;
283
273 InvalidUniqueKeyInbox fInvalidUniqueKeyInbox; 284 InvalidUniqueKeyInbox fInvalidUniqueKeyInbox;
285
286 // This resource is allowed to be in the nonpurgeable array for the sake of validate() because
287 // we're in the midst of converting it to purgeable status.
288 SkDEBUGCODE(GrGpuResource* fNewlyPurgeableResourceForValidation;)
274 }; 289 };
275 290
276 class GrResourceCache::ResourceAccess { 291 class GrResourceCache::ResourceAccess {
277 private: 292 private:
278 ResourceAccess(GrResourceCache* cache) : fCache(cache) { } 293 ResourceAccess(GrResourceCache* cache) : fCache(cache) { }
279 ResourceAccess(const ResourceAccess& that) : fCache(that.fCache) { } 294 ResourceAccess(const ResourceAccess& that) : fCache(that.fCache) { }
280 ResourceAccess& operator=(const ResourceAccess&); // unimpl 295 ResourceAccess& operator=(const ResourceAccess&); // unimpl
281 296
282 /** 297 /**
283 * Insert a resource into the cache. 298 * Insert a resource into the cache.
284 */ 299 */
285 void insertResource(GrGpuResource* resource) { fCache->insertResource(resour ce); } 300 void insertResource(GrGpuResource* resource) { fCache->insertResource(resour ce); }
286 301
287 /** 302 /**
288 * Removes a resource from the cache. 303 * Removes a resource from the cache.
289 */ 304 */
290 void removeResource(GrGpuResource* resource) { fCache->removeResource(resour ce); } 305 void removeResource(GrGpuResource* resource) { fCache->removeResource(resour ce); }
291 306
292 /** 307 /**
293 * Called by GrGpuResources when they detects that they are newly purgeable. 308 * Notifications that should be sent to the cache when the ref/io cnt status of resources
309 * changes.
294 */ 310 */
295 void notifyPurgeable(GrGpuResource* resource) { fCache->notifyPurgeable(reso urce); } 311 enum RefNotificationFlags {
312 /** All types of refs on the resource have reached zero. */
313 kAllCntsReachedZero_RefNotificationFlag = 0x1,
314 /** The normal (not pending IO type) ref cnt has reached zero. */
315 kRefCntReachedZero_RefNotificationFlag = 0x2,
316 };
317 /**
robertphillips 2015/04/06 19:34:51 detects -> detect ?
bsalomon 2015/04/07 20:33:46 Done.
318 * Called by GrGpuResources when they detects that their ref/io cnts have re ached zero. When the
319 * normal ref cnt reaches zero the flags that are set should be:
320 * a) kRefCntReachedZero if a pending IO cnt is still non-zero.
321 * b) (kRefCntReachedZero | kAllCntsReachedZero) when all pending IO cnt s are also zero.
322 * kAllCntsReachedZero is set by itself if a pending IO cnt is decremented t o zero and all the
323 * the other cnts are already zero.
324 */
325 void notifyCntReachedZero(GrGpuResource* resource, uint32_t flags) {
326 fCache->notifyCntReachedZero(resource, flags);
327 }
296 328
297 /** 329 /**
298 * Called by GrGpuResources when their sizes change. 330 * Called by GrGpuResources when their sizes change.
299 */ 331 */
300 void didChangeGpuMemorySize(const GrGpuResource* resource, size_t oldSize) { 332 void didChangeGpuMemorySize(const GrGpuResource* resource, size_t oldSize) {
301 fCache->didChangeGpuMemorySize(resource, oldSize); 333 fCache->didChangeGpuMemorySize(resource, oldSize);
302 } 334 }
303 335
304 /** 336 /**
305 * Called by GrGpuResources to change their unique keys. 337 * Called by GrGpuResources to change their unique keys.
(...skipping 27 matching lines...) Expand all
333 365
334 friend class GrGpuResource; // To access all the proxy inline methods. 366 friend class GrGpuResource; // To access all the proxy inline methods.
335 friend class GrResourceCache; // To create this type. 367 friend class GrResourceCache; // To create this type.
336 }; 368 };
337 369
338 inline GrResourceCache::ResourceAccess GrResourceCache::resourceAccess() { 370 inline GrResourceCache::ResourceAccess GrResourceCache::resourceAccess() {
339 return ResourceAccess(this); 371 return ResourceAccess(this);
340 } 372 }
341 373
342 #endif 374 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698