| 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 |