OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2010 Google Inc. | 3 * Copyright 2010 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 |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 | 269 |
270 /** | 270 /** |
271 * Destroying a resource may potentially trigger the unlock of additional | 271 * Destroying a resource may potentially trigger the unlock of additional |
272 * resources which in turn will trigger a nested purge. We block the nested | 272 * resources which in turn will trigger a nested purge. We block the nested |
273 * purge using the fPurging variable. However, the initial purge will keep | 273 * purge using the fPurging variable. However, the initial purge will keep |
274 * looping until either all resources in the cache are unlocked or we've met | 274 * looping until either all resources in the cache are unlocked or we've met |
275 * the budget. There is an assertion in createAndLock to check against a | 275 * the budget. There is an assertion in createAndLock to check against a |
276 * resource's destructor inserting new resources into the cache. If these | 276 * resource's destructor inserting new resources into the cache. If these |
277 * new resources were unlocked before purgeAsNeeded completed it could | 277 * new resources were unlocked before purgeAsNeeded completed it could |
278 * potentially make purgeAsNeeded loop infinitely. | 278 * potentially make purgeAsNeeded loop infinitely. |
| 279 * |
| 280 * extraCount and extraBytes are added to the current resource totals to account |
| 281 * for incoming resources (e.g., GrContext is about to add 10MB split between |
| 282 * 10 textures). |
279 */ | 283 */ |
280 void GrResourceCache::purgeAsNeeded() { | 284 void GrResourceCache::purgeAsNeeded(int extraCount, size_t extraBytes) { |
281 if (fPurging) { | 285 if (fPurging) { |
282 return; | 286 return; |
283 } | 287 } |
284 | 288 |
285 fPurging = true; | 289 fPurging = true; |
286 | 290 |
287 this->internalPurge(); | 291 this->internalPurge(extraCount, extraBytes); |
288 if ((fEntryCount > fMaxCount || fEntryBytes > fMaxBytes) && | 292 if (((fEntryCount+extraCount) > fMaxCount || |
| 293 (fEntryBytes+extraBytes) > fMaxBytes) && |
289 NULL != fOverbudgetCB) { | 294 NULL != fOverbudgetCB) { |
290 // Despite the purge we're still over budget. See if Ganesh can | 295 // Despite the purge we're still over budget. See if Ganesh can |
291 // release some resources and purge again. | 296 // release some resources and purge again. |
292 if ((*fOverbudgetCB)(fOverbudgetData)) { | 297 if ((*fOverbudgetCB)(fOverbudgetData)) { |
293 this->internalPurge(); | 298 this->internalPurge(extraCount, extraBytes); |
294 } | 299 } |
295 } | 300 } |
296 | 301 |
297 fPurging = false; | 302 fPurging = false; |
298 } | 303 } |
299 | 304 |
300 void GrResourceCache::internalPurge() { | 305 void GrResourceCache::internalPurge(int extraCount, size_t extraBytes) { |
301 SkASSERT(fPurging); | 306 SkASSERT(fPurging); |
302 | 307 |
303 bool withinBudget = false; | 308 bool withinBudget = false; |
304 bool changed = false; | 309 bool changed = false; |
305 | 310 |
306 // The purging process is repeated several times since one pass | 311 // The purging process is repeated several times since one pass |
307 // may free up other resources | 312 // may free up other resources |
308 do { | 313 do { |
309 EntryList::Iter iter; | 314 EntryList::Iter iter; |
310 | 315 |
311 changed = false; | 316 changed = false; |
312 | 317 |
313 // Note: the following code relies on the fact that the | 318 // Note: the following code relies on the fact that the |
314 // doubly linked list doesn't invalidate its data/pointers | 319 // doubly linked list doesn't invalidate its data/pointers |
315 // outside of the specific area where a deletion occurs (e.g., | 320 // outside of the specific area where a deletion occurs (e.g., |
316 // in internalDetach) | 321 // in internalDetach) |
317 GrResourceEntry* entry = iter.init(fList, EntryList::Iter::kTail_IterSta
rt); | 322 GrResourceEntry* entry = iter.init(fList, EntryList::Iter::kTail_IterSta
rt); |
318 | 323 |
319 while (NULL != entry) { | 324 while (NULL != entry) { |
320 GrAutoResourceCacheValidate atcv(this); | 325 GrAutoResourceCacheValidate atcv(this); |
321 | 326 |
322 if (fEntryCount <= fMaxCount && fEntryBytes <= fMaxBytes) { | 327 if ((fEntryCount+extraCount) <= fMaxCount && |
| 328 (fEntryBytes+extraBytes) <= fMaxBytes) { |
323 withinBudget = true; | 329 withinBudget = true; |
324 break; | 330 break; |
325 } | 331 } |
326 | 332 |
327 GrResourceEntry* prev = iter.prev(); | 333 GrResourceEntry* prev = iter.prev(); |
328 if (1 == entry->fResource->getRefCnt()) { | 334 if (1 == entry->fResource->getRefCnt()) { |
329 changed = true; | 335 changed = true; |
330 | 336 |
331 // remove from our cache | 337 // remove from our cache |
332 fCache.remove(entry->key(), entry); | 338 fCache.remove(entry->key(), entry); |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 fEntryBytes, fHighWaterEntryBytes); | 464 fEntryBytes, fHighWaterEntryBytes); |
459 SkDebugf("\t\tDetached Entry Count: current %d high %d\n", | 465 SkDebugf("\t\tDetached Entry Count: current %d high %d\n", |
460 fClientDetachedCount, fHighWaterClientDetachedCount); | 466 fClientDetachedCount, fHighWaterClientDetachedCount); |
461 SkDebugf("\t\tDetached Bytes: current %d high %d\n", | 467 SkDebugf("\t\tDetached Bytes: current %d high %d\n", |
462 fClientDetachedBytes, fHighWaterClientDetachedBytes); | 468 fClientDetachedBytes, fHighWaterClientDetachedBytes); |
463 } | 469 } |
464 | 470 |
465 #endif | 471 #endif |
466 | 472 |
467 /////////////////////////////////////////////////////////////////////////////// | 473 /////////////////////////////////////////////////////////////////////////////// |
OLD | NEW |