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 | 9 |
10 #include "GrResourceCache2.h" | 10 #include "GrResourceCache2.h" |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
237 return true; | 237 return true; |
238 } | 238 } |
239 | 239 |
240 void GrResourceCache2::makeResourceMRU(GrGpuResource* resource) { | 240 void GrResourceCache2::makeResourceMRU(GrGpuResource* resource) { |
241 SkASSERT(!fPurging); | 241 SkASSERT(!fPurging); |
242 SkASSERT(resource); | 242 SkASSERT(resource); |
243 SkASSERT(this->isInCache(resource)); | 243 SkASSERT(this->isInCache(resource)); |
244 fResources.remove(resource); | 244 fResources.remove(resource); |
245 fResources.addToHead(resource); | 245 fResources.addToHead(resource); |
246 } | 246 } |
247 | 247 |
robertphillips
2015/01/23 14:54:10
Purgeable ?
| |
248 void GrResourceCache2::notifyPurgable(GrGpuResource* resource) { | 248 void GrResourceCache2::notifyPurgable(GrGpuResource* resource) { |
249 SkASSERT(resource); | 249 SkASSERT(resource); |
250 SkASSERT(this->isInCache(resource)); | 250 SkASSERT(this->isInCache(resource)); |
251 SkASSERT(resource->isPurgable()); | 251 SkASSERT(resource->isPurgable()); |
252 | 252 |
253 // We can't purge if in the middle of purging because purge is iterating. In stead record | 253 // We can't purge if in the middle of purging because purge is iterating. In stead record |
254 // that additional resources became purgable. | 254 // that additional resources became purgable. |
255 if (fPurging) { | 255 if (fPurging) { |
256 fNewlyPurgableResourceWhilePurging = true; | 256 fNewlyPurgableResourceWhilePurging = true; |
257 return; | 257 return; |
258 } | 258 } |
259 | 259 |
260 // Purge the resource if we're over budget | 260 bool release = false; |
261 bool overBudget = fBudgetedCount > fMaxCount || fBudgetedBytes > fMaxBytes; | |
262 | 261 |
263 // Also purge if the resource has neither a valid scratch key nor a content key. | 262 if (resource->cacheAccess().isWrapped()) { |
264 bool noKey = !resource->cacheAccess().getScratchKey().isValid() && | 263 release = true; |
265 !resource->cacheAccess().getContentKey().isValid(); | 264 } else if (!resource->cacheAccess().isBudgeted()) { |
265 // Check whether this resource could still be used as a scratch resource . | |
266 if (resource->cacheAccess().getScratchKey().isValid()) { | |
267 // We won't purge an existing resource to make room for this one. | |
268 bool underBudget = fBudgetedCount < fMaxCount && | |
269 fBudgetedBytes + resource->gpuMemorySize() <= fMa xBytes; | |
270 if (underBudget) { | |
271 resource->cacheAccess().makeBudgeted(); | |
272 } else { | |
273 release = true; | |
274 } | |
275 } else { | |
276 release = true; | |
277 } | |
278 } else { | |
279 // Purge the resource if we're over budget | |
280 bool overBudget = fBudgetedCount > fMaxCount || fBudgetedBytes > fMaxByt es; | |
266 | 281 |
267 // Only cached resources should ever have a key. | 282 // Also purge if the resource has neither a valid scratch key nor a cont ent key. |
268 SkASSERT(noKey || resource->cacheAccess().isBudgeted()); | 283 bool noKey = !resource->cacheAccess().getScratchKey().isValid() && |
284 !resource->cacheAccess().getContentKey().isValid(); | |
285 if (overBudget || noKey) { | |
286 release = true; | |
287 } | |
288 } | |
269 | 289 |
270 if (overBudget || noKey) { | 290 if (release) { |
271 SkDEBUGCODE(int beforeCount = fCount;) | 291 SkDEBUGCODE(int beforeCount = fCount;) |
272 resource->cacheAccess().release(); | 292 resource->cacheAccess().release(); |
273 // We should at least free this resource, perhaps dependent resources as well. | 293 // We should at least free this resource, perhaps dependent resources as well. |
274 SkASSERT(fCount < beforeCount); | 294 SkASSERT(fCount < beforeCount); |
275 } | 295 } |
276 | |
277 this->validate(); | 296 this->validate(); |
278 } | 297 } |
279 | 298 |
280 void GrResourceCache2::didChangeGpuMemorySize(const GrGpuResource* resource, siz e_t oldSize) { | 299 void GrResourceCache2::didChangeGpuMemorySize(const GrGpuResource* resource, siz e_t oldSize) { |
281 // SkASSERT(!fPurging); GrPathRange increases size during flush. :( | 300 // SkASSERT(!fPurging); GrPathRange increases size during flush. :( |
282 SkASSERT(resource); | 301 SkASSERT(resource); |
283 SkASSERT(this->isInCache(resource)); | 302 SkASSERT(this->isInCache(resource)); |
284 | 303 |
285 ptrdiff_t delta = resource->gpuMemorySize() - oldSize; | 304 ptrdiff_t delta = resource->gpuMemorySize() - oldSize; |
286 | 305 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
382 if (!fNewlyPurgableResourceWhilePurging && fCount && fOverBudgetCB) { | 401 if (!fNewlyPurgableResourceWhilePurging && fCount && fOverBudgetCB) { |
383 (*fOverBudgetCB)(fOverBudgetData); | 402 (*fOverBudgetCB)(fOverBudgetData); |
384 } | 403 } |
385 } while (fNewlyPurgableResourceWhilePurging); | 404 } while (fNewlyPurgableResourceWhilePurging); |
386 fPurging = false; | 405 fPurging = false; |
387 this->validate(); | 406 this->validate(); |
388 } | 407 } |
389 | 408 |
390 #ifdef SK_DEBUG | 409 #ifdef SK_DEBUG |
391 void GrResourceCache2::validate() const { | 410 void GrResourceCache2::validate() const { |
411 // Reduce the frequency of validations for large resource counts. | |
412 static SkRandom gRandom; | |
413 int mask = (SkNextPow2(fCount + 1) >> 5) - 1; | |
414 if (~mask && (gRandom.nextU() & mask)) { | |
415 return; | |
416 } | |
417 | |
392 size_t bytes = 0; | 418 size_t bytes = 0; |
393 int count = 0; | 419 int count = 0; |
394 int budgetedCount = 0; | 420 int budgetedCount = 0; |
395 size_t budgetedBytes = 0; | 421 size_t budgetedBytes = 0; |
396 int locked = 0; | 422 int locked = 0; |
397 int scratch = 0; | 423 int scratch = 0; |
398 int couldBeScratch = 0; | 424 int couldBeScratch = 0; |
399 int content = 0; | 425 int content = 0; |
400 | 426 |
401 ResourceList::Iter iter; | 427 ResourceList::Iter iter; |
402 GrGpuResource* resource = iter.init(fResources, ResourceList::Iter::kHead_It erStart); | 428 GrGpuResource* resource = iter.init(fResources, ResourceList::Iter::kHead_It erStart); |
403 for ( ; resource; resource = iter.next()) { | 429 for ( ; resource; resource = iter.next()) { |
404 bytes += resource->gpuMemorySize(); | 430 bytes += resource->gpuMemorySize(); |
405 ++count; | 431 ++count; |
406 | 432 |
407 if (!resource->isPurgable()) { | 433 if (!resource->isPurgable()) { |
408 ++locked; | 434 ++locked; |
409 } | 435 } |
410 | 436 |
411 if (resource->cacheAccess().isScratch()) { | 437 if (resource->cacheAccess().isScratch()) { |
412 SkASSERT(!resource->cacheAccess().getContentKey().isValid()); | 438 SkASSERT(!resource->cacheAccess().getContentKey().isValid()); |
413 ++scratch; | 439 ++scratch; |
414 SkASSERT(fScratchMap.countForKey(resource->cacheAccess().getScratchK ey())); | 440 SkASSERT(fScratchMap.countForKey(resource->cacheAccess().getScratchK ey())); |
415 SkASSERT(!resource->cacheAccess().isWrapped()); | 441 SkASSERT(!resource->cacheAccess().isWrapped()); |
416 } else if (resource->cacheAccess().getScratchKey().isValid()) { | 442 } else if (resource->cacheAccess().getScratchKey().isValid()) { |
417 SkASSERT(resource->cacheAccess().getContentKey().isValid()); | 443 SkASSERT(!resource->cacheAccess().isBudgeted() || |
444 resource->cacheAccess().getContentKey().isValid()); | |
418 ++couldBeScratch; | 445 ++couldBeScratch; |
419 SkASSERT(fScratchMap.countForKey(resource->cacheAccess().getScratchK ey())); | 446 SkASSERT(fScratchMap.countForKey(resource->cacheAccess().getScratchK ey())); |
420 SkASSERT(!resource->cacheAccess().isWrapped()); | 447 SkASSERT(!resource->cacheAccess().isWrapped()); |
421 } | 448 } |
422 const GrContentKey& contentKey = resource->cacheAccess().getContentKey() ; | 449 const GrContentKey& contentKey = resource->cacheAccess().getContentKey() ; |
423 if (contentKey.isValid()) { | 450 if (contentKey.isValid()) { |
424 ++content; | 451 ++content; |
425 SkASSERT(fContentHash.find(contentKey) == resource); | 452 SkASSERT(fContentHash.find(contentKey) == resource); |
426 SkASSERT(!resource->cacheAccess().isWrapped()); | 453 SkASSERT(!resource->cacheAccess().isWrapped()); |
454 SkASSERT(resource->cacheAccess().isBudgeted()); | |
427 } | 455 } |
428 | 456 |
429 if (resource->cacheAccess().isBudgeted()) { | 457 if (resource->cacheAccess().isBudgeted()) { |
430 ++budgetedCount; | 458 ++budgetedCount; |
431 budgetedBytes += resource->gpuMemorySize(); | 459 budgetedBytes += resource->gpuMemorySize(); |
432 } | 460 } |
433 } | 461 } |
434 | 462 |
435 SkASSERT(fBudgetedCount <= fCount); | 463 SkASSERT(fBudgetedCount <= fCount); |
436 SkASSERT(fBudgetedBytes <= fBudgetedBytes); | 464 SkASSERT(fBudgetedBytes <= fBudgetedBytes); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
488 | 516 |
489 SkDebugf("Budget: %d items %d bytes\n", fMaxCount, fMaxBytes); | 517 SkDebugf("Budget: %d items %d bytes\n", fMaxCount, fMaxBytes); |
490 SkDebugf("\t\tEntry Count: current %d" | 518 SkDebugf("\t\tEntry Count: current %d" |
491 " (%d budgeted, %d wrapped, %d locked, %d scratch %.2g%% full), hig h %d\n", | 519 " (%d budgeted, %d wrapped, %d locked, %d scratch %.2g%% full), hig h %d\n", |
492 fCount, fBudgetedCount, wrapped, locked, scratch, countUtilization, fHig hWaterCount); | 520 fCount, fBudgetedCount, wrapped, locked, scratch, countUtilization, fHig hWaterCount); |
493 SkDebugf("\t\tEntry Bytes: current %d (budgeted %d, %.2g%% full, %d unbudget ed) high %d\n", | 521 SkDebugf("\t\tEntry Bytes: current %d (budgeted %d, %.2g%% full, %d unbudget ed) high %d\n", |
494 fBytes, fBudgetedBytes, byteUtilization, unbudgetedSize, fHighWa terBytes); | 522 fBytes, fBudgetedBytes, byteUtilization, unbudgetedSize, fHighWa terBytes); |
495 } | 523 } |
496 | 524 |
497 #endif | 525 #endif |
OLD | NEW |