Chromium Code Reviews| Index: src/gpu/GrResourceCache.cpp |
| diff --git a/src/gpu/GrResourceCache.cpp b/src/gpu/GrResourceCache.cpp |
| index 529f87c124880bbefd0c724bd2e48016841d4cd9..f97422d8887d238c24aa0c0a4efa7039bad1d7b2 100644 |
| --- a/src/gpu/GrResourceCache.cpp |
| +++ b/src/gpu/GrResourceCache.cpp |
| @@ -74,49 +74,23 @@ GrResourceCache::GrResourceCache(const GrCaps* caps) |
| , fBudgetedCount(0) |
| , fBudgetedBytes(0) |
| , fRequestFlush(false) |
| - , fFlushTimestamps(nullptr) |
| - , fLastFlushTimestampIndex(0) |
| + , fExternalFlushCnt(0) |
| , fPreferVRAMUseOverFlushes(caps->preferVRAMUseOverFlushes()) { |
| SkDEBUGCODE(fCount = 0;) |
| SkDEBUGCODE(fNewlyPurgeableResourceForValidation = nullptr;) |
| - this->resetFlushTimestamps(); |
| } |
| GrResourceCache::~GrResourceCache() { |
| this->releaseAll(); |
| - delete[] fFlushTimestamps; |
| } |
| void GrResourceCache::setLimits(int count, size_t bytes, int maxUnusedFlushes) { |
| fMaxCount = count; |
| fMaxBytes = bytes; |
| fMaxUnusedFlushes = maxUnusedFlushes; |
| - this->resetFlushTimestamps(); |
| this->purgeAsNeeded(); |
| } |
| -void GrResourceCache::resetFlushTimestamps() { |
| - delete[] fFlushTimestamps; |
| - |
| - // We assume this number is a power of two when wrapping indices into the timestamp array. |
| - fMaxUnusedFlushes = SkNextPow2(fMaxUnusedFlushes); |
| - |
| - // Since our implementation is to store the timestamps of the last fMaxUnusedFlushes flush calls |
| - // we just turn the feature off if that array would be large. |
| - static const int kMaxSupportedTimestampHistory = 128; |
| - |
| - if (fMaxUnusedFlushes > kMaxSupportedTimestampHistory) { |
| - fFlushTimestamps = nullptr; |
| - return; |
| - } |
| - |
| - fFlushTimestamps = new uint32_t[fMaxUnusedFlushes]; |
| - fLastFlushTimestampIndex = 0; |
| - // Set all the historical flush timestamps to initially be at the beginning of time (timestamp |
| - // 0). |
| - sk_bzero(fFlushTimestamps, fMaxUnusedFlushes * sizeof(uint32_t)); |
| -} |
| - |
| void GrResourceCache::insertResource(GrGpuResource* resource) { |
| SkASSERT(resource); |
| SkASSERT(!this->isInCache(resource)); |
| @@ -390,6 +364,7 @@ void GrResourceCache::notifyCntReachedZero(GrGpuResource* resource, uint32_t fla |
| SkASSERT(resource->isPurgeable()); |
| this->removeFromNonpurgeableArray(resource); |
| fPurgeableQueue.insert(resource); |
| + resource->cacheAccess().setFlushCntWhenResourceBecamePurgeable(fExternalFlushCnt); |
| if (SkBudgeted::kNo == resource->resourcePriv().isBudgeted()) { |
| // Check whether this resource could still be used as a scratch resource. |
| @@ -474,20 +449,24 @@ void GrResourceCache::purgeAsNeeded() { |
| this->processInvalidUniqueKeys(invalidKeyMsgs); |
| } |
| - if (fFlushTimestamps) { |
| - // Assuming kNumFlushesToDeleteUnusedResource is a power of 2. |
| - SkASSERT(SkIsPow2(fMaxUnusedFlushes)); |
| - int oldestFlushIndex = (fLastFlushTimestampIndex + 1) & (fMaxUnusedFlushes - 1); |
| - |
| - uint32_t oldestAllowedTimestamp = fFlushTimestamps[oldestFlushIndex]; |
| - while (fPurgeableQueue.count()) { |
| - uint32_t oldestResourceTimestamp = fPurgeableQueue.peek()->cacheAccess().timestamp(); |
| - if (oldestAllowedTimestamp < oldestResourceTimestamp) { |
| - break; |
| + if (fMaxUnusedFlushes > 0) { |
| + // We want to know how many complete flushes have occurred without the resource being used. |
| + // If the resource was tagged when fExternalFlushCnt was N then this means it became |
| + // purgeable during activity that became the N+1th flush. So when the flush count is N+2 |
| + // it has sat in the purgeable queue for a one entire flush. |
| + uint32_t oldestAllowedFlushCnt = fExternalFlushCnt - fMaxUnusedFlushes - 1; |
| + // check for underflow |
| + if (oldestAllowedFlushCnt < fExternalFlushCnt) { |
| + while (fPurgeableQueue.count()) { |
|
robertphillips
2016/09/22 17:55:56
oldestResourceFlushCnt doesn't seem like the right
bsalomon
2016/09/22 18:09:55
Done.
|
| + uint32_t oldestResourceFlushCnt = |
| + fPurgeableQueue.peek()->cacheAccess().flushCntWhenResourceBecamePurgeable(); |
| + if (oldestAllowedFlushCnt < oldestResourceFlushCnt) { |
|
robertphillips
2016/09/22 17:55:56
// comment why this is break and not continue
?
bsalomon
2016/09/22 18:09:55
Done.
|
| + break; |
| + } |
| + GrGpuResource* resource = fPurgeableQueue.peek(); |
| + SkASSERT(resource->isPurgeable()); |
| + resource->cacheAccess().release(); |
| } |
| - GrGpuResource* resource = fPurgeableQueue.peek(); |
| - SkASSERT(resource->isPurgeable()); |
| - resource->cacheAccess().release(); |
| } |
| } |
| @@ -566,13 +545,8 @@ uint32_t GrResourceCache::getNextTimestamp() { |
| fPurgeableQueue.pop(); |
| } |
| - struct Less { |
| - bool operator()(GrGpuResource* a, GrGpuResource* b) { |
| - return CompareTimestamp(a,b); |
| - } |
| - }; |
| - Less less; |
| - SkTQSort(fNonpurgeableResources.begin(), fNonpurgeableResources.end() - 1, less); |
| + SkTQSort(fNonpurgeableResources.begin(), fNonpurgeableResources.end() - 1, |
| + CompareTimestamp); |
| // Pick resources out of the purgeable and non-purgeable arrays based on lowest |
| // timestamp and assign new timestamps. |
| @@ -611,9 +585,6 @@ uint32_t GrResourceCache::getNextTimestamp() { |
| // count should be the next timestamp we return. |
| SkASSERT(fTimestamp == SkToU32(count)); |
| - |
| - // The historical timestamps of flushes are now invalid. |
| - this->resetFlushTimestamps(); |
| } |
| } |
| return fTimestamp++; |
| @@ -628,13 +599,12 @@ void GrResourceCache::notifyFlushOccurred(FlushType type) { |
| fRequestFlush = false; |
| break; |
| case FlushType::kExternal: |
| - if (fFlushTimestamps) { |
| - SkASSERT(SkIsPow2(fMaxUnusedFlushes)); |
| - fLastFlushTimestampIndex = (fLastFlushTimestampIndex + 1) & (fMaxUnusedFlushes - 1); |
| - // get the timestamp before accessing fFlushTimestamps because getNextTimestamp will |
| - // reallocate fFlushTimestamps on timestamp overflow. |
| - uint32_t timestamp = this->getNextTimestamp(); |
| - fFlushTimestamps[fLastFlushTimestampIndex] = timestamp; |
| + ++fExternalFlushCnt; |
| + if (0 == fExternalFlushCnt) { |
| + // When this wraps just reset all the purgeable resources' last used flush state. |
| + for (int i = 0; i < fPurgeableQueue.count(); ++i) { |
| + fPurgeableQueue.at(i)->cacheAccess().setFlushCntWhenResourceBecamePurgeable(0); |
| + } |
| } |
| break; |
| } |