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 "GrResourceCache.h" | 10 #include "GrResourceCache.h" |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 , fMaxUnusedFlushes(kDefaultMaxUnusedFlushes) | 65 , fMaxUnusedFlushes(kDefaultMaxUnusedFlushes) |
66 #if GR_CACHE_STATS | 66 #if GR_CACHE_STATS |
67 , fHighWaterCount(0) | 67 , fHighWaterCount(0) |
68 , fHighWaterBytes(0) | 68 , fHighWaterBytes(0) |
69 , fBudgetedHighWaterCount(0) | 69 , fBudgetedHighWaterCount(0) |
70 , fBudgetedHighWaterBytes(0) | 70 , fBudgetedHighWaterBytes(0) |
71 #endif | 71 #endif |
72 , fBytes(0) | 72 , fBytes(0) |
73 , fBudgetedCount(0) | 73 , fBudgetedCount(0) |
74 , fBudgetedBytes(0) | 74 , fBudgetedBytes(0) |
75 , fOverBudgetCB(NULL) | 75 , fOverBudgetCB(nullptr) |
76 , fOverBudgetData(NULL) | 76 , fOverBudgetData(nullptr) |
77 , fFlushTimestamps(NULL) | 77 , fFlushTimestamps(nullptr) |
78 , fLastFlushTimestampIndex(0) | 78 , fLastFlushTimestampIndex(0) |
79 , fPreferVRAMUseOverFlushes(caps->preferVRAMUseOverFlushes()) { | 79 , fPreferVRAMUseOverFlushes(caps->preferVRAMUseOverFlushes()) { |
80 SkDEBUGCODE(fCount = 0;) | 80 SkDEBUGCODE(fCount = 0;) |
81 SkDEBUGCODE(fNewlyPurgeableResourceForValidation = NULL;) | 81 SkDEBUGCODE(fNewlyPurgeableResourceForValidation = nullptr;) |
82 this->resetFlushTimestamps(); | 82 this->resetFlushTimestamps(); |
83 } | 83 } |
84 | 84 |
85 GrResourceCache::~GrResourceCache() { | 85 GrResourceCache::~GrResourceCache() { |
86 this->releaseAll(); | 86 this->releaseAll(); |
87 delete[] fFlushTimestamps; | 87 delete[] fFlushTimestamps; |
88 } | 88 } |
89 | 89 |
90 void GrResourceCache::setLimits(int count, size_t bytes, int maxUnusedFlushes) { | 90 void GrResourceCache::setLimits(int count, size_t bytes, int maxUnusedFlushes) { |
91 fMaxCount = count; | 91 fMaxCount = count; |
92 fMaxBytes = bytes; | 92 fMaxBytes = bytes; |
93 fMaxUnusedFlushes = maxUnusedFlushes; | 93 fMaxUnusedFlushes = maxUnusedFlushes; |
94 this->resetFlushTimestamps(); | 94 this->resetFlushTimestamps(); |
95 this->purgeAsNeeded(); | 95 this->purgeAsNeeded(); |
96 } | 96 } |
97 | 97 |
98 void GrResourceCache::resetFlushTimestamps() { | 98 void GrResourceCache::resetFlushTimestamps() { |
99 delete[] fFlushTimestamps; | 99 delete[] fFlushTimestamps; |
100 | 100 |
101 // We assume this number is a power of two when wrapping indices into the ti
mestamp array. | 101 // We assume this number is a power of two when wrapping indices into the ti
mestamp array. |
102 fMaxUnusedFlushes = SkNextPow2(fMaxUnusedFlushes); | 102 fMaxUnusedFlushes = SkNextPow2(fMaxUnusedFlushes); |
103 | 103 |
104 // Since our implementation is to store the timestamps of the last fMaxUnuse
dFlushes flush calls | 104 // Since our implementation is to store the timestamps of the last fMaxUnuse
dFlushes flush calls |
105 // we just turn the feature off if that array would be large. | 105 // we just turn the feature off if that array would be large. |
106 static const int kMaxSupportedTimestampHistory = 128; | 106 static const int kMaxSupportedTimestampHistory = 128; |
107 | 107 |
108 if (fMaxUnusedFlushes > kMaxSupportedTimestampHistory) { | 108 if (fMaxUnusedFlushes > kMaxSupportedTimestampHistory) { |
109 fFlushTimestamps = NULL; | 109 fFlushTimestamps = nullptr; |
110 return; | 110 return; |
111 } | 111 } |
112 | 112 |
113 fFlushTimestamps = new uint32_t[fMaxUnusedFlushes]; | 113 fFlushTimestamps = new uint32_t[fMaxUnusedFlushes]; |
114 fLastFlushTimestampIndex = 0; | 114 fLastFlushTimestampIndex = 0; |
115 // Set all the historical flush timestamps to initially be at the beginning
of time (timestamp | 115 // Set all the historical flush timestamps to initially be at the beginning
of time (timestamp |
116 // 0). | 116 // 0). |
117 sk_bzero(fFlushTimestamps, fMaxUnusedFlushes * sizeof(uint32_t)); | 117 sk_bzero(fFlushTimestamps, fMaxUnusedFlushes * sizeof(uint32_t)); |
118 } | 118 } |
119 | 119 |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 SkASSERT(scratchKey.isValid()); | 252 SkASSERT(scratchKey.isValid()); |
253 | 253 |
254 GrGpuResource* resource; | 254 GrGpuResource* resource; |
255 if (flags & (kPreferNoPendingIO_ScratchFlag | kRequireNoPendingIO_ScratchFla
g)) { | 255 if (flags & (kPreferNoPendingIO_ScratchFlag | kRequireNoPendingIO_ScratchFla
g)) { |
256 resource = fScratchMap.find(scratchKey, AvailableForScratchUse(true)); | 256 resource = fScratchMap.find(scratchKey, AvailableForScratchUse(true)); |
257 if (resource) { | 257 if (resource) { |
258 this->refAndMakeResourceMRU(resource); | 258 this->refAndMakeResourceMRU(resource); |
259 this->validate(); | 259 this->validate(); |
260 return resource; | 260 return resource; |
261 } else if (flags & kRequireNoPendingIO_ScratchFlag) { | 261 } else if (flags & kRequireNoPendingIO_ScratchFlag) { |
262 return NULL; | 262 return nullptr; |
263 } | 263 } |
264 // We would prefer to consume more available VRAM rather than flushing | 264 // We would prefer to consume more available VRAM rather than flushing |
265 // immediately, but on ANGLE this can lead to starving of the GPU. | 265 // immediately, but on ANGLE this can lead to starving of the GPU. |
266 if (fPreferVRAMUseOverFlushes && this->wouldFit(resourceSize)) { | 266 if (fPreferVRAMUseOverFlushes && this->wouldFit(resourceSize)) { |
267 // kPrefer is specified, we didn't find a resource without pending i
o, | 267 // kPrefer is specified, we didn't find a resource without pending i
o, |
268 // but there is still space in our budget for the resource so force | 268 // but there is still space in our budget for the resource so force |
269 // the caller to allocate a new resource. | 269 // the caller to allocate a new resource. |
270 return NULL; | 270 return nullptr; |
271 } | 271 } |
272 } | 272 } |
273 resource = fScratchMap.find(scratchKey, AvailableForScratchUse(false)); | 273 resource = fScratchMap.find(scratchKey, AvailableForScratchUse(false)); |
274 if (resource) { | 274 if (resource) { |
275 this->refAndMakeResourceMRU(resource); | 275 this->refAndMakeResourceMRU(resource); |
276 this->validate(); | 276 this->validate(); |
277 } | 277 } |
278 return resource; | 278 return resource; |
279 } | 279 } |
280 | 280 |
(...skipping 14 matching lines...) Expand all Loading... |
295 } | 295 } |
296 | 296 |
297 void GrResourceCache::changeUniqueKey(GrGpuResource* resource, const GrUniqueKey
& newKey) { | 297 void GrResourceCache::changeUniqueKey(GrGpuResource* resource, const GrUniqueKey
& newKey) { |
298 SkASSERT(resource); | 298 SkASSERT(resource); |
299 SkASSERT(this->isInCache(resource)); | 299 SkASSERT(this->isInCache(resource)); |
300 | 300 |
301 // Remove the entry for this resource if it already has a unique key. | 301 // Remove the entry for this resource if it already has a unique key. |
302 if (resource->getUniqueKey().isValid()) { | 302 if (resource->getUniqueKey().isValid()) { |
303 SkASSERT(resource == fUniqueHash.find(resource->getUniqueKey())); | 303 SkASSERT(resource == fUniqueHash.find(resource->getUniqueKey())); |
304 fUniqueHash.remove(resource->getUniqueKey()); | 304 fUniqueHash.remove(resource->getUniqueKey()); |
305 SkASSERT(NULL == fUniqueHash.find(resource->getUniqueKey())); | 305 SkASSERT(nullptr == fUniqueHash.find(resource->getUniqueKey())); |
306 } | 306 } |
307 | 307 |
308 // If another resource has the new key, remove its key then install the key
on this resource. | 308 // If another resource has the new key, remove its key then install the key
on this resource. |
309 if (newKey.isValid()) { | 309 if (newKey.isValid()) { |
310 if (GrGpuResource* old = fUniqueHash.find(newKey)) { | 310 if (GrGpuResource* old = fUniqueHash.find(newKey)) { |
311 // If the old resource using the key is purgeable and is unreachable
, then remove it. | 311 // If the old resource using the key is purgeable and is unreachable
, then remove it. |
312 if (!old->resourcePriv().getScratchKey().isValid() && old->isPurgeab
le()) { | 312 if (!old->resourcePriv().getScratchKey().isValid() && old->isPurgeab
le()) { |
313 // release may call validate() which will assert that resource i
s in fUniqueHash | 313 // release may call validate() which will assert that resource i
s in fUniqueHash |
314 // if it has a valid key. So in debug reset the key here before
we assign it. | 314 // if it has a valid key. So in debug reset the key here before
we assign it. |
315 SkDEBUGCODE(resource->cacheAccess().removeUniqueKey();) | 315 SkDEBUGCODE(resource->cacheAccess().removeUniqueKey();) |
316 old->cacheAccess().release(); | 316 old->cacheAccess().release(); |
317 } else { | 317 } else { |
318 fUniqueHash.remove(newKey); | 318 fUniqueHash.remove(newKey); |
319 old->cacheAccess().removeUniqueKey(); | 319 old->cacheAccess().removeUniqueKey(); |
320 } | 320 } |
321 } | 321 } |
322 SkASSERT(NULL == fUniqueHash.find(newKey)); | 322 SkASSERT(nullptr == fUniqueHash.find(newKey)); |
323 resource->cacheAccess().setUniqueKey(newKey); | 323 resource->cacheAccess().setUniqueKey(newKey); |
324 fUniqueHash.add(resource); | 324 fUniqueHash.add(resource); |
325 } else { | 325 } else { |
326 resource->cacheAccess().removeUniqueKey(); | 326 resource->cacheAccess().removeUniqueKey(); |
327 } | 327 } |
328 | 328 |
329 this->validate(); | 329 this->validate(); |
330 } | 330 } |
331 | 331 |
332 void GrResourceCache::refAndMakeResourceMRU(GrGpuResource* resource) { | 332 void GrResourceCache::refAndMakeResourceMRU(GrGpuResource* resource) { |
(...skipping 23 matching lines...) Expand all Loading... |
356 if (SkToBool(ResourceAccess::kRefCntReachedZero_RefNotificationFlag & flags)
) { | 356 if (SkToBool(ResourceAccess::kRefCntReachedZero_RefNotificationFlag & flags)
) { |
357 #ifdef SK_DEBUG | 357 #ifdef SK_DEBUG |
358 // When the timestamp overflows validate() is called. validate() checks
that resources in | 358 // When the timestamp overflows validate() is called. validate() checks
that resources in |
359 // the nonpurgeable array are indeed not purgeable. However, the movemen
t from the array to | 359 // the nonpurgeable array are indeed not purgeable. However, the movemen
t from the array to |
360 // the purgeable queue happens just below in this function. So we mark i
t as an exception. | 360 // the purgeable queue happens just below in this function. So we mark i
t as an exception. |
361 if (resource->isPurgeable()) { | 361 if (resource->isPurgeable()) { |
362 fNewlyPurgeableResourceForValidation = resource; | 362 fNewlyPurgeableResourceForValidation = resource; |
363 } | 363 } |
364 #endif | 364 #endif |
365 resource->cacheAccess().setTimestamp(this->getNextTimestamp()); | 365 resource->cacheAccess().setTimestamp(this->getNextTimestamp()); |
366 SkDEBUGCODE(fNewlyPurgeableResourceForValidation = NULL); | 366 SkDEBUGCODE(fNewlyPurgeableResourceForValidation = nullptr); |
367 } | 367 } |
368 | 368 |
369 if (!SkToBool(ResourceAccess::kAllCntsReachedZero_RefNotificationFlag & flag
s)) { | 369 if (!SkToBool(ResourceAccess::kAllCntsReachedZero_RefNotificationFlag & flag
s)) { |
370 SkASSERT(!resource->isPurgeable()); | 370 SkASSERT(!resource->isPurgeable()); |
371 return; | 371 return; |
372 } | 372 } |
373 | 373 |
374 SkASSERT(resource->isPurgeable()); | 374 SkASSERT(resource->isPurgeable()); |
375 this->removeFromNonpurgeableArray(resource); | 375 this->removeFromNonpurgeableArray(resource); |
376 fPurgeableQueue.insert(resource); | 376 fPurgeableQueue.insert(resource); |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 return true; | 724 return true; |
725 } | 725 } |
726 if (index < fNonpurgeableResources.count() && fNonpurgeableResources[index]
== resource) { | 726 if (index < fNonpurgeableResources.count() && fNonpurgeableResources[index]
== resource) { |
727 return true; | 727 return true; |
728 } | 728 } |
729 SkDEBUGFAIL("Resource index should be -1 or the resource should be in the ca
che."); | 729 SkDEBUGFAIL("Resource index should be -1 or the resource should be in the ca
che."); |
730 return false; | 730 return false; |
731 } | 731 } |
732 | 732 |
733 #endif | 733 #endif |
OLD | NEW |