| 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" |
| 11 #include "GrGpuResource.h" | 11 #include "GrGpuResource.h" |
| 12 | 12 |
| 13 #include "SkChecksum.h" | 13 #include "SkChecksum.h" |
| 14 #include "SkGr.h" | 14 #include "SkGr.h" |
| 15 #include "SkMessageBus.h" | 15 #include "SkMessageBus.h" |
| 16 | 16 |
| 17 DECLARE_SKMESSAGEBUS_MESSAGE(GrResourceInvalidatedMessage); | 17 DECLARE_SKMESSAGEBUS_MESSAGE(GrResourceInvalidatedMessage); |
| 18 | 18 |
| 19 ////////////////////////////////////////////////////////////////////////////// | 19 ////////////////////////////////////////////////////////////////////////////// |
| 20 | 20 |
| 21 GrScratchKey::ResourceType GrScratchKey::GenerateResourceType() { | 21 GrScratchKey::ResourceType GrScratchKey::GenerateResourceType() { |
| 22 static int32_t gType = kInvalidResourceType + 1; | 22 static int32_t gType = INHERITED::kInvalidDomain + 1; |
| 23 | 23 |
| 24 int32_t type = sk_atomic_inc(&gType); | 24 int32_t type = sk_atomic_inc(&gType); |
| 25 if (type > SK_MaxU16) { | 25 if (type > SK_MaxU16) { |
| 26 SkFAIL("Too many Resource Types"); | 26 SkFAIL("Too many Resource Types"); |
| 27 } | 27 } |
| 28 | 28 |
| 29 return static_cast<ResourceType>(type); | 29 return static_cast<ResourceType>(type); |
| 30 } | 30 } |
| 31 | 31 |
| 32 GrContentKey::Domain GrContentKey::GenerateDomain() { |
| 33 static int32_t gDomain = INHERITED::kInvalidDomain + 1; |
| 32 | 34 |
| 33 void GrScratchKey::Builder::finish() { | 35 int32_t domain = sk_atomic_inc(&gDomain); |
| 34 if (NULL == fKey) { | 36 if (kInvalidDomain == gDomain) { |
| 35 return; | 37 SkFAIL("Too many Content Key Domains"); |
| 36 } | 38 } |
| 37 GR_STATIC_ASSERT(0 == kHash_MetaDataIdx); | 39 |
| 38 fKey->fKey[kHash_MetaDataIdx] = | 40 return static_cast<Domain>(domain); |
| 39 SkChecksum::Compute(&fKey->fKey[kHash_MetaDataIdx + 1], fKey->size() - s
izeof(uint32_t)); | 41 } |
| 40 fKey = NULL; | 42 uint32_t GrResourceKeyHash(const uint32_t* data, size_t size) { |
| 43 return SkChecksum::Compute(data, size); |
| 41 } | 44 } |
| 42 | 45 |
| 43 ////////////////////////////////////////////////////////////////////////////// | 46 ////////////////////////////////////////////////////////////////////////////// |
| 44 | 47 |
| 45 class GrResourceCache2::AutoValidate : ::SkNoncopyable { | 48 class GrResourceCache2::AutoValidate : ::SkNoncopyable { |
| 46 public: | 49 public: |
| 47 AutoValidate(GrResourceCache2* cache) : fCache(cache) { cache->validate(); } | 50 AutoValidate(GrResourceCache2* cache) : fCache(cache) { cache->validate(); } |
| 48 ~AutoValidate() { fCache->validate(); } | 51 ~AutoValidate() { fCache->validate(); } |
| 49 private: | 52 private: |
| 50 GrResourceCache2* fCache; | 53 GrResourceCache2* fCache; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 fBytes -= size; | 125 fBytes -= size; |
| 123 if (resource->cacheAccess().isBudgeted()) { | 126 if (resource->cacheAccess().isBudgeted()) { |
| 124 --fBudgetedCount; | 127 --fBudgetedCount; |
| 125 fBudgetedBytes -= size; | 128 fBudgetedBytes -= size; |
| 126 } | 129 } |
| 127 | 130 |
| 128 fResources.remove(resource); | 131 fResources.remove(resource); |
| 129 if (resource->cacheAccess().getScratchKey().isValid()) { | 132 if (resource->cacheAccess().getScratchKey().isValid()) { |
| 130 fScratchMap.remove(resource->cacheAccess().getScratchKey(), resource); | 133 fScratchMap.remove(resource->cacheAccess().getScratchKey(), resource); |
| 131 } | 134 } |
| 132 if (const GrResourceKey* contentKey = resource->cacheAccess().getContentKey(
)) { | 135 if (resource->cacheAccess().getContentKey().isValid()) { |
| 133 fContentHash.remove(*contentKey); | 136 fContentHash.remove(resource->cacheAccess().getContentKey()); |
| 134 } | 137 } |
| 135 this->validate(); | 138 this->validate(); |
| 136 } | 139 } |
| 137 | 140 |
| 138 void GrResourceCache2::abandonAll() { | 141 void GrResourceCache2::abandonAll() { |
| 139 AutoValidate av(this); | 142 AutoValidate av(this); |
| 140 | 143 |
| 141 SkASSERT(!fPurging); | 144 SkASSERT(!fPurging); |
| 142 while (GrGpuResource* head = fResources.head()) { | 145 while (GrGpuResource* head = fResources.head()) { |
| 143 SkASSERT(!head->wasDestroyed()); | 146 SkASSERT(!head->wasDestroyed()); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 | 218 |
| 216 void GrResourceCache2::willRemoveScratchKey(const GrGpuResource* resource) { | 219 void GrResourceCache2::willRemoveScratchKey(const GrGpuResource* resource) { |
| 217 SkASSERT(resource->cacheAccess().isScratch()); | 220 SkASSERT(resource->cacheAccess().isScratch()); |
| 218 fScratchMap.remove(resource->cacheAccess().getScratchKey(), resource); | 221 fScratchMap.remove(resource->cacheAccess().getScratchKey(), resource); |
| 219 } | 222 } |
| 220 | 223 |
| 221 bool GrResourceCache2::didSetContentKey(GrGpuResource* resource) { | 224 bool GrResourceCache2::didSetContentKey(GrGpuResource* resource) { |
| 222 SkASSERT(!fPurging); | 225 SkASSERT(!fPurging); |
| 223 SkASSERT(resource); | 226 SkASSERT(resource); |
| 224 SkASSERT(this->isInCache(resource)); | 227 SkASSERT(this->isInCache(resource)); |
| 225 SkASSERT(resource->cacheAccess().getContentKey()); | 228 SkASSERT(resource->cacheAccess().getContentKey().isValid()); |
| 226 | 229 |
| 227 GrGpuResource* res = fContentHash.find(*resource->cacheAccess().getContentKe
y()); | 230 GrGpuResource* res = fContentHash.find(resource->cacheAccess().getContentKey
()); |
| 228 if (NULL != res) { | 231 if (NULL != res) { |
| 229 return false; | 232 return false; |
| 230 } | 233 } |
| 231 | 234 |
| 232 fContentHash.add(resource); | 235 fContentHash.add(resource); |
| 233 this->validate(); | 236 this->validate(); |
| 234 return true; | 237 return true; |
| 235 } | 238 } |
| 236 | 239 |
| 237 void GrResourceCache2::makeResourceMRU(GrGpuResource* resource) { | 240 void GrResourceCache2::makeResourceMRU(GrGpuResource* resource) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 251 // that additional resources became purgable. | 254 // that additional resources became purgable. |
| 252 if (fPurging) { | 255 if (fPurging) { |
| 253 fNewlyPurgableResourceWhilePurging = true; | 256 fNewlyPurgableResourceWhilePurging = true; |
| 254 return; | 257 return; |
| 255 } | 258 } |
| 256 | 259 |
| 257 // Purge the resource if we're over budget | 260 // Purge the resource if we're over budget |
| 258 bool overBudget = fBudgetedCount > fMaxCount || fBudgetedBytes > fMaxBytes; | 261 bool overBudget = fBudgetedCount > fMaxCount || fBudgetedBytes > fMaxBytes; |
| 259 | 262 |
| 260 // Also purge if the resource has neither a valid scratch key nor a content
key. | 263 // Also purge if the resource has neither a valid scratch key nor a content
key. |
| 261 bool noKey = !resource->cacheAccess().isScratch() && | 264 bool noKey = !resource->cacheAccess().getScratchKey().isValid() && |
| 262 (NULL == resource->cacheAccess().getContentKey()); | 265 !resource->cacheAccess().getContentKey().isValid(); |
| 263 | 266 |
| 264 // Only cached resources should ever have a key. | 267 // Only cached resources should ever have a key. |
| 265 SkASSERT(noKey || resource->cacheAccess().isBudgeted()); | 268 SkASSERT(noKey || resource->cacheAccess().isBudgeted()); |
| 266 | 269 |
| 267 if (overBudget || noKey) { | 270 if (overBudget || noKey) { |
| 268 SkDEBUGCODE(int beforeCount = fCount;) | 271 SkDEBUGCODE(int beforeCount = fCount;) |
| 269 resource->cacheAccess().release(); | 272 resource->cacheAccess().release(); |
| 270 // We should at least free this resource, perhaps dependent resources as
well. | 273 // We should at least free this resource, perhaps dependent resources as
well. |
| 271 SkASSERT(fCount < beforeCount); | 274 SkASSERT(fCount < beforeCount); |
| 272 } | 275 } |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 GrGpuResource* resource = iter.init(fResources, ResourceList::Iter::kHead_It
erStart); | 402 GrGpuResource* resource = iter.init(fResources, ResourceList::Iter::kHead_It
erStart); |
| 400 for ( ; resource; resource = iter.next()) { | 403 for ( ; resource; resource = iter.next()) { |
| 401 bytes += resource->gpuMemorySize(); | 404 bytes += resource->gpuMemorySize(); |
| 402 ++count; | 405 ++count; |
| 403 | 406 |
| 404 if (!resource->isPurgable()) { | 407 if (!resource->isPurgable()) { |
| 405 ++locked; | 408 ++locked; |
| 406 } | 409 } |
| 407 | 410 |
| 408 if (resource->cacheAccess().isScratch()) { | 411 if (resource->cacheAccess().isScratch()) { |
| 409 SkASSERT(NULL == resource->cacheAccess().getContentKey()); | 412 SkASSERT(!resource->cacheAccess().getContentKey().isValid()); |
| 410 ++scratch; | 413 ++scratch; |
| 411 SkASSERT(fScratchMap.countForKey(resource->cacheAccess().getScratchK
ey())); | 414 SkASSERT(fScratchMap.countForKey(resource->cacheAccess().getScratchK
ey())); |
| 412 SkASSERT(!resource->cacheAccess().isWrapped()); | 415 SkASSERT(!resource->cacheAccess().isWrapped()); |
| 413 } else if (resource->cacheAccess().getScratchKey().isValid()) { | 416 } else if (resource->cacheAccess().getScratchKey().isValid()) { |
| 414 SkASSERT(NULL != resource->cacheAccess().getContentKey()); | 417 SkASSERT(resource->cacheAccess().getContentKey().isValid()); |
| 415 ++couldBeScratch; | 418 ++couldBeScratch; |
| 416 SkASSERT(fScratchMap.countForKey(resource->cacheAccess().getScratchK
ey())); | 419 SkASSERT(fScratchMap.countForKey(resource->cacheAccess().getScratchK
ey())); |
| 417 SkASSERT(!resource->cacheAccess().isWrapped()); | 420 SkASSERT(!resource->cacheAccess().isWrapped()); |
| 418 } | 421 } |
| 419 | 422 const GrContentKey& contentKey = resource->cacheAccess().getContentKey()
; |
| 420 if (const GrResourceKey* contentKey = resource->cacheAccess().getContent
Key()) { | 423 if (contentKey.isValid()) { |
| 421 ++content; | 424 ++content; |
| 422 SkASSERT(fContentHash.find(*contentKey) == resource); | 425 SkASSERT(fContentHash.find(contentKey) == resource); |
| 423 SkASSERT(!resource->cacheAccess().isWrapped()); | 426 SkASSERT(!resource->cacheAccess().isWrapped()); |
| 424 } | 427 } |
| 425 | 428 |
| 426 if (resource->cacheAccess().isBudgeted()) { | 429 if (resource->cacheAccess().isBudgeted()) { |
| 427 ++budgetedCount; | 430 ++budgetedCount; |
| 428 budgetedBytes += resource->gpuMemorySize(); | 431 budgetedBytes += resource->gpuMemorySize(); |
| 429 } | 432 } |
| 430 } | 433 } |
| 431 | 434 |
| 432 SkASSERT(fBudgetedCount <= fCount); | 435 SkASSERT(fBudgetedCount <= fCount); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 | 488 |
| 486 SkDebugf("Budget: %d items %d bytes\n", fMaxCount, fMaxBytes); | 489 SkDebugf("Budget: %d items %d bytes\n", fMaxCount, fMaxBytes); |
| 487 SkDebugf("\t\tEntry Count: current %d" | 490 SkDebugf("\t\tEntry Count: current %d" |
| 488 " (%d budgeted, %d wrapped, %d locked, %d scratch %.2g%% full), hig
h %d\n", | 491 " (%d budgeted, %d wrapped, %d locked, %d scratch %.2g%% full), hig
h %d\n", |
| 489 fCount, fBudgetedCount, wrapped, locked, scratch, countUtilization, fHig
hWaterCount); | 492 fCount, fBudgetedCount, wrapped, locked, scratch, countUtilization, fHig
hWaterCount); |
| 490 SkDebugf("\t\tEntry Bytes: current %d (budgeted %d, %.2g%% full, %d unbudget
ed) high %d\n", | 493 SkDebugf("\t\tEntry Bytes: current %d (budgeted %d, %.2g%% full, %d unbudget
ed) high %d\n", |
| 491 fBytes, fBudgetedBytes, byteUtilization, unbudgetedSize, fHighWa
terBytes); | 494 fBytes, fBudgetedBytes, byteUtilization, unbudgetedSize, fHighWa
terBytes); |
| 492 } | 495 } |
| 493 | 496 |
| 494 #endif | 497 #endif |
| OLD | NEW |