blob: 8eed4d4b7d5f36f0855af7f5d64a4f318d0ffcbc [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@google.comac10a2d2010-12-22 21:39:39 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2010 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@google.comac10a2d2010-12-22 21:39:39 +00007 */
8
bsalomon@google.com50398bf2011-07-26 20:45:30 +00009#include "GrResourceCache.h"
bsalomon6d3fe022014-07-25 08:35:45 -070010#include "GrGpuResource.h"
bsalomonbcf0a522014-10-08 08:40:09 -070011#include "GrTexturePriv.h"
12
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +000013DECLARE_SKMESSAGEBUS_MESSAGE(GrResourceInvalidatedMessage);
bsalomon@google.com0797c2c2012-12-20 15:13:01 +000014
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +000015///////////////////////////////////////////////////////////////////////////////
16
bsalomon6d3fe022014-07-25 08:35:45 -070017void GrGpuResource::didChangeGpuMemorySize() const {
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +000018 if (this->isInCache()) {
19 fCacheEntry->didChangeResourceSize();
20 }
21}
22
23///////////////////////////////////////////////////////////////////////////////
24
bsalomon@google.com0797c2c2012-12-20 15:13:01 +000025GrResourceKey::ResourceType GrResourceKey::GenerateResourceType() {
26 static int32_t gNextType = 0;
27
28 int32_t type = sk_atomic_inc(&gNextType);
29 if (type >= (1 << 8 * sizeof(ResourceType))) {
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +000030 SkFAIL("Too many Resource Types");
bsalomon@google.com0797c2c2012-12-20 15:13:01 +000031 }
32
33 return static_cast<ResourceType>(type);
34}
35
36///////////////////////////////////////////////////////////////////////////////
37
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +000038GrResourceCacheEntry::GrResourceCacheEntry(GrResourceCache* resourceCache,
39 const GrResourceKey& key,
bsalomon6d3fe022014-07-25 08:35:45 -070040 GrGpuResource* resource)
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +000041 : fResourceCache(resourceCache),
42 fKey(key),
43 fResource(resource),
44 fCachedSize(resource->gpuMemorySize()),
45 fIsExclusive(false) {
bsalomon@google.com50398bf2011-07-26 20:45:30 +000046 // we assume ownership of the resource, and will unref it when we die
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000047 SkASSERT(resource);
skia.committer@gmail.com6c778162012-09-06 02:01:13 +000048 resource->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +000049}
50
commit-bot@chromium.org089a7802014-05-02 21:38:22 +000051GrResourceCacheEntry::~GrResourceCacheEntry() {
bsalomon8b79d232014-11-10 10:19:06 -080052 // We're relying on having the cache entry to remove this from GrResourceCache2's content hash.
53 // fResource->setCacheEntry(NULL);
bsalomon@google.com50398bf2011-07-26 20:45:30 +000054 fResource->unref();
reed@google.comac10a2d2010-12-22 21:39:39 +000055}
56
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +000057#ifdef SK_DEBUG
commit-bot@chromium.org089a7802014-05-02 21:38:22 +000058void GrResourceCacheEntry::validate() const {
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +000059 SkASSERT(fResourceCache);
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000060 SkASSERT(fResource);
61 SkASSERT(fResource->getCacheEntry() == this);
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +000062 SkASSERT(fResource->gpuMemorySize() == fCachedSize);
bsalomon@google.com50398bf2011-07-26 20:45:30 +000063 fResource->validate();
reed@google.comac10a2d2010-12-22 21:39:39 +000064}
65#endif
66
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +000067void GrResourceCacheEntry::didChangeResourceSize() {
68 size_t oldSize = fCachedSize;
69 fCachedSize = fResource->gpuMemorySize();
70 if (fCachedSize > oldSize) {
71 fResourceCache->didIncreaseResourceSize(this, fCachedSize - oldSize);
72 } else if (fCachedSize < oldSize) {
73 fResourceCache->didDecreaseResourceSize(this, oldSize - fCachedSize);
74 }
75}
76
reed@google.comac10a2d2010-12-22 21:39:39 +000077///////////////////////////////////////////////////////////////////////////////
78
bsalomonbcf0a522014-10-08 08:40:09 -070079GrResourceCache::GrResourceCache(const GrDrawTargetCaps* caps, int maxCount, size_t maxBytes)
80 : fMaxCount(maxCount)
81 , fMaxBytes(maxBytes)
82 , fCaps(SkRef(caps)) {
robertphillips@google.com59552022012-08-31 13:07:37 +000083#if GR_CACHE_STATS
robertphillips@google.com5f9f2f52012-08-22 10:57:05 +000084 fHighWaterEntryCount = 0;
robertphillips@google.com5f9f2f52012-08-22 10:57:05 +000085 fHighWaterEntryBytes = 0;
robertphillips@google.com5f9f2f52012-08-22 10:57:05 +000086#endif
87
88 fEntryCount = 0;
robertphillips@google.com5f9f2f52012-08-22 10:57:05 +000089 fEntryBytes = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +000090
commit-bot@chromium.orgcae27fe2013-07-10 10:14:35 +000091 fPurging = false;
92
93 fOverbudgetCB = NULL;
94 fOverbudgetData = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +000095}
96
bsalomon@google.com50398bf2011-07-26 20:45:30 +000097GrResourceCache::~GrResourceCache() {
98 GrAutoResourceCacheValidate atcv(this);
reed@google.com01804b42011-01-18 21:50:41 +000099
bsalomon@google.coma2921122012-08-28 12:34:17 +0000100 EntryList::Iter iter;
101
102 // Unlike the removeAll, here we really remove everything, including locked resources.
commit-bot@chromium.org089a7802014-05-02 21:38:22 +0000103 while (GrResourceCacheEntry* entry = fList.head()) {
bsalomon@google.coma2921122012-08-28 12:34:17 +0000104 GrAutoResourceCacheValidate atcv(this);
105
106 // remove from our cache
107 fCache.remove(entry->fKey, entry);
108
109 // remove from our llist
robertphillips@google.com209a1142012-10-31 12:25:21 +0000110 this->internalDetach(entry);
bsalomon@google.coma2921122012-08-28 12:34:17 +0000111
112 delete entry;
113 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000114}
115
bsalomon@google.com07fc0d12012-06-22 15:15:59 +0000116void GrResourceCache::getLimits(int* maxResources, size_t* maxResourceBytes) const{
bsalomon49f085d2014-09-05 13:34:00 -0700117 if (maxResources) {
bsalomon@google.com07fc0d12012-06-22 15:15:59 +0000118 *maxResources = fMaxCount;
119 }
bsalomon49f085d2014-09-05 13:34:00 -0700120 if (maxResourceBytes) {
bsalomon@google.com07fc0d12012-06-22 15:15:59 +0000121 *maxResourceBytes = fMaxBytes;
122 }
123}
reed@google.com01804b42011-01-18 21:50:41 +0000124
bsalomon@google.com07fc0d12012-06-22 15:15:59 +0000125void GrResourceCache::setLimits(int maxResources, size_t maxResourceBytes) {
126 bool smaller = (maxResources < fMaxCount) || (maxResourceBytes < fMaxBytes);
127
128 fMaxCount = maxResources;
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000129 fMaxBytes = maxResourceBytes;
reed@google.com01804b42011-01-18 21:50:41 +0000130
131 if (smaller) {
132 this->purgeAsNeeded();
133 }
134}
135
bsalomonbcf0a522014-10-08 08:40:09 -0700136void GrResourceCache::internalDetach(GrResourceCacheEntry* entry) {
robertphillips@google.com521eaf82012-08-22 11:03:19 +0000137 fList.remove(entry);
bsalomonbcf0a522014-10-08 08:40:09 -0700138 fEntryCount -= 1;
139 fEntryBytes -= entry->fCachedSize;
Brian Salomon9323b8b2014-10-07 15:07:38 -0400140}
141
bsalomonbcf0a522014-10-08 08:40:09 -0700142void GrResourceCache::attachToHead(GrResourceCacheEntry* entry) {
Brian Salomon9323b8b2014-10-07 15:07:38 -0400143 fList.addToHead(entry);
144
bsalomonbcf0a522014-10-08 08:40:09 -0700145 fEntryCount += 1;
146 fEntryBytes += entry->fCachedSize;
Brian Salomon9323b8b2014-10-07 15:07:38 -0400147
148#if GR_CACHE_STATS
bsalomonbcf0a522014-10-08 08:40:09 -0700149 if (fHighWaterEntryCount < fEntryCount) {
150 fHighWaterEntryCount = fEntryCount;
Brian Salomon9323b8b2014-10-07 15:07:38 -0400151 }
bsalomonbcf0a522014-10-08 08:40:09 -0700152 if (fHighWaterEntryBytes < fEntryBytes) {
153 fHighWaterEntryBytes = fEntryBytes;
154 }
155#endif
reed@google.comac10a2d2010-12-22 21:39:39 +0000156}
157
robertphillips@google.com209a1142012-10-31 12:25:21 +0000158// This functor just searches for an entry with only a single ref (from
159// the texture cache itself). Presumably in this situation no one else
160// is relying on the texture.
161class GrTFindUnreffedFunctor {
162public:
commit-bot@chromium.org089a7802014-05-02 21:38:22 +0000163 bool operator()(const GrResourceCacheEntry* entry) const {
bsalomonbcf0a522014-10-08 08:40:09 -0700164 return entry->resource()->isPurgable();
robertphillips@google.com209a1142012-10-31 12:25:21 +0000165 }
166};
167
bsalomonbcf0a522014-10-08 08:40:09 -0700168
169void GrResourceCache::makeResourceMRU(GrGpuResource* resource) {
170 GrResourceCacheEntry* entry = resource->getCacheEntry();
171 if (entry) {
172 this->internalDetach(entry);
173 this->attachToHead(entry);
174 }
175}
176
177void GrResourceCache::notifyPurgable(const GrGpuResource* resource) {
178 // Remove scratch textures from the cache the moment they become purgeable if
179 // scratch texture reuse is turned off.
180 SkASSERT(resource->getCacheEntry());
181 if (resource->getCacheEntry()->key().getResourceType() == GrTexturePriv::ResourceType() &&
bsalomon1e2530b2014-10-09 09:57:18 -0700182 resource->getCacheEntry()->key().isScratch() &&
bsalomonbcf0a522014-10-08 08:40:09 -0700183 !fCaps->reuseScratchTextures() &&
bsalomon37dd3312014-11-03 08:47:23 -0800184 !(static_cast<const GrSurface*>(resource)->desc().fFlags & kRenderTarget_GrSurfaceFlag)) {
bsalomonbcf0a522014-10-08 08:40:09 -0700185 this->deleteResource(resource->getCacheEntry());
186 }
187}
188
bsalomon8b79d232014-11-10 10:19:06 -0800189bool GrResourceCache::addResource(const GrResourceKey& key, GrGpuResource* resource) {
190 if (NULL != resource->getCacheEntry()) {
191 return false;
robertphillips@google.coma9b06232012-08-30 11:06:31 +0000192 }
193
bsalomon@google.coma5a1da82011-08-05 14:02:41 +0000194 // we don't expect to create new resources during a purge. In theory
195 // this could cause purgeAsNeeded() into an infinite loop (e.g.
196 // each resource destroyed creates and locks 2 resources and
197 // unlocks 1 thereby causing a new purge).
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000198 SkASSERT(!fPurging);
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000199 GrAutoResourceCacheValidate atcv(this);
reed@google.comac10a2d2010-12-22 21:39:39 +0000200
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000201 GrResourceCacheEntry* entry = SkNEW_ARGS(GrResourceCacheEntry, (this, key, resource));
bsalomon8b79d232014-11-10 10:19:06 -0800202 if (!resource->setCacheEntry(entry)) {
203 SkDELETE(entry);
204 this->purgeAsNeeded();
205 return false;
206 }
robertphillips@google.com1f47f4f2012-08-16 14:49:16 +0000207
robertphillips@google.com209a1142012-10-31 12:25:21 +0000208 this->attachToHead(entry);
reed@google.comac10a2d2010-12-22 21:39:39 +0000209 fCache.insert(key, entry);
bsalomonbcf0a522014-10-08 08:40:09 -0700210 this->purgeAsNeeded();
bsalomon8b79d232014-11-10 10:19:06 -0800211 return true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000212}
213
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000214void GrResourceCache::didIncreaseResourceSize(const GrResourceCacheEntry* entry, size_t amountInc) {
215 fEntryBytes += amountInc;
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000216 this->purgeAsNeeded();
217}
218
219void GrResourceCache::didDecreaseResourceSize(const GrResourceCacheEntry* entry, size_t amountDec) {
220 fEntryBytes -= amountDec;
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000221#ifdef SK_DEBUG
222 this->validate();
223#endif
224}
225
bsalomon@google.coma5a1da82011-08-05 14:02:41 +0000226/**
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000227 * Destroying a resource may potentially trigger the unlock of additional
bsalomon@google.coma5a1da82011-08-05 14:02:41 +0000228 * resources which in turn will trigger a nested purge. We block the nested
229 * purge using the fPurging variable. However, the initial purge will keep
230 * looping until either all resources in the cache are unlocked or we've met
231 * the budget. There is an assertion in createAndLock to check against a
232 * resource's destructor inserting new resources into the cache. If these
233 * new resources were unlocked before purgeAsNeeded completed it could
234 * potentially make purgeAsNeeded loop infinitely.
robertphillips@google.com41d25322013-07-18 17:12:57 +0000235 *
236 * extraCount and extraBytes are added to the current resource totals to account
237 * for incoming resources (e.g., GrContext is about to add 10MB split between
238 * 10 textures).
bsalomon@google.coma5a1da82011-08-05 14:02:41 +0000239 */
robertphillips@google.com41d25322013-07-18 17:12:57 +0000240void GrResourceCache::purgeAsNeeded(int extraCount, size_t extraBytes) {
commit-bot@chromium.orgcae27fe2013-07-10 10:14:35 +0000241 if (fPurging) {
242 return;
reed@google.comac10a2d2010-12-22 21:39:39 +0000243 }
commit-bot@chromium.orgcae27fe2013-07-10 10:14:35 +0000244
245 fPurging = true;
246
commit-bot@chromium.org50a30432013-10-24 17:44:27 +0000247 this->purgeInvalidated();
248
robertphillips@google.com41d25322013-07-18 17:12:57 +0000249 this->internalPurge(extraCount, extraBytes);
skia.committer@gmail.coma7991982013-07-19 07:00:57 +0000250 if (((fEntryCount+extraCount) > fMaxCount ||
robertphillips@google.com41d25322013-07-18 17:12:57 +0000251 (fEntryBytes+extraBytes) > fMaxBytes) &&
bsalomon49f085d2014-09-05 13:34:00 -0700252 fOverbudgetCB) {
commit-bot@chromium.orgcae27fe2013-07-10 10:14:35 +0000253 // Despite the purge we're still over budget. See if Ganesh can
254 // release some resources and purge again.
255 if ((*fOverbudgetCB)(fOverbudgetData)) {
robertphillips@google.com41d25322013-07-18 17:12:57 +0000256 this->internalPurge(extraCount, extraBytes);
commit-bot@chromium.orgcae27fe2013-07-10 10:14:35 +0000257 }
258 }
259
260 fPurging = false;
261}
262
commit-bot@chromium.org50a30432013-10-24 17:44:27 +0000263void GrResourceCache::purgeInvalidated() {
264 SkTDArray<GrResourceInvalidatedMessage> invalidated;
265 fInvalidationInbox.poll(&invalidated);
266
267 for (int i = 0; i < invalidated.count(); i++) {
commit-bot@chromium.org089a7802014-05-02 21:38:22 +0000268 while (GrResourceCacheEntry* entry = fCache.find(invalidated[i].key, GrTFindUnreffedFunctor())) {
commit-bot@chromium.org50a30432013-10-24 17:44:27 +0000269 this->deleteResource(entry);
270 }
271 }
272}
273
commit-bot@chromium.org089a7802014-05-02 21:38:22 +0000274void GrResourceCache::deleteResource(GrResourceCacheEntry* entry) {
bsalomonbcf0a522014-10-08 08:40:09 -0700275 SkASSERT(entry->fResource->isPurgable());
robertphillips@google.come4eaea22013-07-19 16:51:46 +0000276
277 // remove from our cache
278 fCache.remove(entry->key(), entry);
279
280 // remove from our llist
281 this->internalDetach(entry);
282 delete entry;
283}
284
robertphillips@google.com41d25322013-07-18 17:12:57 +0000285void GrResourceCache::internalPurge(int extraCount, size_t extraBytes) {
commit-bot@chromium.orgcae27fe2013-07-10 10:14:35 +0000286 SkASSERT(fPurging);
287
288 bool withinBudget = false;
289 bool changed = false;
290
291 // The purging process is repeated several times since one pass
292 // may free up other resources
293 do {
294 EntryList::Iter iter;
295
296 changed = false;
297
298 // Note: the following code relies on the fact that the
299 // doubly linked list doesn't invalidate its data/pointers
300 // outside of the specific area where a deletion occurs (e.g.,
301 // in internalDetach)
commit-bot@chromium.org089a7802014-05-02 21:38:22 +0000302 GrResourceCacheEntry* entry = iter.init(fList, EntryList::Iter::kTail_IterStart);
commit-bot@chromium.orgcae27fe2013-07-10 10:14:35 +0000303
bsalomon49f085d2014-09-05 13:34:00 -0700304 while (entry) {
commit-bot@chromium.orgcae27fe2013-07-10 10:14:35 +0000305 GrAutoResourceCacheValidate atcv(this);
306
skia.committer@gmail.coma7991982013-07-19 07:00:57 +0000307 if ((fEntryCount+extraCount) <= fMaxCount &&
robertphillips@google.com41d25322013-07-18 17:12:57 +0000308 (fEntryBytes+extraBytes) <= fMaxBytes) {
commit-bot@chromium.orgcae27fe2013-07-10 10:14:35 +0000309 withinBudget = true;
310 break;
311 }
312
commit-bot@chromium.org089a7802014-05-02 21:38:22 +0000313 GrResourceCacheEntry* prev = iter.prev();
bsalomonbcf0a522014-10-08 08:40:09 -0700314 if (entry->fResource->isPurgable()) {
commit-bot@chromium.orgcae27fe2013-07-10 10:14:35 +0000315 changed = true;
robertphillips@google.come4eaea22013-07-19 16:51:46 +0000316 this->deleteResource(entry);
commit-bot@chromium.orgcae27fe2013-07-10 10:14:35 +0000317 }
318 entry = prev;
319 }
320 } while (!withinBudget && changed);
reed@google.comac10a2d2010-12-22 21:39:39 +0000321}
322
bsalomon@google.coma2921122012-08-28 12:34:17 +0000323void GrResourceCache::purgeAllUnlocked() {
bsalomon@google.come9a98942011-08-22 17:06:16 +0000324 GrAutoResourceCacheValidate atcv(this);
reed@google.com01804b42011-01-18 21:50:41 +0000325
commit-bot@chromium.org089a7802014-05-02 21:38:22 +0000326 // we can have one GrCacheable holding a lock on another
bsalomon@google.come9a98942011-08-22 17:06:16 +0000327 // so we don't want to just do a simple loop kicking each
328 // entry out. Instead change the budget and purge.
reed@google.comac10a2d2010-12-22 21:39:39 +0000329
robertphillips@google.comadacc702013-10-14 21:53:24 +0000330 size_t savedMaxBytes = fMaxBytes;
bsalomon@google.com07fc0d12012-06-22 15:15:59 +0000331 int savedMaxCount = fMaxCount;
332 fMaxBytes = (size_t) -1;
333 fMaxCount = 0;
bsalomon@google.come9a98942011-08-22 17:06:16 +0000334 this->purgeAsNeeded();
335
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000336#ifdef SK_DEBUG
twiz@google.com0ec107f2012-02-21 19:15:53 +0000337 if (!fCache.count()) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000338 SkASSERT(fList.isEmpty());
twiz@google.com0ec107f2012-02-21 19:15:53 +0000339 }
340#endif
bsalomon@google.come9a98942011-08-22 17:06:16 +0000341
342 fMaxBytes = savedMaxBytes;
bsalomon@google.com07fc0d12012-06-22 15:15:59 +0000343 fMaxCount = savedMaxCount;
reed@google.comac10a2d2010-12-22 21:39:39 +0000344}
345
346///////////////////////////////////////////////////////////////////////////////
347
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000348#ifdef SK_DEBUG
bsalomon@google.coma2921122012-08-28 12:34:17 +0000349size_t GrResourceCache::countBytes(const EntryList& list) {
robertphillips@google.com2ea0a232012-08-23 11:13:48 +0000350 size_t bytes = 0;
351
bsalomon@google.coma2921122012-08-28 12:34:17 +0000352 EntryList::Iter iter;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000353
commit-bot@chromium.org089a7802014-05-02 21:38:22 +0000354 const GrResourceCacheEntry* entry = iter.init(const_cast<EntryList&>(list),
355 EntryList::Iter::kTail_IterStart);
robertphillips@google.com2ea0a232012-08-23 11:13:48 +0000356
bsalomon49f085d2014-09-05 13:34:00 -0700357 for ( ; entry; entry = iter.prev()) {
commit-bot@chromium.org089a7802014-05-02 21:38:22 +0000358 bytes += entry->resource()->gpuMemorySize();
reed@google.comac10a2d2010-12-22 21:39:39 +0000359 }
robertphillips@google.com2ea0a232012-08-23 11:13:48 +0000360 return bytes;
reed@google.comac10a2d2010-12-22 21:39:39 +0000361}
362
reed@google.comb89a6432011-02-07 13:20:30 +0000363static bool both_zero_or_nonzero(int count, size_t bytes) {
364 return (count == 0 && bytes == 0) || (count > 0 && bytes > 0);
365}
reed@google.comb89a6432011-02-07 13:20:30 +0000366
bsalomon@google.com50398bf2011-07-26 20:45:30 +0000367void GrResourceCache::validate() const {
robertphillips@google.com2ea0a232012-08-23 11:13:48 +0000368 fList.validate();
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000369 SkASSERT(both_zero_or_nonzero(fEntryCount, fEntryBytes));
bsalomonbcf0a522014-10-08 08:40:09 -0700370 SkASSERT(fEntryCount == fCache.count());
reed@google.com01804b42011-01-18 21:50:41 +0000371
bsalomon@google.coma2921122012-08-28 12:34:17 +0000372 EntryList::Iter iter;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000373
Brian Salomon9323b8b2014-10-07 15:07:38 -0400374 // check that the shareable entries are okay
bsalomonbcf0a522014-10-08 08:40:09 -0700375 const GrResourceCacheEntry* entry = iter.init(const_cast<EntryList&>(fList),
376 EntryList::Iter::kHead_IterStart);
Brian Salomon9323b8b2014-10-07 15:07:38 -0400377
robertphillips@google.comd07cb0c2012-08-30 19:22:29 +0000378 int count = 0;
bsalomon49f085d2014-09-05 13:34:00 -0700379 for ( ; entry; entry = iter.next()) {
robertphillips@google.comd07cb0c2012-08-30 19:22:29 +0000380 entry->validate();
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000381 SkASSERT(fCache.find(entry->key()));
reed@google.comac10a2d2010-12-22 21:39:39 +0000382 count += 1;
reed@google.comac10a2d2010-12-22 21:39:39 +0000383 }
bsalomonbcf0a522014-10-08 08:40:09 -0700384 SkASSERT(count == fEntryCount);
robertphillips@google.com521eaf82012-08-22 11:03:19 +0000385
bsalomonbcf0a522014-10-08 08:40:09 -0700386 size_t bytes = this->countBytes(fList);
387 SkASSERT(bytes == fEntryBytes);
388 SkASSERT(fList.countEntries() == fEntryCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000389}
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000390#endif // SK_DEBUG
robertphillips@google.com59552022012-08-31 13:07:37 +0000391
392#if GR_CACHE_STATS
robertphillips@google.com5f9f2f52012-08-22 10:57:05 +0000393
robertphillips@google.com9fbcad02012-09-09 14:44:15 +0000394void GrResourceCache::printStats() {
395 int locked = 0;
bsalomon24234fe2014-10-24 09:34:41 -0700396 int scratch = 0;
robertphillips@google.com9fbcad02012-09-09 14:44:15 +0000397
398 EntryList::Iter iter;
399
commit-bot@chromium.org089a7802014-05-02 21:38:22 +0000400 GrResourceCacheEntry* entry = iter.init(fList, EntryList::Iter::kTail_IterStart);
robertphillips@google.com9fbcad02012-09-09 14:44:15 +0000401
bsalomon49f085d2014-09-05 13:34:00 -0700402 for ( ; entry; entry = iter.prev()) {
bsalomon24234fe2014-10-24 09:34:41 -0700403 if (!entry->fResource->isPurgable()) {
robertphillips@google.com9fbcad02012-09-09 14:44:15 +0000404 ++locked;
405 }
bsalomon24234fe2014-10-24 09:34:41 -0700406 if (entry->fResource->isScratch()) {
407 ++scratch;
408 }
robertphillips@google.com9fbcad02012-09-09 14:44:15 +0000409 }
410
bsalomon24234fe2014-10-24 09:34:41 -0700411 float countUtilization = (100.f * fEntryCount) / fMaxCount;
412 float byteUtilization = (100.f * fEntryBytes) / fMaxBytes;
413
robertphillips@google.com5f9f2f52012-08-22 10:57:05 +0000414 SkDebugf("Budget: %d items %d bytes\n", fMaxCount, fMaxBytes);
bsalomon24234fe2014-10-24 09:34:41 -0700415 SkDebugf("\t\tEntry Count: current %d (%d locked, %d scratch %.2g%% full), high %d\n",
416 fEntryCount, locked, scratch, countUtilization, fHighWaterEntryCount);
417 SkDebugf("\t\tEntry Bytes: current %d (%.2g%% full) high %d\n",
418 fEntryBytes, byteUtilization, fHighWaterEntryBytes);
robertphillips@google.com5f9f2f52012-08-22 10:57:05 +0000419}
420
reed@google.comac10a2d2010-12-22 21:39:39 +0000421#endif
robertphillips@google.com521eaf82012-08-22 11:03:19 +0000422
423///////////////////////////////////////////////////////////////////////////////