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

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: Add comment 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
« no previous file with comments | « src/gpu/GrGpuResource.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 /* 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 20 matching lines...) Expand all
31 * resource instances with the same properties (e.g. multipass rendering that ping-pongs 31 * resource instances with the same properties (e.g. multipass rendering that ping-pongs
32 * between two temporary surfaces). The scratch key is set at resource c reation time and 32 * between two temporary surfaces). The scratch key is set at resource c reation time and
33 * should never change. Resources need not have a scratch key. 33 * should never change. Resources need not have a scratch key.
34 * 2) A unique key. This key's meaning is specific to the domain that creat ed the key. Only one 34 * 2) A unique key. This key's meaning is specific to the domain that creat ed the key. Only one
35 * resource may have a given unique key. The unique key can be set, clea red, or changed 35 * resource may have a given unique key. The unique key can be set, clea red, or changed
36 * anytime after resource creation. 36 * anytime after resource creation.
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 *
42 * When proactive purging is enabled, on every flush, the timestamp of that flus h is stored in a
43 * n-sized ring buffer. When purging occurs each purgeable resource's timestamp is compared to the
44 * timestamp of the n-th prior flush. If the resource's last use timestamp is ol der than the old
45 * flush then the resource is proactively purged even when the cache is under bu dget. By default
46 * this feature is disabled, though it can be enabled by calling GrResourceCache ::setLimits.
41 */ 47 */
42 class GrResourceCache { 48 class GrResourceCache {
43 public: 49 public:
44 GrResourceCache(); 50 GrResourceCache();
45 ~GrResourceCache(); 51 ~GrResourceCache();
46 52
53 // Default maximum number of budgeted resources in the cache.
54 static const int kDefaultMaxCount = 2 * (1 << 12);
55 // Default maximum number of bytes of gpu memory of budgeted resources in th e cache.
56 static const size_t kDefaultMaxSize = 96 * (1 << 20);
57 // Default number of flushes a budgeted resources can go unused in the cache before it is
58 // purged. Large values disable the feature (as the ring buffer of flush tim estamps would be
59 // large). This is currently the default until we decide to enable this feat ure
60 // of the cache by default.
61 static const int kDefaultMaxUnusedFlushes = 1024;
62
47 /** Used to access functionality needed by GrGpuResource for lifetime manage ment. */ 63 /** Used to access functionality needed by GrGpuResource for lifetime manage ment. */
48 class ResourceAccess; 64 class ResourceAccess;
49 ResourceAccess resourceAccess(); 65 ResourceAccess resourceAccess();
50 66
51 /** 67 /**
52 * Sets the cache limits in terms of number of resources and max gpu memory byte size. 68 * Sets the cache limits in terms of number of resources, max gpu memory byt e size, and number
69 * of GrContext flushes that a resource can be unused before it is evicted. The latter value is
70 * a suggestion and there is no promise that a resource will be purged immed iately after it
71 * hasn't been used in maxUnusedFlushes flushes.
53 */ 72 */
54 void setLimits(int count, size_t bytes); 73 void setLimits(int count, size_t bytes, int maxUnusedFlushes = kDefaultMaxUn usedFlushes);
55 74
56 /** 75 /**
57 * Returns the number of resources. 76 * Returns the number of resources.
58 */ 77 */
59 int getResourceCount() const { 78 int getResourceCount() const {
60 return fPurgeableQueue.count() + fNonpurgeableResources.count(); 79 return fPurgeableQueue.count() + fNonpurgeableResources.count();
61 } 80 }
62 81
63 /** 82 /**
64 * Returns the number of resources that count against the budget. 83 * Returns the number of resources that count against the budget.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 148
130 /** 149 /**
131 * Query whether a unique key exists in the cache. 150 * Query whether a unique key exists in the cache.
132 */ 151 */
133 bool hasUniqueKey(const GrUniqueKey& key) const { 152 bool hasUniqueKey(const GrUniqueKey& key) const {
134 return SkToBool(fUniqueHash.find(key)); 153 return SkToBool(fUniqueHash.find(key));
135 } 154 }
136 155
137 /** Purges resources to become under budget and processes resources with inv alidated unique 156 /** Purges resources to become under budget and processes resources with inv alidated unique
138 keys. */ 157 keys. */
139 void purgeAsNeeded() { 158 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 159
151 /** Purges all resources that don't have external owners. */ 160 /** Purges all resources that don't have external owners. */
152 void purgeAllUnlocked(); 161 void purgeAllUnlocked();
153 162
154 /** 163 /**
155 * The callback function used by the cache when it is still over budget afte r a purge. The 164 * 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. 165 * passed in 'data' is the same 'data' handed to setOverbudgetCallback.
157 */ 166 */
158 typedef void (*PFOverBudgetCB)(void* data); 167 typedef void (*PFOverBudgetCB)(void* data);
159 168
160 /** 169 /**
161 * Set the callback the cache should use when it is still over budget after a purge. The 'data' 170 * 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 171 * 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. 172 * any resources newly freed by the callback.
164 */ 173 */
165 void setOverBudgetCallback(PFOverBudgetCB overBudgetCB, void* data) { 174 void setOverBudgetCallback(PFOverBudgetCB overBudgetCB, void* data) {
166 fOverBudgetCB = overBudgetCB; 175 fOverBudgetCB = overBudgetCB;
167 fOverBudgetData = data; 176 fOverBudgetData = data;
168 } 177 }
178
179 void notifyFlushOccurred();
169 180
170 #if GR_GPU_STATS 181 #if GR_GPU_STATS
171 void dumpStats(SkString*) const; 182 void dumpStats(SkString*) const;
172 #endif 183 #endif
173 184
174 // This function is for unit testing and is only defined in test tools. 185 // This function is for unit testing and is only defined in test tools.
175 void changeTimestamp(uint32_t newTimestamp); 186 void changeTimestamp(uint32_t newTimestamp);
176 187
177 private: 188 private:
178 /////////////////////////////////////////////////////////////////////////// 189 ///////////////////////////////////////////////////////////////////////////
179 /// @name Methods accessible via ResourceAccess 190 /// @name Methods accessible via ResourceAccess
180 //// 191 ////
181 void insertResource(GrGpuResource*); 192 void insertResource(GrGpuResource*);
182 void removeResource(GrGpuResource*); 193 void removeResource(GrGpuResource*);
183 void notifyPurgeable(GrGpuResource*); 194 void notifyCntReachedZero(GrGpuResource*, uint32_t flags);
184 void didChangeGpuMemorySize(const GrGpuResource*, size_t oldSize); 195 void didChangeGpuMemorySize(const GrGpuResource*, size_t oldSize);
185 void changeUniqueKey(GrGpuResource*, const GrUniqueKey&); 196 void changeUniqueKey(GrGpuResource*, const GrUniqueKey&);
186 void removeUniqueKey(GrGpuResource*); 197 void removeUniqueKey(GrGpuResource*);
187 void willRemoveScratchKey(const GrGpuResource*); 198 void willRemoveScratchKey(const GrGpuResource*);
188 void didChangeBudgetStatus(GrGpuResource*); 199 void didChangeBudgetStatus(GrGpuResource*);
189 void refAndMakeResourceMRU(GrGpuResource*); 200 void refAndMakeResourceMRU(GrGpuResource*);
190 /// @} 201 /// @}
191 202
192 void internalPurgeAsNeeded(); 203 void resetFlushTimestamps();
193 void processInvalidUniqueKeys(const SkTArray<GrUniqueKeyInvalidatedMessage>& ); 204 void processInvalidUniqueKeys(const SkTArray<GrUniqueKeyInvalidatedMessage>& );
194 void addToNonpurgeableArray(GrGpuResource*); 205 void addToNonpurgeableArray(GrGpuResource*);
195 void removeFromNonpurgeableArray(GrGpuResource*); 206 void removeFromNonpurgeableArray(GrGpuResource*);
196 bool overBudget() const { return fBudgetedBytes > fMaxBytes || fBudgetedCoun t > fMaxCount; } 207 bool overBudget() const { return fBudgetedBytes > fMaxBytes || fBudgetedCoun t > fMaxCount; }
197 208
198 uint32_t getNextTimestamp(); 209 uint32_t getNextTimestamp();
199 210
200 #ifdef SK_DEBUG 211 #ifdef SK_DEBUG
201 bool isInCache(const GrGpuResource* r) const; 212 bool isInCache(const GrGpuResource* r) const;
202 void validate() const; 213 void validate() const;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 ResourceArray fNonpurgeableResources; 255 ResourceArray fNonpurgeableResources;
245 256
246 // This map holds all resources that can be used as scratch resources. 257 // This map holds all resources that can be used as scratch resources.
247 ScratchMap fScratchMap; 258 ScratchMap fScratchMap;
248 // This holds all resources that have unique keys. 259 // This holds all resources that have unique keys.
249 UniqueHash fUniqueHash; 260 UniqueHash fUniqueHash;
250 261
251 // our budget, used in purgeAsNeeded() 262 // our budget, used in purgeAsNeeded()
252 int fMaxCount; 263 int fMaxCount;
253 size_t fMaxBytes; 264 size_t fMaxBytes;
265 int fMaxUnusedFlushes;
254 266
255 #if GR_CACHE_STATS 267 #if GR_CACHE_STATS
256 int fHighWaterCount; 268 int fHighWaterCount;
257 size_t fHighWaterBytes; 269 size_t fHighWaterBytes;
258 int fBudgetedHighWaterCount; 270 int fBudgetedHighWaterCount;
259 size_t fBudgetedHighWaterBytes; 271 size_t fBudgetedHighWaterBytes;
260 #endif 272 #endif
261 273
262 // our current stats for all resources 274 // our current stats for all resources
263 SkDEBUGCODE(int fCount;) 275 SkDEBUGCODE(int fCount;)
264 size_t fBytes; 276 size_t fBytes;
265 277
266 // our current stats for resources that count against the budget 278 // our current stats for resources that count against the budget
267 int fBudgetedCount; 279 int fBudgetedCount;
268 size_t fBudgetedBytes; 280 size_t fBudgetedBytes;
269 281
270 PFOverBudgetCB fOverBudgetCB; 282 PFOverBudgetCB fOverBudgetCB;
271 void* fOverBudgetData; 283 void* fOverBudgetData;
272 284
285 // We keep track of the "timestamps" of the last n flushes. If a resource ha sn't been used in
286 // that time then we well preemptively purge it to reduce memory usage.
287 uint32_t* fFlushTimestamps;
288 int fLastFlushTimestampIndex;
289
273 InvalidUniqueKeyInbox fInvalidUniqueKeyInbox; 290 InvalidUniqueKeyInbox fInvalidUniqueKeyInbox;
291
292 // This resource is allowed to be in the nonpurgeable array for the sake of validate() because
293 // we're in the midst of converting it to purgeable status.
294 SkDEBUGCODE(GrGpuResource* fNewlyPurgeableResourceForValidation;)
274 }; 295 };
275 296
276 class GrResourceCache::ResourceAccess { 297 class GrResourceCache::ResourceAccess {
277 private: 298 private:
278 ResourceAccess(GrResourceCache* cache) : fCache(cache) { } 299 ResourceAccess(GrResourceCache* cache) : fCache(cache) { }
279 ResourceAccess(const ResourceAccess& that) : fCache(that.fCache) { } 300 ResourceAccess(const ResourceAccess& that) : fCache(that.fCache) { }
280 ResourceAccess& operator=(const ResourceAccess&); // unimpl 301 ResourceAccess& operator=(const ResourceAccess&); // unimpl
281 302
282 /** 303 /**
283 * Insert a resource into the cache. 304 * Insert a resource into the cache.
284 */ 305 */
285 void insertResource(GrGpuResource* resource) { fCache->insertResource(resour ce); } 306 void insertResource(GrGpuResource* resource) { fCache->insertResource(resour ce); }
286 307
287 /** 308 /**
288 * Removes a resource from the cache. 309 * Removes a resource from the cache.
289 */ 310 */
290 void removeResource(GrGpuResource* resource) { fCache->removeResource(resour ce); } 311 void removeResource(GrGpuResource* resource) { fCache->removeResource(resour ce); }
291 312
292 /** 313 /**
293 * Called by GrGpuResources when they detects that they are newly purgeable. 314 * Notifications that should be sent to the cache when the ref/io cnt status of resources
315 * changes.
294 */ 316 */
295 void notifyPurgeable(GrGpuResource* resource) { fCache->notifyPurgeable(reso urce); } 317 enum RefNotificationFlags {
318 /** All types of refs on the resource have reached zero. */
319 kAllCntsReachedZero_RefNotificationFlag = 0x1,
320 /** The normal (not pending IO type) ref cnt has reached zero. */
321 kRefCntReachedZero_RefNotificationFlag = 0x2,
322 };
323 /**
324 * Called by GrGpuResources when they detect that their ref/io cnts have rea ched zero. When the
325 * normal ref cnt reaches zero the flags that are set should be:
326 * a) kRefCntReachedZero if a pending IO cnt is still non-zero.
327 * b) (kRefCntReachedZero | kAllCntsReachedZero) when all pending IO cnt s are also zero.
328 * kAllCntsReachedZero is set by itself if a pending IO cnt is decremented t o zero and all the
329 * the other cnts are already zero.
330 */
331 void notifyCntReachedZero(GrGpuResource* resource, uint32_t flags) {
332 fCache->notifyCntReachedZero(resource, flags);
333 }
296 334
297 /** 335 /**
298 * Called by GrGpuResources when their sizes change. 336 * Called by GrGpuResources when their sizes change.
299 */ 337 */
300 void didChangeGpuMemorySize(const GrGpuResource* resource, size_t oldSize) { 338 void didChangeGpuMemorySize(const GrGpuResource* resource, size_t oldSize) {
301 fCache->didChangeGpuMemorySize(resource, oldSize); 339 fCache->didChangeGpuMemorySize(resource, oldSize);
302 } 340 }
303 341
304 /** 342 /**
305 * Called by GrGpuResources to change their unique keys. 343 * Called by GrGpuResources to change their unique keys.
(...skipping 27 matching lines...) Expand all
333 371
334 friend class GrGpuResource; // To access all the proxy inline methods. 372 friend class GrGpuResource; // To access all the proxy inline methods.
335 friend class GrResourceCache; // To create this type. 373 friend class GrResourceCache; // To create this type.
336 }; 374 };
337 375
338 inline GrResourceCache::ResourceAccess GrResourceCache::resourceAccess() { 376 inline GrResourceCache::ResourceAccess GrResourceCache::resourceAccess() {
339 return ResourceAccess(this); 377 return ResourceAccess(this);
340 } 378 }
341 379
342 #endif 380 #endif
OLDNEW
« no previous file with comments | « src/gpu/GrGpuResource.cpp ('k') | src/gpu/GrResourceCache.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698