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 "SkGr.h" | 14 #include "SkGr.h" |
14 #include "SkMessageBus.h" | 15 #include "SkMessageBus.h" |
15 | 16 |
16 DECLARE_SKMESSAGEBUS_MESSAGE(GrResourceInvalidatedMessage); | 17 DECLARE_SKMESSAGEBUS_MESSAGE(GrResourceInvalidatedMessage); |
17 | 18 |
18 ////////////////////////////////////////////////////////////////////////////// | 19 ////////////////////////////////////////////////////////////////////////////// |
19 | 20 |
20 GrResourceKey& GrResourceKey::NullScratchKey() { | 21 GrScratchKey::ResourceType GrScratchKey::GenerateResourceType() { |
21 static const GrCacheID::Key kBogusKey = { { {0} } }; | 22 static int32_t gType = kInvalidResourceType + 1; |
22 static GrCacheID kBogusID(ScratchDomain(), kBogusKey); | |
23 static GrResourceKey kNullScratchKey(kBogusID, NoneResourceType(), 0); | |
24 return kNullScratchKey; | |
25 } | |
26 | 23 |
27 GrResourceKey::ResourceType GrResourceKey::NoneResourceType() { | 24 int32_t type = sk_atomic_inc(&gType); |
28 static const ResourceType gNoneResourceType = GenerateResourceType(); | 25 if (kInvalidResourceType == type) { |
29 return gNoneResourceType; | |
30 } | |
31 | |
32 GrCacheID::Domain GrResourceKey::ScratchDomain() { | |
33 static const GrCacheID::Domain gDomain = GrCacheID::GenerateDomain(); | |
34 return gDomain; | |
35 } | |
36 | |
37 GrResourceKey::ResourceType GrResourceKey::GenerateResourceType() { | |
38 static int32_t gNextType = 0; | |
39 | |
40 int32_t type = sk_atomic_inc(&gNextType); | |
41 if (type >= (1 << 8 * sizeof(ResourceType))) { | |
42 SkFAIL("Too many Resource Types"); | 26 SkFAIL("Too many Resource Types"); |
43 } | 27 } |
44 | 28 |
45 return static_cast<ResourceType>(type); | 29 return static_cast<ResourceType>(type); |
46 } | 30 } |
47 | 31 |
| 32 |
| 33 void GrScratchKey::Builder::finish() { |
| 34 if (NULL == fKey) { |
| 35 return; |
| 36 } |
| 37 GR_STATIC_ASSERT(0 == kHash_MetaDataIdx); |
| 38 fKey->fKey[kHash_MetaDataIdx] = |
| 39 SkChecksum::Compute(&fKey->fKey[kHash_MetaDataIdx + 1], fKey->size() - s
izeof(uint32_t)); |
| 40 fKey = NULL; |
| 41 } |
| 42 |
48 ////////////////////////////////////////////////////////////////////////////// | 43 ////////////////////////////////////////////////////////////////////////////// |
49 | 44 |
50 class GrResourceCache2::AutoValidate : ::SkNoncopyable { | 45 class GrResourceCache2::AutoValidate : ::SkNoncopyable { |
51 public: | 46 public: |
52 AutoValidate(GrResourceCache2* cache) : fCache(cache) { cache->validate(); } | 47 AutoValidate(GrResourceCache2* cache) : fCache(cache) { cache->validate(); } |
53 ~AutoValidate() { fCache->validate(); } | 48 ~AutoValidate() { fCache->validate(); } |
54 private: | 49 private: |
55 GrResourceCache2* fCache; | 50 GrResourceCache2* fCache; |
56 }; | 51 }; |
57 | 52 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 fHighWaterBytes = SkTMax(fBytes, fHighWaterBytes); | 99 fHighWaterBytes = SkTMax(fBytes, fHighWaterBytes); |
105 #endif | 100 #endif |
106 if (resource->cacheAccess().isBudgeted()) { | 101 if (resource->cacheAccess().isBudgeted()) { |
107 ++fBudgetedCount; | 102 ++fBudgetedCount; |
108 fBudgetedBytes += size; | 103 fBudgetedBytes += size; |
109 #if GR_CACHE_STATS | 104 #if GR_CACHE_STATS |
110 fBudgetedHighWaterCount = SkTMax(fBudgetedCount, fBudgetedHighWaterCount
); | 105 fBudgetedHighWaterCount = SkTMax(fBudgetedCount, fBudgetedHighWaterCount
); |
111 fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes
); | 106 fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes
); |
112 #endif | 107 #endif |
113 } | 108 } |
114 if (!resource->cacheAccess().getScratchKey().isNullScratch()) { | 109 if (resource->cacheAccess().getScratchKey().isValid()) { |
115 SkASSERT(!resource->cacheAccess().isWrapped()); | 110 SkASSERT(!resource->cacheAccess().isWrapped()); |
116 fScratchMap.insert(resource->cacheAccess().getScratchKey(), resource); | 111 fScratchMap.insert(resource->cacheAccess().getScratchKey(), resource); |
117 } | 112 } |
118 | 113 |
119 this->purgeAsNeeded(); | 114 this->purgeAsNeeded(); |
120 } | 115 } |
121 | 116 |
122 void GrResourceCache2::removeResource(GrGpuResource* resource) { | 117 void GrResourceCache2::removeResource(GrGpuResource* resource) { |
123 SkASSERT(this->isInCache(resource)); | 118 SkASSERT(this->isInCache(resource)); |
124 | 119 |
125 size_t size = resource->gpuMemorySize(); | 120 size_t size = resource->gpuMemorySize(); |
126 --fCount; | 121 --fCount; |
127 fBytes -= size; | 122 fBytes -= size; |
128 if (resource->cacheAccess().isBudgeted()) { | 123 if (resource->cacheAccess().isBudgeted()) { |
129 --fBudgetedCount; | 124 --fBudgetedCount; |
130 fBudgetedBytes -= size; | 125 fBudgetedBytes -= size; |
131 } | 126 } |
132 | 127 |
133 fResources.remove(resource); | 128 fResources.remove(resource); |
134 if (!resource->cacheAccess().getScratchKey().isNullScratch()) { | 129 if (resource->cacheAccess().getScratchKey().isValid()) { |
135 fScratchMap.remove(resource->cacheAccess().getScratchKey(), resource); | 130 fScratchMap.remove(resource->cacheAccess().getScratchKey(), resource); |
136 } | 131 } |
137 if (const GrResourceKey* contentKey = resource->cacheAccess().getContentKey(
)) { | 132 if (const GrResourceKey* contentKey = resource->cacheAccess().getContentKey(
)) { |
138 fContentHash.remove(*contentKey); | 133 fContentHash.remove(*contentKey); |
139 } | 134 } |
140 this->validate(); | 135 this->validate(); |
141 } | 136 } |
142 | 137 |
143 void GrResourceCache2::abandonAll() { | 138 void GrResourceCache2::abandonAll() { |
144 AutoValidate av(this); | 139 AutoValidate av(this); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 if (resource->internalHasRef() || !resource->cacheAccess().isScratch())
{ | 178 if (resource->internalHasRef() || !resource->cacheAccess().isScratch())
{ |
184 return false; | 179 return false; |
185 } | 180 } |
186 return !fRejectPendingIO || !resource->internalHasPendingIO(); | 181 return !fRejectPendingIO || !resource->internalHasPendingIO(); |
187 } | 182 } |
188 | 183 |
189 private: | 184 private: |
190 bool fRejectPendingIO; | 185 bool fRejectPendingIO; |
191 }; | 186 }; |
192 | 187 |
193 GrGpuResource* GrResourceCache2::findAndRefScratchResource(const GrResourceKey&
scratchKey, | 188 GrGpuResource* GrResourceCache2::findAndRefScratchResource(const GrScratchKey& s
cratchKey, |
194 uint32_t flags) { | 189 uint32_t flags) { |
195 SkASSERT(!fPurging); | 190 SkASSERT(!fPurging); |
196 SkASSERT(scratchKey.isScratch()); | 191 SkASSERT(scratchKey.isValid()); |
197 | 192 |
198 GrGpuResource* resource; | 193 GrGpuResource* resource; |
199 if (flags & (kPreferNoPendingIO_ScratchFlag | kRequireNoPendingIO_ScratchFla
g)) { | 194 if (flags & (kPreferNoPendingIO_ScratchFlag | kRequireNoPendingIO_ScratchFla
g)) { |
200 resource = fScratchMap.find(scratchKey, AvailableForScratchUse(true)); | 195 resource = fScratchMap.find(scratchKey, AvailableForScratchUse(true)); |
201 if (resource) { | 196 if (resource) { |
202 resource->ref(); | 197 resource->ref(); |
203 this->makeResourceMRU(resource); | 198 this->makeResourceMRU(resource); |
204 this->validate(); | 199 this->validate(); |
205 return resource; | 200 return resource; |
206 } else if (flags & kRequireNoPendingIO_ScratchFlag) { | 201 } else if (flags & kRequireNoPendingIO_ScratchFlag) { |
(...skipping 14 matching lines...) Expand all Loading... |
221 void GrResourceCache2::willRemoveScratchKey(const GrGpuResource* resource) { | 216 void GrResourceCache2::willRemoveScratchKey(const GrGpuResource* resource) { |
222 SkASSERT(resource->cacheAccess().isScratch()); | 217 SkASSERT(resource->cacheAccess().isScratch()); |
223 fScratchMap.remove(resource->cacheAccess().getScratchKey(), resource); | 218 fScratchMap.remove(resource->cacheAccess().getScratchKey(), resource); |
224 } | 219 } |
225 | 220 |
226 bool GrResourceCache2::didSetContentKey(GrGpuResource* resource) { | 221 bool GrResourceCache2::didSetContentKey(GrGpuResource* resource) { |
227 SkASSERT(!fPurging); | 222 SkASSERT(!fPurging); |
228 SkASSERT(resource); | 223 SkASSERT(resource); |
229 SkASSERT(this->isInCache(resource)); | 224 SkASSERT(this->isInCache(resource)); |
230 SkASSERT(resource->cacheAccess().getContentKey()); | 225 SkASSERT(resource->cacheAccess().getContentKey()); |
231 SkASSERT(!resource->cacheAccess().getContentKey()->isScratch()); | |
232 | 226 |
233 GrGpuResource* res = fContentHash.find(*resource->cacheAccess().getContentKe
y()); | 227 GrGpuResource* res = fContentHash.find(*resource->cacheAccess().getContentKe
y()); |
234 if (NULL != res) { | 228 if (NULL != res) { |
235 return false; | 229 return false; |
236 } | 230 } |
237 | 231 |
238 fContentHash.add(resource); | 232 fContentHash.add(resource); |
239 this->validate(); | 233 this->validate(); |
240 return true; | 234 return true; |
241 } | 235 } |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
407 | 401 |
408 if (!resource->isPurgable()) { | 402 if (!resource->isPurgable()) { |
409 ++locked; | 403 ++locked; |
410 } | 404 } |
411 | 405 |
412 if (resource->cacheAccess().isScratch()) { | 406 if (resource->cacheAccess().isScratch()) { |
413 SkASSERT(NULL == resource->cacheAccess().getContentKey()); | 407 SkASSERT(NULL == resource->cacheAccess().getContentKey()); |
414 ++scratch; | 408 ++scratch; |
415 SkASSERT(fScratchMap.countForKey(resource->cacheAccess().getScratchK
ey())); | 409 SkASSERT(fScratchMap.countForKey(resource->cacheAccess().getScratchK
ey())); |
416 SkASSERT(!resource->cacheAccess().isWrapped()); | 410 SkASSERT(!resource->cacheAccess().isWrapped()); |
417 } else if (!resource->cacheAccess().getScratchKey().isNullScratch()) { | 411 } else if (resource->cacheAccess().getScratchKey().isValid()) { |
418 SkASSERT(NULL != resource->cacheAccess().getContentKey()); | 412 SkASSERT(NULL != resource->cacheAccess().getContentKey()); |
419 ++couldBeScratch; | 413 ++couldBeScratch; |
420 SkASSERT(fScratchMap.countForKey(resource->cacheAccess().getScratchK
ey())); | 414 SkASSERT(fScratchMap.countForKey(resource->cacheAccess().getScratchK
ey())); |
421 SkASSERT(!resource->cacheAccess().isWrapped()); | 415 SkASSERT(!resource->cacheAccess().isWrapped()); |
422 } | 416 } |
423 | 417 |
424 if (const GrResourceKey* contentKey = resource->cacheAccess().getContent
Key()) { | 418 if (const GrResourceKey* contentKey = resource->cacheAccess().getContent
Key()) { |
425 ++content; | 419 ++content; |
426 SkASSERT(fContentHash.find(*contentKey) == resource); | 420 SkASSERT(fContentHash.find(*contentKey) == resource); |
427 SkASSERT(!resource->cacheAccess().isWrapped()); | 421 SkASSERT(!resource->cacheAccess().isWrapped()); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 | 483 |
490 SkDebugf("Budget: %d items %d bytes\n", fMaxCount, fMaxBytes); | 484 SkDebugf("Budget: %d items %d bytes\n", fMaxCount, fMaxBytes); |
491 SkDebugf("\t\tEntry Count: current %d" | 485 SkDebugf("\t\tEntry Count: current %d" |
492 " (%d budgeted, %d wrapped, %d locked, %d scratch %.2g%% full), hig
h %d\n", | 486 " (%d budgeted, %d wrapped, %d locked, %d scratch %.2g%% full), hig
h %d\n", |
493 fCount, fBudgetedCount, wrapped, locked, scratch, countUtilization, fHig
hWaterCount); | 487 fCount, fBudgetedCount, wrapped, locked, scratch, countUtilization, fHig
hWaterCount); |
494 SkDebugf("\t\tEntry Bytes: current %d (budgeted %d, %.2g%% full, %d unbudget
ed) high %d\n", | 488 SkDebugf("\t\tEntry Bytes: current %d (budgeted %d, %.2g%% full, %d unbudget
ed) high %d\n", |
495 fBytes, fBudgetedBytes, byteUtilization, unbudgetedSize, fHighWa
terBytes); | 489 fBytes, fBudgetedBytes, byteUtilization, unbudgetedSize, fHighWa
terBytes); |
496 } | 490 } |
497 | 491 |
498 #endif | 492 #endif |
OLD | NEW |