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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 } | 86 } |
87 | 87 |
88 void GrResourceCache2::insertResource(GrGpuResource* resource) { | 88 void GrResourceCache2::insertResource(GrGpuResource* resource) { |
89 AutoValidate av(this); | 89 AutoValidate av(this); |
90 | 90 |
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 resource->ref(); | |
97 | 96 |
98 ++fCount; | 97 ++fCount; |
99 SkDEBUGCODE(fHighWaterCount = SkTMax(fCount, fHighWaterCount)); | 98 SkDEBUGCODE(fHighWaterCount = SkTMax(fCount, fHighWaterCount)); |
100 fBytes += resource->gpuMemorySize(); | 99 fBytes += resource->gpuMemorySize(); |
101 SkDEBUGCODE(fHighWaterBytes = SkTMax(fBytes, fHighWaterBytes)); | 100 SkDEBUGCODE(fHighWaterBytes = SkTMax(fBytes, fHighWaterBytes)); |
102 if (!resource->cacheAccess().getScratchKey().isNullScratch()) { | 101 if (!resource->cacheAccess().getScratchKey().isNullScratch()) { |
103 // TODO(bsalomon): Make this assertion possible. | 102 // TODO(bsalomon): Make this assertion possible. |
104 // SkASSERT(!resource->isWrapped()); | 103 // SkASSERT(!resource->isWrapped()); |
105 fScratchMap.insert(resource->cacheAccess().getScratchKey(), resource); | 104 fScratchMap.insert(resource->cacheAccess().getScratchKey(), resource); |
106 } | 105 } |
(...skipping 15 matching lines...) Expand all Loading... |
122 fContentHash.remove(*contentKey); | 121 fContentHash.remove(*contentKey); |
123 } | 122 } |
124 } | 123 } |
125 | 124 |
126 void GrResourceCache2::abandonAll() { | 125 void GrResourceCache2::abandonAll() { |
127 AutoValidate av(this); | 126 AutoValidate av(this); |
128 | 127 |
129 SkASSERT(!fPurging); | 128 SkASSERT(!fPurging); |
130 while (GrGpuResource* head = fResources.head()) { | 129 while (GrGpuResource* head = fResources.head()) { |
131 SkASSERT(!head->wasDestroyed()); | 130 SkASSERT(!head->wasDestroyed()); |
132 head->abandon(); | 131 head->cacheAccess().abandon(); |
133 head->unref(); | |
134 // abandon should have already removed this from the list. | 132 // abandon should have already removed this from the list. |
135 SkASSERT(head != fResources.head()); | 133 SkASSERT(head != fResources.head()); |
136 } | 134 } |
137 SkASSERT(!fScratchMap.count()); | 135 SkASSERT(!fScratchMap.count()); |
138 SkASSERT(!fContentHash.count()); | 136 SkASSERT(!fContentHash.count()); |
139 SkASSERT(!fCount); | 137 SkASSERT(!fCount); |
140 } | 138 } |
141 | 139 |
142 void GrResourceCache2::releaseAll() { | 140 void GrResourceCache2::releaseAll() { |
143 AutoValidate av(this); | 141 AutoValidate av(this); |
144 | 142 |
145 SkASSERT(!fPurging); | 143 SkASSERT(!fPurging); |
146 while (GrGpuResource* head = fResources.head()) { | 144 while (GrGpuResource* head = fResources.head()) { |
147 SkASSERT(!head->wasDestroyed()); | 145 SkASSERT(!head->wasDestroyed()); |
148 head->release(); | 146 head->cacheAccess().release(); |
149 head->unref(); | |
150 // release should have already removed this from the list. | 147 // release should have already removed this from the list. |
151 SkASSERT(head != fResources.head()); | 148 SkASSERT(head != fResources.head()); |
152 } | 149 } |
153 SkASSERT(!fScratchMap.count()); | 150 SkASSERT(!fScratchMap.count()); |
154 SkASSERT(!fCount); | 151 SkASSERT(!fCount); |
155 } | 152 } |
156 | 153 |
157 class GrResourceCache2::AvailableForScratchUse { | 154 class GrResourceCache2::AvailableForScratchUse { |
158 public: | 155 public: |
159 AvailableForScratchUse(bool rejectPendingIO) : fRejectPendingIO(rejectPendin
gIO) { } | 156 AvailableForScratchUse(bool rejectPendingIO) : fRejectPendingIO(rejectPendin
gIO) { } |
160 | 157 |
161 bool operator()(const GrGpuResource* resource) const { | 158 bool operator()(const GrGpuResource* resource) const { |
162 if (!resource->reffedOnlyByCache() || !resource->cacheAccess().isScratch
()) { | 159 if (resource->internalHasRef() || !resource->cacheAccess().isScratch())
{ |
163 return false; | 160 return false; |
164 } | 161 } |
165 | 162 |
166 return !fRejectPendingIO || !resource->internalHasPendingIO(); | 163 return !fRejectPendingIO || !resource->internalHasPendingIO(); |
167 } | 164 } |
168 | 165 |
169 private: | 166 private: |
170 bool fRejectPendingIO; | 167 bool fRejectPendingIO; |
171 }; | 168 }; |
172 | 169 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 void GrResourceCache2::makeResourceMRU(GrGpuResource* resource) { | 214 void GrResourceCache2::makeResourceMRU(GrGpuResource* resource) { |
218 AutoValidate av(this); | 215 AutoValidate av(this); |
219 | 216 |
220 SkASSERT(!fPurging); | 217 SkASSERT(!fPurging); |
221 SkASSERT(resource); | 218 SkASSERT(resource); |
222 SkASSERT(this->isInCache(resource)); | 219 SkASSERT(this->isInCache(resource)); |
223 fResources.remove(resource); | 220 fResources.remove(resource); |
224 fResources.addToHead(resource); | 221 fResources.addToHead(resource); |
225 } | 222 } |
226 | 223 |
227 void GrResourceCache2::notifyPurgable(const GrGpuResource* resource) { | 224 void GrResourceCache2::notifyPurgable(GrGpuResource* resource) { |
228 SkASSERT(resource); | 225 SkASSERT(resource); |
229 SkASSERT(this->isInCache(resource)); | 226 SkASSERT(this->isInCache(resource)); |
230 SkASSERT(resource->isPurgable()); | 227 SkASSERT(resource->isPurgable()); |
231 | 228 |
232 // We can't purge if in the middle of purging because purge is iterating. In
stead record | 229 // We can't purge if in the middle of purging because purge is iterating. In
stead record |
233 // that additional resources became purgable. | 230 // that additional resources became purgable. |
234 if (fPurging) { | 231 if (fPurging) { |
235 fNewlyPurgableResourceWhilePurging = true; | 232 fNewlyPurgableResourceWhilePurging = true; |
236 return; | 233 return; |
237 } | 234 } |
238 | 235 |
239 // Purge the resource if we're over budget | 236 // Purge the resource if we're over budget |
240 bool overBudget = fCount > fMaxCount || fBytes > fMaxBytes; | 237 bool overBudget = fCount > fMaxCount || fBytes > fMaxBytes; |
241 | 238 |
242 // We should not be over budget here unless all resources are unpuragble. | |
243 #ifdef SK_DEBUG | |
244 if (overBudget) { | |
245 ResourceList::Iter iter; | |
246 GrGpuResource* r = iter.init(fResources, ResourceList::Iter::kHead_IterS
tart); | |
247 for ( ; r; r = iter.next()) { | |
248 SkASSERT(r == resource || !r->isPurgable()); | |
249 } | |
250 } | |
251 #endif | |
252 | |
253 // Also purge if the resource has neither a valid scratch key nor a content
key. | 239 // Also purge if the resource has neither a valid scratch key nor a content
key. |
254 bool noKey = !resource->cacheAccess().isScratch() && | 240 bool noKey = !resource->cacheAccess().isScratch() && |
255 (NULL == resource->cacheAccess().getContentKey()); | 241 (NULL == resource->cacheAccess().getContentKey()); |
256 | 242 |
257 if (overBudget || noKey) { | 243 if (overBudget || noKey) { |
258 SkDEBUGCODE(int beforeCount = fCount;) | 244 SkDEBUGCODE(int beforeCount = fCount;) |
259 resource->unref(); | 245 resource->cacheAccess().release(); |
260 // We should at least have freed resource. It may have in turn freed oth
er resources. | 246 // We should at least free this resource, perhaps dependent resources as
well. |
261 SkASSERT(fCount < beforeCount); | 247 SkASSERT(fCount < beforeCount); |
262 } | 248 } |
263 | 249 |
264 this->validate(); | 250 this->validate(); |
265 } | 251 } |
266 | 252 |
267 void GrResourceCache2::didChangeGpuMemorySize(const GrGpuResource* resource, siz
e_t oldSize) { | 253 void GrResourceCache2::didChangeGpuMemorySize(const GrGpuResource* resource, siz
e_t oldSize) { |
268 // SkASSERT(!fPurging); GrPathRange increases size during flush. :( | 254 // SkASSERT(!fPurging); GrPathRange increases size during flush. :( |
269 SkASSERT(resource); | 255 SkASSERT(resource); |
270 SkASSERT(this->isInCache(resource)); | 256 SkASSERT(this->isInCache(resource)); |
(...skipping 17 matching lines...) Expand all Loading... |
288 bool overBudget = true; | 274 bool overBudget = true; |
289 do { | 275 do { |
290 fNewlyPurgableResourceWhilePurging = false; | 276 fNewlyPurgableResourceWhilePurging = false; |
291 ResourceList::Iter resourceIter; | 277 ResourceList::Iter resourceIter; |
292 GrGpuResource* resource = resourceIter.init(fResources, | 278 GrGpuResource* resource = resourceIter.init(fResources, |
293 ResourceList::Iter::kTail_It
erStart); | 279 ResourceList::Iter::kTail_It
erStart); |
294 | 280 |
295 while (resource) { | 281 while (resource) { |
296 GrGpuResource* prev = resourceIter.prev(); | 282 GrGpuResource* prev = resourceIter.prev(); |
297 if (resource->isPurgable()) { | 283 if (resource->isPurgable()) { |
298 resource->unref(); | 284 resource->cacheAccess().release(); |
299 } | 285 } |
300 resource = prev; | 286 resource = prev; |
301 if (fCount <= fMaxCount && fBytes <= fMaxBytes) { | 287 if (fCount <= fMaxCount && fBytes <= fMaxBytes) { |
302 overBudget = false; | 288 overBudget = false; |
303 resource = NULL; | 289 resource = NULL; |
304 } | 290 } |
305 } | 291 } |
306 | 292 |
307 if (!fNewlyPurgableResourceWhilePurging && overBudget && fOverBudgetCB)
{ | 293 if (!fNewlyPurgableResourceWhilePurging && overBudget && fOverBudgetCB)
{ |
308 // Despite the purge we're still over budget. Call our over budget c
allback. | 294 // Despite the purge we're still over budget. Call our over budget c
allback. |
(...skipping 15 matching lines...) Expand all Loading... |
324 | 310 |
325 do { | 311 do { |
326 fNewlyPurgableResourceWhilePurging = false; | 312 fNewlyPurgableResourceWhilePurging = false; |
327 ResourceList::Iter resourceIter; | 313 ResourceList::Iter resourceIter; |
328 GrGpuResource* resource = | 314 GrGpuResource* resource = |
329 resourceIter.init(fResources, ResourceList::Iter::kTail_IterStart); | 315 resourceIter.init(fResources, ResourceList::Iter::kTail_IterStart); |
330 | 316 |
331 while (resource) { | 317 while (resource) { |
332 GrGpuResource* prev = resourceIter.prev(); | 318 GrGpuResource* prev = resourceIter.prev(); |
333 if (resource->isPurgable()) { | 319 if (resource->isPurgable()) { |
334 resource->unref(); | 320 resource->cacheAccess().release(); |
335 } | 321 } |
336 resource = prev; | 322 resource = prev; |
337 } | 323 } |
338 | 324 |
339 if (!fNewlyPurgableResourceWhilePurging && fCount && fOverBudgetCB) { | 325 if (!fNewlyPurgableResourceWhilePurging && fCount && fOverBudgetCB) { |
340 (*fOverBudgetCB)(fOverBudgetData); | 326 (*fOverBudgetCB)(fOverBudgetData); |
341 } | 327 } |
342 } while (fNewlyPurgableResourceWhilePurging); | 328 } while (fNewlyPurgableResourceWhilePurging); |
343 fPurging = false; | 329 fPurging = false; |
344 } | 330 } |
345 | 331 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 | 366 |
381 SkASSERT(bytes == fBytes); | 367 SkASSERT(bytes == fBytes); |
382 SkASSERT(count == fCount); | 368 SkASSERT(count == fCount); |
383 #if GR_CACHE_STATS | 369 #if GR_CACHE_STATS |
384 SkASSERT(bytes <= fHighWaterBytes); | 370 SkASSERT(bytes <= fHighWaterBytes); |
385 SkASSERT(count <= fHighWaterCount); | 371 SkASSERT(count <= fHighWaterCount); |
386 #endif | 372 #endif |
387 SkASSERT(content == fContentHash.count()); | 373 SkASSERT(content == fContentHash.count()); |
388 SkASSERT(scratch + couldBeScratch == fScratchMap.count()); | 374 SkASSERT(scratch + couldBeScratch == fScratchMap.count()); |
389 | 375 |
390 bool overBudget = bytes > fMaxBytes || count > fMaxCount; | 376 // This assertion is not currently valid because we can be in recursive noti
fyIsPurgable() |
391 SkASSERT(!overBudget || locked == count || fPurging); | 377 // calls. This will be fixed when subresource registration is explicit. |
| 378 // bool overBudget = bytes > fMaxBytes || count > fMaxCount; |
| 379 // SkASSERT(!overBudget || locked == count || fPurging); |
392 } | 380 } |
393 #endif | 381 #endif |
394 | 382 |
395 #if GR_CACHE_STATS | 383 #if GR_CACHE_STATS |
396 void GrResourceCache2::printStats() const { | 384 void GrResourceCache2::printStats() const { |
397 this->validate(); | 385 this->validate(); |
398 | 386 |
399 int locked = 0; | 387 int locked = 0; |
400 int scratch = 0; | 388 int scratch = 0; |
401 | 389 |
(...skipping 13 matching lines...) Expand all Loading... |
415 float byteUtilization = (100.f * fBytes) / fMaxBytes; | 403 float byteUtilization = (100.f * fBytes) / fMaxBytes; |
416 | 404 |
417 SkDebugf("Budget: %d items %d bytes\n", fMaxCount, fMaxBytes); | 405 SkDebugf("Budget: %d items %d bytes\n", fMaxCount, fMaxBytes); |
418 SkDebugf("\t\tEntry Count: current %d (%d locked, %d scratch %.2g%% full), h
igh %d\n", | 406 SkDebugf("\t\tEntry Count: current %d (%d locked, %d scratch %.2g%% full), h
igh %d\n", |
419 fCount, locked, scratch, countUtilization, fHighWaterCount); | 407 fCount, locked, scratch, countUtilization, fHighWaterCount); |
420 SkDebugf("\t\tEntry Bytes: current %d (%.2g%% full) high %d\n", | 408 SkDebugf("\t\tEntry Bytes: current %d (%.2g%% full) high %d\n", |
421 fBytes, byteUtilization, fHighWaterBytes); | 409 fBytes, byteUtilization, fHighWaterBytes); |
422 } | 410 } |
423 | 411 |
424 #endif | 412 #endif |
OLD | NEW |