Chromium Code Reviews| 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 |