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 "GrResourceCache.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(GrContentKeyInvalidatedMessage); | 17 DECLARE_SKMESSAGEBUS_MESSAGE(GrContentKeyInvalidatedMessage); |
18 | 18 |
19 ////////////////////////////////////////////////////////////////////////////// | 19 ////////////////////////////////////////////////////////////////////////////// |
20 | 20 |
(...skipping 17 matching lines...) Expand all Loading... |
38 } | 38 } |
39 | 39 |
40 return static_cast<Domain>(domain); | 40 return static_cast<Domain>(domain); |
41 } | 41 } |
42 uint32_t GrResourceKeyHash(const uint32_t* data, size_t size) { | 42 uint32_t GrResourceKeyHash(const uint32_t* data, size_t size) { |
43 return SkChecksum::Compute(data, size); | 43 return SkChecksum::Compute(data, size); |
44 } | 44 } |
45 | 45 |
46 ////////////////////////////////////////////////////////////////////////////// | 46 ////////////////////////////////////////////////////////////////////////////// |
47 | 47 |
48 class GrResourceCache2::AutoValidate : ::SkNoncopyable { | 48 class GrResourceCache::AutoValidate : ::SkNoncopyable { |
49 public: | 49 public: |
50 AutoValidate(GrResourceCache2* cache) : fCache(cache) { cache->validate(); } | 50 AutoValidate(GrResourceCache* cache) : fCache(cache) { cache->validate(); } |
51 ~AutoValidate() { fCache->validate(); } | 51 ~AutoValidate() { fCache->validate(); } |
52 private: | 52 private: |
53 GrResourceCache2* fCache; | 53 GrResourceCache* fCache; |
54 }; | 54 }; |
55 | 55 |
56 ////////////////////////////////////////////////////////////////////////////// | 56 ////////////////////////////////////////////////////////////////////////////// |
57 | 57 |
58 static const int kDefaultMaxCount = 2 * (1 << 10); | 58 static const int kDefaultMaxCount = 2 * (1 << 10); |
59 static const size_t kDefaultMaxSize = 96 * (1 << 20); | 59 static const size_t kDefaultMaxSize = 96 * (1 << 20); |
60 | 60 |
61 GrResourceCache2::GrResourceCache2() | 61 GrResourceCache::GrResourceCache() |
62 : fMaxCount(kDefaultMaxCount) | 62 : fMaxCount(kDefaultMaxCount) |
63 , fMaxBytes(kDefaultMaxSize) | 63 , fMaxBytes(kDefaultMaxSize) |
64 #if GR_CACHE_STATS | 64 #if GR_CACHE_STATS |
65 , fHighWaterCount(0) | 65 , fHighWaterCount(0) |
66 , fHighWaterBytes(0) | 66 , fHighWaterBytes(0) |
67 , fBudgetedHighWaterCount(0) | 67 , fBudgetedHighWaterCount(0) |
68 , fBudgetedHighWaterBytes(0) | 68 , fBudgetedHighWaterBytes(0) |
69 #endif | 69 #endif |
70 , fCount(0) | 70 , fCount(0) |
71 , fBytes(0) | 71 , fBytes(0) |
72 , fBudgetedCount(0) | 72 , fBudgetedCount(0) |
73 , fBudgetedBytes(0) | 73 , fBudgetedBytes(0) |
74 , fPurging(false) | 74 , fPurging(false) |
75 , fNewlyPurgeableResourceWhilePurging(false) | 75 , fNewlyPurgeableResourceWhilePurging(false) |
76 , fOverBudgetCB(NULL) | 76 , fOverBudgetCB(NULL) |
77 , fOverBudgetData(NULL) { | 77 , fOverBudgetData(NULL) { |
78 } | 78 } |
79 | 79 |
80 GrResourceCache2::~GrResourceCache2() { | 80 GrResourceCache::~GrResourceCache() { |
81 this->releaseAll(); | 81 this->releaseAll(); |
82 } | 82 } |
83 | 83 |
84 void GrResourceCache2::setLimits(int count, size_t bytes) { | 84 void GrResourceCache::setLimits(int count, size_t bytes) { |
85 fMaxCount = count; | 85 fMaxCount = count; |
86 fMaxBytes = bytes; | 86 fMaxBytes = bytes; |
87 this->purgeAsNeeded(); | 87 this->purgeAsNeeded(); |
88 } | 88 } |
89 | 89 |
90 void GrResourceCache2::insertResource(GrGpuResource* resource) { | 90 void GrResourceCache::insertResource(GrGpuResource* resource) { |
91 SkASSERT(resource); | 91 SkASSERT(resource); |
92 SkASSERT(!resource->wasDestroyed()); | 92 SkASSERT(!resource->wasDestroyed()); |
93 SkASSERT(!this->isInCache(resource)); | 93 SkASSERT(!this->isInCache(resource)); |
94 SkASSERT(!fPurging); | 94 SkASSERT(!fPurging); |
95 fResources.addToHead(resource); | 95 fResources.addToHead(resource); |
96 | 96 |
97 size_t size = resource->gpuMemorySize(); | 97 size_t size = resource->gpuMemorySize(); |
98 ++fCount; | 98 ++fCount; |
99 fBytes += size; | 99 fBytes += size; |
100 #if GR_CACHE_STATS | 100 #if GR_CACHE_STATS |
101 fHighWaterCount = SkTMax(fCount, fHighWaterCount); | 101 fHighWaterCount = SkTMax(fCount, fHighWaterCount); |
102 fHighWaterBytes = SkTMax(fBytes, fHighWaterBytes); | 102 fHighWaterBytes = SkTMax(fBytes, fHighWaterBytes); |
103 #endif | 103 #endif |
104 if (resource->cacheAccess().isBudgeted()) { | 104 if (resource->cacheAccess().isBudgeted()) { |
105 ++fBudgetedCount; | 105 ++fBudgetedCount; |
106 fBudgetedBytes += size; | 106 fBudgetedBytes += size; |
107 #if GR_CACHE_STATS | 107 #if GR_CACHE_STATS |
108 fBudgetedHighWaterCount = SkTMax(fBudgetedCount, fBudgetedHighWaterCount
); | 108 fBudgetedHighWaterCount = SkTMax(fBudgetedCount, fBudgetedHighWaterCount
); |
109 fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes
); | 109 fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes
); |
110 #endif | 110 #endif |
111 } | 111 } |
112 if (resource->cacheAccess().getScratchKey().isValid()) { | 112 if (resource->cacheAccess().getScratchKey().isValid()) { |
113 SkASSERT(!resource->cacheAccess().isWrapped()); | 113 SkASSERT(!resource->cacheAccess().isWrapped()); |
114 fScratchMap.insert(resource->cacheAccess().getScratchKey(), resource); | 114 fScratchMap.insert(resource->cacheAccess().getScratchKey(), resource); |
115 } | 115 } |
116 | 116 |
117 this->purgeAsNeeded(); | 117 this->purgeAsNeeded(); |
118 } | 118 } |
119 | 119 |
120 void GrResourceCache2::removeResource(GrGpuResource* resource) { | 120 void GrResourceCache::removeResource(GrGpuResource* resource) { |
121 SkASSERT(this->isInCache(resource)); | 121 SkASSERT(this->isInCache(resource)); |
122 | 122 |
123 size_t size = resource->gpuMemorySize(); | 123 size_t size = resource->gpuMemorySize(); |
124 --fCount; | 124 --fCount; |
125 fBytes -= size; | 125 fBytes -= size; |
126 if (resource->cacheAccess().isBudgeted()) { | 126 if (resource->cacheAccess().isBudgeted()) { |
127 --fBudgetedCount; | 127 --fBudgetedCount; |
128 fBudgetedBytes -= size; | 128 fBudgetedBytes -= size; |
129 } | 129 } |
130 | 130 |
131 fResources.remove(resource); | 131 fResources.remove(resource); |
132 if (resource->cacheAccess().getScratchKey().isValid()) { | 132 if (resource->cacheAccess().getScratchKey().isValid()) { |
133 fScratchMap.remove(resource->cacheAccess().getScratchKey(), resource); | 133 fScratchMap.remove(resource->cacheAccess().getScratchKey(), resource); |
134 } | 134 } |
135 if (resource->getContentKey().isValid()) { | 135 if (resource->getContentKey().isValid()) { |
136 fContentHash.remove(resource->getContentKey()); | 136 fContentHash.remove(resource->getContentKey()); |
137 } | 137 } |
138 this->validate(); | 138 this->validate(); |
139 } | 139 } |
140 | 140 |
141 void GrResourceCache2::abandonAll() { | 141 void GrResourceCache::abandonAll() { |
142 AutoValidate av(this); | 142 AutoValidate av(this); |
143 | 143 |
144 SkASSERT(!fPurging); | 144 SkASSERT(!fPurging); |
145 while (GrGpuResource* head = fResources.head()) { | 145 while (GrGpuResource* head = fResources.head()) { |
146 SkASSERT(!head->wasDestroyed()); | 146 SkASSERT(!head->wasDestroyed()); |
147 head->cacheAccess().abandon(); | 147 head->cacheAccess().abandon(); |
148 // abandon should have already removed this from the list. | 148 // abandon should have already removed this from the list. |
149 SkASSERT(head != fResources.head()); | 149 SkASSERT(head != fResources.head()); |
150 } | 150 } |
151 SkASSERT(!fScratchMap.count()); | 151 SkASSERT(!fScratchMap.count()); |
152 SkASSERT(!fContentHash.count()); | 152 SkASSERT(!fContentHash.count()); |
153 SkASSERT(!fCount); | 153 SkASSERT(!fCount); |
154 SkASSERT(!fBytes); | 154 SkASSERT(!fBytes); |
155 SkASSERT(!fBudgetedCount); | 155 SkASSERT(!fBudgetedCount); |
156 SkASSERT(!fBudgetedBytes); | 156 SkASSERT(!fBudgetedBytes); |
157 } | 157 } |
158 | 158 |
159 void GrResourceCache2::releaseAll() { | 159 void GrResourceCache::releaseAll() { |
160 AutoValidate av(this); | 160 AutoValidate av(this); |
161 | 161 |
162 SkASSERT(!fPurging); | 162 SkASSERT(!fPurging); |
163 while (GrGpuResource* head = fResources.head()) { | 163 while (GrGpuResource* head = fResources.head()) { |
164 SkASSERT(!head->wasDestroyed()); | 164 SkASSERT(!head->wasDestroyed()); |
165 head->cacheAccess().release(); | 165 head->cacheAccess().release(); |
166 // release should have already removed this from the list. | 166 // release should have already removed this from the list. |
167 SkASSERT(head != fResources.head()); | 167 SkASSERT(head != fResources.head()); |
168 } | 168 } |
169 SkASSERT(!fScratchMap.count()); | 169 SkASSERT(!fScratchMap.count()); |
170 SkASSERT(!fCount); | 170 SkASSERT(!fCount); |
171 SkASSERT(!fBytes); | 171 SkASSERT(!fBytes); |
172 SkASSERT(!fBudgetedCount); | 172 SkASSERT(!fBudgetedCount); |
173 SkASSERT(!fBudgetedBytes); | 173 SkASSERT(!fBudgetedBytes); |
174 } | 174 } |
175 | 175 |
176 class GrResourceCache2::AvailableForScratchUse { | 176 class GrResourceCache::AvailableForScratchUse { |
177 public: | 177 public: |
178 AvailableForScratchUse(bool rejectPendingIO) : fRejectPendingIO(rejectPendin
gIO) { } | 178 AvailableForScratchUse(bool rejectPendingIO) : fRejectPendingIO(rejectPendin
gIO) { } |
179 | 179 |
180 bool operator()(const GrGpuResource* resource) const { | 180 bool operator()(const GrGpuResource* resource) const { |
181 if (resource->internalHasRef() || !resource->cacheAccess().isScratch())
{ | 181 if (resource->internalHasRef() || !resource->cacheAccess().isScratch())
{ |
182 return false; | 182 return false; |
183 } | 183 } |
184 return !fRejectPendingIO || !resource->internalHasPendingIO(); | 184 return !fRejectPendingIO || !resource->internalHasPendingIO(); |
185 } | 185 } |
186 | 186 |
187 private: | 187 private: |
188 bool fRejectPendingIO; | 188 bool fRejectPendingIO; |
189 }; | 189 }; |
190 | 190 |
191 GrGpuResource* GrResourceCache2::findAndRefScratchResource(const GrScratchKey& s
cratchKey, | 191 GrGpuResource* GrResourceCache::findAndRefScratchResource(const GrScratchKey& sc
ratchKey, |
192 uint32_t flags) { | 192 uint32_t flags) { |
193 SkASSERT(!fPurging); | 193 SkASSERT(!fPurging); |
194 SkASSERT(scratchKey.isValid()); | 194 SkASSERT(scratchKey.isValid()); |
195 | 195 |
196 GrGpuResource* resource; | 196 GrGpuResource* resource; |
197 if (flags & (kPreferNoPendingIO_ScratchFlag | kRequireNoPendingIO_ScratchFla
g)) { | 197 if (flags & (kPreferNoPendingIO_ScratchFlag | kRequireNoPendingIO_ScratchFla
g)) { |
198 resource = fScratchMap.find(scratchKey, AvailableForScratchUse(true)); | 198 resource = fScratchMap.find(scratchKey, AvailableForScratchUse(true)); |
199 if (resource) { | 199 if (resource) { |
200 resource->ref(); | 200 resource->ref(); |
201 this->makeResourceMRU(resource); | 201 this->makeResourceMRU(resource); |
202 this->validate(); | 202 this->validate(); |
203 return resource; | 203 return resource; |
204 } else if (flags & kRequireNoPendingIO_ScratchFlag) { | 204 } else if (flags & kRequireNoPendingIO_ScratchFlag) { |
205 return NULL; | 205 return NULL; |
206 } | 206 } |
207 // TODO: fail here when kPrefer is specified, we didn't find a resource
without pending io, | 207 // TODO: fail here when kPrefer is specified, we didn't find a resource
without pending io, |
208 // but there is still space in our budget for the resource. | 208 // but there is still space in our budget for the resource. |
209 } | 209 } |
210 resource = fScratchMap.find(scratchKey, AvailableForScratchUse(false)); | 210 resource = fScratchMap.find(scratchKey, AvailableForScratchUse(false)); |
211 if (resource) { | 211 if (resource) { |
212 resource->ref(); | 212 resource->ref(); |
213 this->makeResourceMRU(resource); | 213 this->makeResourceMRU(resource); |
214 this->validate(); | 214 this->validate(); |
215 } | 215 } |
216 return resource; | 216 return resource; |
217 } | 217 } |
218 | 218 |
219 void GrResourceCache2::willRemoveScratchKey(const GrGpuResource* resource) { | 219 void GrResourceCache::willRemoveScratchKey(const GrGpuResource* resource) { |
220 SkASSERT(resource->cacheAccess().getScratchKey().isValid()); | 220 SkASSERT(resource->cacheAccess().getScratchKey().isValid()); |
221 fScratchMap.remove(resource->cacheAccess().getScratchKey(), resource); | 221 fScratchMap.remove(resource->cacheAccess().getScratchKey(), resource); |
222 } | 222 } |
223 | 223 |
224 void GrResourceCache2::willRemoveContentKey(const GrGpuResource* resource) { | 224 void GrResourceCache::willRemoveContentKey(const GrGpuResource* resource) { |
225 // Someone has a ref to this resource in order to invalidate it. When the re
f count reaches | 225 // Someone has a ref to this resource in order to invalidate it. When the re
f count reaches |
226 // zero we will get a notifyPurgable() and figure out what to do with it. | 226 // zero we will get a notifyPurgable() and figure out what to do with it. |
227 SkASSERT(resource->getContentKey().isValid()); | 227 SkASSERT(resource->getContentKey().isValid()); |
228 fContentHash.remove(resource->getContentKey()); | 228 fContentHash.remove(resource->getContentKey()); |
229 } | 229 } |
230 | 230 |
231 bool GrResourceCache2::didSetContentKey(GrGpuResource* resource) { | 231 bool GrResourceCache::didSetContentKey(GrGpuResource* resource) { |
232 SkASSERT(!fPurging); | 232 SkASSERT(!fPurging); |
233 SkASSERT(resource); | 233 SkASSERT(resource); |
234 SkASSERT(this->isInCache(resource)); | 234 SkASSERT(this->isInCache(resource)); |
235 SkASSERT(resource->getContentKey().isValid()); | 235 SkASSERT(resource->getContentKey().isValid()); |
236 | 236 |
237 GrGpuResource* res = fContentHash.find(resource->getContentKey()); | 237 GrGpuResource* res = fContentHash.find(resource->getContentKey()); |
238 if (NULL != res) { | 238 if (NULL != res) { |
239 return false; | 239 return false; |
240 } | 240 } |
241 | 241 |
242 fContentHash.add(resource); | 242 fContentHash.add(resource); |
243 this->validate(); | 243 this->validate(); |
244 return true; | 244 return true; |
245 } | 245 } |
246 | 246 |
247 void GrResourceCache2::makeResourceMRU(GrGpuResource* resource) { | 247 void GrResourceCache::makeResourceMRU(GrGpuResource* resource) { |
248 SkASSERT(!fPurging); | 248 SkASSERT(!fPurging); |
249 SkASSERT(resource); | 249 SkASSERT(resource); |
250 SkASSERT(this->isInCache(resource)); | 250 SkASSERT(this->isInCache(resource)); |
251 fResources.remove(resource); | 251 fResources.remove(resource); |
252 fResources.addToHead(resource); | 252 fResources.addToHead(resource); |
253 } | 253 } |
254 | 254 |
255 void GrResourceCache2::notifyPurgeable(GrGpuResource* resource) { | 255 void GrResourceCache::notifyPurgeable(GrGpuResource* resource) { |
256 SkASSERT(resource); | 256 SkASSERT(resource); |
257 SkASSERT(this->isInCache(resource)); | 257 SkASSERT(this->isInCache(resource)); |
258 SkASSERT(resource->isPurgeable()); | 258 SkASSERT(resource->isPurgeable()); |
259 | 259 |
260 // We can't purge if in the middle of purging because purge is iterating. In
stead record | 260 // We can't purge if in the middle of purging because purge is iterating. In
stead record |
261 // that additional resources became purgeable. | 261 // that additional resources became purgeable. |
262 if (fPurging) { | 262 if (fPurging) { |
263 fNewlyPurgeableResourceWhilePurging = true; | 263 fNewlyPurgeableResourceWhilePurging = true; |
264 return; | 264 return; |
265 } | 265 } |
(...skipping 30 matching lines...) Expand all Loading... |
296 | 296 |
297 if (release) { | 297 if (release) { |
298 SkDEBUGCODE(int beforeCount = fCount;) | 298 SkDEBUGCODE(int beforeCount = fCount;) |
299 resource->cacheAccess().release(); | 299 resource->cacheAccess().release(); |
300 // We should at least free this resource, perhaps dependent resources as
well. | 300 // We should at least free this resource, perhaps dependent resources as
well. |
301 SkASSERT(fCount < beforeCount); | 301 SkASSERT(fCount < beforeCount); |
302 } | 302 } |
303 this->validate(); | 303 this->validate(); |
304 } | 304 } |
305 | 305 |
306 void GrResourceCache2::didChangeGpuMemorySize(const GrGpuResource* resource, siz
e_t oldSize) { | 306 void GrResourceCache::didChangeGpuMemorySize(const GrGpuResource* resource, size
_t oldSize) { |
307 // SkASSERT(!fPurging); GrPathRange increases size during flush. :( | 307 // SkASSERT(!fPurging); GrPathRange increases size during flush. :( |
308 SkASSERT(resource); | 308 SkASSERT(resource); |
309 SkASSERT(this->isInCache(resource)); | 309 SkASSERT(this->isInCache(resource)); |
310 | 310 |
311 ptrdiff_t delta = resource->gpuMemorySize() - oldSize; | 311 ptrdiff_t delta = resource->gpuMemorySize() - oldSize; |
312 | 312 |
313 fBytes += delta; | 313 fBytes += delta; |
314 #if GR_CACHE_STATS | 314 #if GR_CACHE_STATS |
315 fHighWaterBytes = SkTMax(fBytes, fHighWaterBytes); | 315 fHighWaterBytes = SkTMax(fBytes, fHighWaterBytes); |
316 #endif | 316 #endif |
317 if (resource->cacheAccess().isBudgeted()) { | 317 if (resource->cacheAccess().isBudgeted()) { |
318 fBudgetedBytes += delta; | 318 fBudgetedBytes += delta; |
319 #if GR_CACHE_STATS | 319 #if GR_CACHE_STATS |
320 fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes
); | 320 fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes
); |
321 #endif | 321 #endif |
322 } | 322 } |
323 | 323 |
324 this->purgeAsNeeded(); | 324 this->purgeAsNeeded(); |
325 this->validate(); | 325 this->validate(); |
326 } | 326 } |
327 | 327 |
328 void GrResourceCache2::didChangeBudgetStatus(GrGpuResource* resource) { | 328 void GrResourceCache::didChangeBudgetStatus(GrGpuResource* resource) { |
329 SkASSERT(!fPurging); | 329 SkASSERT(!fPurging); |
330 SkASSERT(resource); | 330 SkASSERT(resource); |
331 SkASSERT(this->isInCache(resource)); | 331 SkASSERT(this->isInCache(resource)); |
332 | 332 |
333 size_t size = resource->gpuMemorySize(); | 333 size_t size = resource->gpuMemorySize(); |
334 | 334 |
335 if (resource->cacheAccess().isBudgeted()) { | 335 if (resource->cacheAccess().isBudgeted()) { |
336 ++fBudgetedCount; | 336 ++fBudgetedCount; |
337 fBudgetedBytes += size; | 337 fBudgetedBytes += size; |
338 #if GR_CACHE_STATS | 338 #if GR_CACHE_STATS |
339 fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes
); | 339 fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes
); |
340 fBudgetedHighWaterCount = SkTMax(fBudgetedCount, fBudgetedHighWaterCount
); | 340 fBudgetedHighWaterCount = SkTMax(fBudgetedCount, fBudgetedHighWaterCount
); |
341 #endif | 341 #endif |
342 this->purgeAsNeeded(); | 342 this->purgeAsNeeded(); |
343 } else { | 343 } else { |
344 --fBudgetedCount; | 344 --fBudgetedCount; |
345 fBudgetedBytes -= size; | 345 fBudgetedBytes -= size; |
346 } | 346 } |
347 | 347 |
348 this->validate(); | 348 this->validate(); |
349 } | 349 } |
350 | 350 |
351 void GrResourceCache2::internalPurgeAsNeeded() { | 351 void GrResourceCache::internalPurgeAsNeeded() { |
352 SkASSERT(!fPurging); | 352 SkASSERT(!fPurging); |
353 SkASSERT(!fNewlyPurgeableResourceWhilePurging); | 353 SkASSERT(!fNewlyPurgeableResourceWhilePurging); |
354 SkASSERT(fBudgetedCount > fMaxCount || fBudgetedBytes > fMaxBytes); | 354 SkASSERT(fBudgetedCount > fMaxCount || fBudgetedBytes > fMaxBytes); |
355 | 355 |
356 fPurging = true; | 356 fPurging = true; |
357 | 357 |
358 bool overBudget = true; | 358 bool overBudget = true; |
359 do { | 359 do { |
360 fNewlyPurgeableResourceWhilePurging = false; | 360 fNewlyPurgeableResourceWhilePurging = false; |
361 ResourceList::Iter resourceIter; | 361 ResourceList::Iter resourceIter; |
(...skipping 16 matching lines...) Expand all Loading... |
378 // Despite the purge we're still over budget. Call our over budget c
allback. | 378 // Despite the purge we're still over budget. Call our over budget c
allback. |
379 (*fOverBudgetCB)(fOverBudgetData); | 379 (*fOverBudgetCB)(fOverBudgetData); |
380 } | 380 } |
381 } while (overBudget && fNewlyPurgeableResourceWhilePurging); | 381 } while (overBudget && fNewlyPurgeableResourceWhilePurging); |
382 | 382 |
383 fNewlyPurgeableResourceWhilePurging = false; | 383 fNewlyPurgeableResourceWhilePurging = false; |
384 fPurging = false; | 384 fPurging = false; |
385 this->validate(); | 385 this->validate(); |
386 } | 386 } |
387 | 387 |
388 void GrResourceCache2::purgeAllUnlocked() { | 388 void GrResourceCache::purgeAllUnlocked() { |
389 SkASSERT(!fPurging); | 389 SkASSERT(!fPurging); |
390 SkASSERT(!fNewlyPurgeableResourceWhilePurging); | 390 SkASSERT(!fNewlyPurgeableResourceWhilePurging); |
391 | 391 |
392 fPurging = true; | 392 fPurging = true; |
393 | 393 |
394 do { | 394 do { |
395 fNewlyPurgeableResourceWhilePurging = false; | 395 fNewlyPurgeableResourceWhilePurging = false; |
396 ResourceList::Iter resourceIter; | 396 ResourceList::Iter resourceIter; |
397 GrGpuResource* resource = | 397 GrGpuResource* resource = |
398 resourceIter.init(fResources, ResourceList::Iter::kTail_IterStart); | 398 resourceIter.init(fResources, ResourceList::Iter::kTail_IterStart); |
399 | 399 |
400 while (resource) { | 400 while (resource) { |
401 GrGpuResource* prev = resourceIter.prev(); | 401 GrGpuResource* prev = resourceIter.prev(); |
402 if (resource->isPurgeable()) { | 402 if (resource->isPurgeable()) { |
403 resource->cacheAccess().release(); | 403 resource->cacheAccess().release(); |
404 } | 404 } |
405 resource = prev; | 405 resource = prev; |
406 } | 406 } |
407 | 407 |
408 if (!fNewlyPurgeableResourceWhilePurging && fCount && fOverBudgetCB) { | 408 if (!fNewlyPurgeableResourceWhilePurging && fCount && fOverBudgetCB) { |
409 (*fOverBudgetCB)(fOverBudgetData); | 409 (*fOverBudgetCB)(fOverBudgetData); |
410 } | 410 } |
411 } while (fNewlyPurgeableResourceWhilePurging); | 411 } while (fNewlyPurgeableResourceWhilePurging); |
412 fPurging = false; | 412 fPurging = false; |
413 this->validate(); | 413 this->validate(); |
414 } | 414 } |
415 | 415 |
416 void GrResourceCache2::processInvalidContentKeys( | 416 void GrResourceCache::processInvalidContentKeys( |
417 const SkTArray<GrContentKeyInvalidatedMessage>& msgs) { | 417 const SkTArray<GrContentKeyInvalidatedMessage>& msgs) { |
418 for (int i = 0; i < msgs.count(); ++i) { | 418 for (int i = 0; i < msgs.count(); ++i) { |
419 GrGpuResource* resource = this->findAndRefContentResource(msgs[i].key())
; | 419 GrGpuResource* resource = this->findAndRefContentResource(msgs[i].key())
; |
420 if (resource) { | 420 if (resource) { |
421 resource->cacheAccess().removeContentKey(); | 421 resource->cacheAccess().removeContentKey(); |
422 resource->unref(); // will call notifyPurgeable, if it is indeed now
purgeable. | 422 resource->unref(); // will call notifyPurgeable, if it is indeed now
purgeable. |
423 } | 423 } |
424 } | 424 } |
425 } | 425 } |
426 | 426 |
427 #ifdef SK_DEBUG | 427 #ifdef SK_DEBUG |
428 void GrResourceCache2::validate() const { | 428 void GrResourceCache::validate() const { |
429 // Reduce the frequency of validations for large resource counts. | 429 // Reduce the frequency of validations for large resource counts. |
430 static SkRandom gRandom; | 430 static SkRandom gRandom; |
431 int mask = (SkNextPow2(fCount + 1) >> 5) - 1; | 431 int mask = (SkNextPow2(fCount + 1) >> 5) - 1; |
432 if (~mask && (gRandom.nextU() & mask)) { | 432 if (~mask && (gRandom.nextU() & mask)) { |
433 return; | 433 return; |
434 } | 434 } |
435 | 435 |
436 size_t bytes = 0; | 436 size_t bytes = 0; |
437 int count = 0; | 437 int count = 0; |
438 int budgetedCount = 0; | 438 int budgetedCount = 0; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 #endif | 494 #endif |
495 SkASSERT(content == fContentHash.count()); | 495 SkASSERT(content == fContentHash.count()); |
496 SkASSERT(scratch + couldBeScratch == fScratchMap.count()); | 496 SkASSERT(scratch + couldBeScratch == fScratchMap.count()); |
497 | 497 |
498 // This assertion is not currently valid because we can be in recursive noti
fyIsPurgeable() | 498 // This assertion is not currently valid because we can be in recursive noti
fyIsPurgeable() |
499 // calls. This will be fixed when subresource registration is explicit. | 499 // calls. This will be fixed when subresource registration is explicit. |
500 // bool overBudget = budgetedBytes > fMaxBytes || budgetedCount > fMaxCount; | 500 // bool overBudget = budgetedBytes > fMaxBytes || budgetedCount > fMaxCount; |
501 // SkASSERT(!overBudget || locked == count || fPurging); | 501 // SkASSERT(!overBudget || locked == count || fPurging); |
502 } | 502 } |
503 #endif | 503 #endif |
OLD | NEW |