Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(106)

Side by Side Diff: src/gpu/GrResourceCache.cpp

Issue 932863004: Use an array of nonpurgeable resources in GrResourceCache (Closed) Base URL: https://skia.googlesource.com/skia.git@queue
Patch Set: add assert back Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 GrResourceCache::GrResourceCache() 60 GrResourceCache::GrResourceCache()
61 : fTimestamp(0) 61 : fTimestamp(0)
62 , fMaxCount(kDefaultMaxCount) 62 , fMaxCount(kDefaultMaxCount)
63 , fMaxBytes(kDefaultMaxSize) 63 , fMaxBytes(kDefaultMaxSize)
64 #if GR_CACHE_STATS 64 #if GR_CACHE_STATS
65 , fHighWaterCount(0) 65 , fHighWaterCount(0)
66 , fHighWaterBytes(0) 66 , fHighWaterBytes(0)
67 , fBudgetedHighWaterCount(0) 67 , fBudgetedHighWaterCount(0)
68 , fBudgetedHighWaterBytes(0) 68 , fBudgetedHighWaterBytes(0)
69 #endif 69 #endif
70 , fCount(0)
71 , fBytes(0) 70 , fBytes(0)
72 , fBudgetedCount(0) 71 , fBudgetedCount(0)
73 , fBudgetedBytes(0) 72 , fBudgetedBytes(0)
74 , fOverBudgetCB(NULL) 73 , fOverBudgetCB(NULL)
75 , fOverBudgetData(NULL) { 74 , fOverBudgetData(NULL) {
75 SkDEBUGCODE(fCount = 0;)
76 } 76 }
77 77
78 GrResourceCache::~GrResourceCache() { 78 GrResourceCache::~GrResourceCache() {
79 this->releaseAll(); 79 this->releaseAll();
80 } 80 }
81 81
82 void GrResourceCache::setLimits(int count, size_t bytes) { 82 void GrResourceCache::setLimits(int count, size_t bytes) {
83 fMaxCount = count; 83 fMaxCount = count;
84 fMaxBytes = bytes; 84 fMaxBytes = bytes;
85 this->purgeAsNeeded(); 85 this->purgeAsNeeded();
86 } 86 }
87 87
88 void GrResourceCache::insertResource(GrGpuResource* resource) { 88 void GrResourceCache::insertResource(GrGpuResource* resource) {
89 SkASSERT(resource); 89 SkASSERT(resource);
90 SkASSERT(!this->isInCache(resource));
90 SkASSERT(!resource->wasDestroyed()); 91 SkASSERT(!resource->wasDestroyed());
91 SkASSERT(!this->isInCache(resource)); 92 SkASSERT(!resource->isPurgeable());
92 fResources.addToHead(resource); 93 this->addToNonpurgeableArray(resource);
93 94
94 size_t size = resource->gpuMemorySize(); 95 size_t size = resource->gpuMemorySize();
95 ++fCount; 96 SkDEBUGCODE(++fCount;)
96 fBytes += size; 97 fBytes += size;
97 #if GR_CACHE_STATS 98 #if GR_CACHE_STATS
98 fHighWaterCount = SkTMax(fCount, fHighWaterCount); 99 fHighWaterCount = SkTMax(this->getResourceCount(), fHighWaterCount);
99 fHighWaterBytes = SkTMax(fBytes, fHighWaterBytes); 100 fHighWaterBytes = SkTMax(fBytes, fHighWaterBytes);
100 #endif 101 #endif
101 if (resource->resourcePriv().isBudgeted()) { 102 if (resource->resourcePriv().isBudgeted()) {
102 ++fBudgetedCount; 103 ++fBudgetedCount;
103 fBudgetedBytes += size; 104 fBudgetedBytes += size;
104 #if GR_CACHE_STATS 105 #if GR_CACHE_STATS
105 fBudgetedHighWaterCount = SkTMax(fBudgetedCount, fBudgetedHighWaterCount ); 106 fBudgetedHighWaterCount = SkTMax(fBudgetedCount, fBudgetedHighWaterCount );
106 fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes ); 107 fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes );
107 #endif 108 #endif
108 } 109 }
109 if (resource->resourcePriv().getScratchKey().isValid()) { 110 if (resource->resourcePriv().getScratchKey().isValid()) {
110 SkASSERT(!resource->cacheAccess().isWrapped()); 111 SkASSERT(!resource->cacheAccess().isWrapped());
111 fScratchMap.insert(resource->resourcePriv().getScratchKey(), resource); 112 fScratchMap.insert(resource->resourcePriv().getScratchKey(), resource);
112 } 113 }
113 114
114 resource->cacheAccess().setTimestamp(fTimestamp++); 115 resource->cacheAccess().setTimestamp(fTimestamp++);
115 116
116 this->purgeAsNeeded(); 117 this->purgeAsNeeded();
117 } 118 }
118 119
119 void GrResourceCache::removeResource(GrGpuResource* resource) { 120 void GrResourceCache::removeResource(GrGpuResource* resource) {
120 this->validate(); 121 this->validate();
121 SkASSERT(this->isInCache(resource)); 122 SkASSERT(this->isInCache(resource));
122 123
123 if (resource->isPurgeable()) { 124 if (resource->isPurgeable()) {
124 fPurgeableQueue.remove(resource); 125 fPurgeableQueue.remove(resource);
126 } else {
127 this->removeFromNonpurgeableArray(resource);
125 } 128 }
126 129
127 size_t size = resource->gpuMemorySize(); 130 size_t size = resource->gpuMemorySize();
128 --fCount; 131 SkDEBUGCODE(--fCount;)
129 fBytes -= size; 132 fBytes -= size;
130 if (resource->resourcePriv().isBudgeted()) { 133 if (resource->resourcePriv().isBudgeted()) {
131 --fBudgetedCount; 134 --fBudgetedCount;
132 fBudgetedBytes -= size; 135 fBudgetedBytes -= size;
133 } 136 }
134 137
135 fResources.remove(resource);
136 if (resource->resourcePriv().getScratchKey().isValid()) { 138 if (resource->resourcePriv().getScratchKey().isValid()) {
137 fScratchMap.remove(resource->resourcePriv().getScratchKey(), resource); 139 fScratchMap.remove(resource->resourcePriv().getScratchKey(), resource);
138 } 140 }
139 if (resource->getContentKey().isValid()) { 141 if (resource->getContentKey().isValid()) {
140 fContentHash.remove(resource->getContentKey()); 142 fContentHash.remove(resource->getContentKey());
141 } 143 }
142 this->validate(); 144 this->validate();
143 } 145 }
144 146
145 void GrResourceCache::abandonAll() { 147 void GrResourceCache::abandonAll() {
146 AutoValidate av(this); 148 AutoValidate av(this);
147 149
robertphillips 2015/02/17 18:32:23 space after while ?
bsalomon 2015/02/17 19:32:51 Done.
148 while (GrGpuResource* head = fResources.head()) { 150 while(fNonpurgeableResources.count()) {
149 SkASSERT(!head->wasDestroyed()); 151 GrGpuResource* back = *(fNonpurgeableResources.end() - 1);
150 head->cacheAccess().abandon(); 152 SkASSERT(!back->wasDestroyed());
151 // abandon should have already removed this from the list. 153 back->cacheAccess().abandon();
152 SkASSERT(head != fResources.head());
153 } 154 }
155
156 while (fPurgeableQueue.count()) {
157 GrGpuResource* top = fPurgeableQueue.peek();
158 SkASSERT(!top->wasDestroyed());
159 top->cacheAccess().abandon();
160 }
161
154 SkASSERT(!fScratchMap.count()); 162 SkASSERT(!fScratchMap.count());
155 SkASSERT(!fContentHash.count()); 163 SkASSERT(!fContentHash.count());
156 SkASSERT(!fCount); 164 SkASSERT(!fCount);
165 SkASSERT(!this->getResourceCount());
157 SkASSERT(!fBytes); 166 SkASSERT(!fBytes);
158 SkASSERT(!fBudgetedCount); 167 SkASSERT(!fBudgetedCount);
159 SkASSERT(!fBudgetedBytes); 168 SkASSERT(!fBudgetedBytes);
160 } 169 }
161 170
162 void GrResourceCache::releaseAll() { 171 void GrResourceCache::releaseAll() {
163 AutoValidate av(this); 172 AutoValidate av(this);
164 173
165 while (GrGpuResource* head = fResources.head()) { 174 while(fNonpurgeableResources.count()) {
166 SkASSERT(!head->wasDestroyed()); 175 GrGpuResource* back = *(fNonpurgeableResources.end() - 1);
167 head->cacheAccess().release(); 176 SkASSERT(!back->wasDestroyed());
168 // release should have already removed this from the list. 177 back->cacheAccess().release();
169 SkASSERT(head != fResources.head());
170 } 178 }
179
180 while (fPurgeableQueue.count()) {
181 GrGpuResource* top = fPurgeableQueue.peek();
182 SkASSERT(!top->wasDestroyed());
183 top->cacheAccess().release();
184 }
185
171 SkASSERT(!fScratchMap.count()); 186 SkASSERT(!fScratchMap.count());
187 SkASSERT(!fContentHash.count());
172 SkASSERT(!fCount); 188 SkASSERT(!fCount);
189 SkASSERT(!this->getResourceCount());
173 SkASSERT(!fBytes); 190 SkASSERT(!fBytes);
174 SkASSERT(!fBudgetedCount); 191 SkASSERT(!fBudgetedCount);
175 SkASSERT(!fBudgetedBytes); 192 SkASSERT(!fBudgetedBytes);
176 } 193 }
177 194
178 class GrResourceCache::AvailableForScratchUse { 195 class GrResourceCache::AvailableForScratchUse {
179 public: 196 public:
180 AvailableForScratchUse(bool rejectPendingIO) : fRejectPendingIO(rejectPendin gIO) { } 197 AvailableForScratchUse(bool rejectPendingIO) : fRejectPendingIO(rejectPendin gIO) { }
181 198
182 bool operator()(const GrGpuResource* resource) const { 199 bool operator()(const GrGpuResource* resource) const {
(...skipping 12 matching lines...) Expand all
195 SkASSERT(scratchKey.isValid()); 212 SkASSERT(scratchKey.isValid());
196 213
197 GrGpuResource* resource; 214 GrGpuResource* resource;
198 if (flags & (kPreferNoPendingIO_ScratchFlag | kRequireNoPendingIO_ScratchFla g)) { 215 if (flags & (kPreferNoPendingIO_ScratchFlag | kRequireNoPendingIO_ScratchFla g)) {
199 resource = fScratchMap.find(scratchKey, AvailableForScratchUse(true)); 216 resource = fScratchMap.find(scratchKey, AvailableForScratchUse(true));
200 if (resource) { 217 if (resource) {
201 this->refAndMakeResourceMRU(resource); 218 this->refAndMakeResourceMRU(resource);
202 this->validate(); 219 this->validate();
203 return resource; 220 return resource;
204 } else if (flags & kRequireNoPendingIO_ScratchFlag) { 221 } else if (flags & kRequireNoPendingIO_ScratchFlag) {
205 return NULL; 222 return NULL;
robertphillips 2015/02/17 18:32:23 Don't we really want to check that the new resourc
bsalomon 2015/02/17 19:32:51 I think so, but there is no way to do that current
223 } else if (this->underBudget()) {
224 // Our flags said to prefer no pending IO and there is still room in the cache. Return
225 // NULL to allow the caller to create a new resource.
226 return NULL;
206 } 227 }
207 // TODO: fail here when kPrefer is specified, we didn't find a resource without pending io,
208 // but there is still space in our budget for the resource.
209 } 228 }
210 resource = fScratchMap.find(scratchKey, AvailableForScratchUse(false)); 229 resource = fScratchMap.find(scratchKey, AvailableForScratchUse(false));
211 if (resource) { 230 if (resource) {
212 this->refAndMakeResourceMRU(resource); 231 this->refAndMakeResourceMRU(resource);
213 this->validate(); 232 this->validate();
214 } 233 }
215 return resource; 234 return resource;
216 } 235 }
217 236
218 void GrResourceCache::willRemoveScratchKey(const GrGpuResource* resource) { 237 void GrResourceCache::willRemoveScratchKey(const GrGpuResource* resource) {
(...skipping 22 matching lines...) Expand all
241 this->validate(); 260 this->validate();
242 return true; 261 return true;
243 } 262 }
244 263
245 void GrResourceCache::refAndMakeResourceMRU(GrGpuResource* resource) { 264 void GrResourceCache::refAndMakeResourceMRU(GrGpuResource* resource) {
246 SkASSERT(resource); 265 SkASSERT(resource);
247 SkASSERT(this->isInCache(resource)); 266 SkASSERT(this->isInCache(resource));
248 if (resource->isPurgeable()) { 267 if (resource->isPurgeable()) {
249 // It's about to become unpurgeable. 268 // It's about to become unpurgeable.
250 fPurgeableQueue.remove(resource); 269 fPurgeableQueue.remove(resource);
270 this->addToNonpurgeableArray(resource);
251 } 271 }
252 resource->ref(); 272 resource->ref();
253 resource->cacheAccess().setTimestamp(fTimestamp++); 273 resource->cacheAccess().setTimestamp(fTimestamp++);
254 SkASSERT(!resource->isPurgeable()); 274 this->validate();
255 } 275 }
256 276
257 void GrResourceCache::notifyPurgeable(GrGpuResource* resource) { 277 void GrResourceCache::notifyPurgeable(GrGpuResource* resource) {
258 SkASSERT(resource); 278 SkASSERT(resource);
259 SkASSERT(this->isInCache(resource)); 279 SkASSERT(this->isInCache(resource));
260 SkASSERT(resource->isPurgeable()); 280 SkASSERT(resource->isPurgeable());
261 281
262 SkASSERT(-1 == *resource->cacheAccess().accessCacheIndex()); 282 this->removeFromNonpurgeableArray(resource);
263 fPurgeableQueue.insert(resource); 283 fPurgeableQueue.insert(resource);
264 284
265 if (!resource->resourcePriv().isBudgeted()) { 285 if (!resource->resourcePriv().isBudgeted()) {
266 // Check whether this resource could still be used as a scratch resource . 286 // Check whether this resource could still be used as a scratch resource .
267 if (!resource->cacheAccess().isWrapped() && 287 if (!resource->cacheAccess().isWrapped() &&
268 resource->resourcePriv().getScratchKey().isValid()) { 288 resource->resourcePriv().getScratchKey().isValid()) {
269 // We won't purge an existing resource to make room for this one. 289 // We won't purge an existing resource to make room for this one.
270 bool underBudget = fBudgetedCount < fMaxCount && 290 if (this->underBudget()) {
271 fBudgetedBytes + resource->gpuMemorySize() <= fM axBytes;
272 if (underBudget) {
273 resource->resourcePriv().makeBudgeted(); 291 resource->resourcePriv().makeBudgeted();
274 return; 292 return;
275 } 293 }
276 } 294 }
277 } else { 295 } else {
278 // Purge the resource immediately if we're over budget 296 // Purge the resource immediately if we're over budget
279 bool overBudget = fBudgetedCount > fMaxCount || fBudgetedBytes > fMaxByt es;
280
281 // Also purge if the resource has neither a valid scratch key nor a cont ent key. 297 // Also purge if the resource has neither a valid scratch key nor a cont ent key.
282 bool noKey = !resource->resourcePriv().getScratchKey().isValid() && 298 bool noKey = !resource->resourcePriv().getScratchKey().isValid() &&
283 !resource->getContentKey().isValid(); 299 !resource->getContentKey().isValid();
284 if (!overBudget && !noKey) { 300 if (!this->overBudget() && !noKey) {
285 return; 301 return;
286 } 302 }
287 } 303 }
288 304
289 SkDEBUGCODE(int beforeCount = fCount;) 305 SkDEBUGCODE(int beforeCount = this->getResourceCount();)
290 resource->cacheAccess().release(); 306 resource->cacheAccess().release();
291 // We should at least free this resource, perhaps dependent resources as wel l. 307 // We should at least free this resource, perhaps dependent resources as wel l.
292 SkASSERT(fCount < beforeCount); 308 SkASSERT(this->getResourceCount() < beforeCount);
293 this->validate(); 309 this->validate();
294 } 310 }
295 311
296 void GrResourceCache::didChangeGpuMemorySize(const GrGpuResource* resource, size _t oldSize) { 312 void GrResourceCache::didChangeGpuMemorySize(const GrGpuResource* resource, size _t oldSize) {
297 // SkASSERT(!fPurging); GrPathRange increases size during flush. :( 313 // SkASSERT(!fPurging); GrPathRange increases size during flush. :(
298 SkASSERT(resource); 314 SkASSERT(resource);
299 SkASSERT(this->isInCache(resource)); 315 SkASSERT(this->isInCache(resource));
300 316
301 ptrdiff_t delta = resource->gpuMemorySize() - oldSize; 317 ptrdiff_t delta = resource->gpuMemorySize() - oldSize;
302 318
(...skipping 28 matching lines...) Expand all
331 this->purgeAsNeeded(); 347 this->purgeAsNeeded();
332 } else { 348 } else {
333 --fBudgetedCount; 349 --fBudgetedCount;
334 fBudgetedBytes -= size; 350 fBudgetedBytes -= size;
335 } 351 }
336 352
337 this->validate(); 353 this->validate();
338 } 354 }
339 355
340 void GrResourceCache::internalPurgeAsNeeded() { 356 void GrResourceCache::internalPurgeAsNeeded() {
341 SkASSERT(fBudgetedCount > fMaxCount || fBudgetedBytes > fMaxBytes); 357 SkASSERT(this->overBudget());
342 358
343 bool stillOverbudget = true; 359 bool stillOverbudget = true;
344 while (fPurgeableQueue.count()) { 360 while (fPurgeableQueue.count()) {
345 GrGpuResource* resource = fPurgeableQueue.peek(); 361 GrGpuResource* resource = fPurgeableQueue.peek();
346 SkASSERT(resource->isPurgeable()); 362 SkASSERT(resource->isPurgeable());
347 resource->cacheAccess().release(); 363 resource->cacheAccess().release();
348 if (fBudgetedCount <= fMaxCount && fBudgetedBytes <= fMaxBytes) { 364 if (!this->overBudget()) {
349 stillOverbudget = false; 365 stillOverbudget = false;
350 break; 366 break;
351 } 367 }
352 } 368 }
353 369
354 this->validate(); 370 this->validate();
355 371
356 if (stillOverbudget) { 372 if (stillOverbudget) {
357 // Despite the purge we're still over budget. Call our over budget callb ack. If this frees 373 // Despite the purge we're still over budget. Call our over budget callb ack. If this frees
358 // any resources then we'll get notifyPurgeable() calls and take appropr iate action. 374 // any resources then we'll get notifyPurgeable() calls and take appropr iate action.
(...skipping 16 matching lines...) Expand all
375 const SkTArray<GrContentKeyInvalidatedMessage>& msgs) { 391 const SkTArray<GrContentKeyInvalidatedMessage>& msgs) {
376 for (int i = 0; i < msgs.count(); ++i) { 392 for (int i = 0; i < msgs.count(); ++i) {
377 GrGpuResource* resource = this->findAndRefContentResource(msgs[i].key()) ; 393 GrGpuResource* resource = this->findAndRefContentResource(msgs[i].key()) ;
378 if (resource) { 394 if (resource) {
379 resource->resourcePriv().removeContentKey(); 395 resource->resourcePriv().removeContentKey();
380 resource->unref(); // will call notifyPurgeable, if it is indeed now purgeable. 396 resource->unref(); // will call notifyPurgeable, if it is indeed now purgeable.
381 } 397 }
382 } 398 }
383 } 399 }
384 400
401 void GrResourceCache::addToNonpurgeableArray(GrGpuResource* resource) {
402 int index = fNonpurgeableResources.count();
403 *fNonpurgeableResources.append() = resource;
404 *resource->cacheAccess().accessCacheIndex() = index;
405 }
406
407 void GrResourceCache::removeFromNonpurgeableArray(GrGpuResource* resource) {
408 int* index = resource->cacheAccess().accessCacheIndex();
409 // Fill the whole we will create in the array with the tail object, adjust i ts index, and
410 // then pop the array
411 GrGpuResource* tail = *(fNonpurgeableResources.end() - 1);
412 SkASSERT(fNonpurgeableResources[*index] == resource);
413 fNonpurgeableResources[*index] = tail;
414 *tail->cacheAccess().accessCacheIndex() = *index;
415 fNonpurgeableResources.pop();
416 SkDEBUGCODE(*index = -1);
417 }
418
385 #ifdef SK_DEBUG 419 #ifdef SK_DEBUG
386 void GrResourceCache::validate() const { 420 void GrResourceCache::validate() const {
387 // Reduce the frequency of validations for large resource counts. 421 // Reduce the frequency of validations for large resource counts.
388 static SkRandom gRandom; 422 static SkRandom gRandom;
389 int mask = (SkNextPow2(fCount + 1) >> 5) - 1; 423 int mask = (SkNextPow2(fCount + 1) >> 5) - 1;
390 if (~mask && (gRandom.nextU() & mask)) { 424 if (~mask && (gRandom.nextU() & mask)) {
391 return; 425 return;
392 } 426 }
393 427
394 size_t bytes = 0; 428 struct Stats {
395 int count = 0; 429 size_t fBytes;
396 int budgetedCount = 0; 430 int fBudgetedCount;
397 size_t budgetedBytes = 0; 431 size_t fBudgetedBytes;
398 int locked = 0; 432 int fLocked;
399 int scratch = 0; 433 int fScratch;
400 int couldBeScratch = 0; 434 int fCouldBeScratch;
401 int content = 0; 435 int fContent;
436 const ScratchMap* fScratchMap;
437 const ContentHash* fContentHash;
402 438
403 ResourceList::Iter iter; 439 Stats(const GrResourceCache* cache) {
404 GrGpuResource* resource = iter.init(fResources, ResourceList::Iter::kHead_It erStart); 440 memset(this, 0, sizeof(*this));
405 for ( ; resource; resource = iter.next()) { 441 fScratchMap = &cache->fScratchMap;
406 bytes += resource->gpuMemorySize(); 442 fContentHash = &cache->fContentHash;
407 ++count;
408
409 if (!resource->isPurgeable()) {
410 ++locked;
411 } 443 }
412 444
413 if (resource->cacheAccess().isScratch()) { 445 void update(GrGpuResource* resource) {
414 SkASSERT(!resource->getContentKey().isValid()); 446 fBytes += resource->gpuMemorySize();
415 ++scratch; 447
416 SkASSERT(fScratchMap.countForKey(resource->resourcePriv().getScratch Key())); 448 if (!resource->isPurgeable()) {
417 SkASSERT(!resource->cacheAccess().isWrapped()); 449 ++fLocked;
418 } else if (resource->resourcePriv().getScratchKey().isValid()) { 450 }
419 SkASSERT(!resource->resourcePriv().isBudgeted() || 451
420 resource->getContentKey().isValid()); 452 if (resource->cacheAccess().isScratch()) {
421 ++couldBeScratch; 453 SkASSERT(!resource->getContentKey().isValid());
422 SkASSERT(fScratchMap.countForKey(resource->resourcePriv().getScratch Key())); 454 ++fScratch;
423 SkASSERT(!resource->cacheAccess().isWrapped()); 455 SkASSERT(fScratchMap->countForKey(resource->resourcePriv().getSc ratchKey()));
456 SkASSERT(!resource->cacheAccess().isWrapped());
457 } else if (resource->resourcePriv().getScratchKey().isValid()) {
458 SkASSERT(!resource->resourcePriv().isBudgeted() ||
459 resource->getContentKey().isValid());
460 ++fCouldBeScratch;
461 SkASSERT(fScratchMap->countForKey(resource->resourcePriv().getSc ratchKey()));
462 SkASSERT(!resource->cacheAccess().isWrapped());
463 }
464 const GrContentKey& contentKey = resource->getContentKey();
465 if (contentKey.isValid()) {
466 ++fContent;
467 SkASSERT(fContentHash->find(contentKey) == resource);
468 SkASSERT(!resource->cacheAccess().isWrapped());
469 SkASSERT(resource->resourcePriv().isBudgeted());
470 }
471
472 if (resource->resourcePriv().isBudgeted()) {
473 ++fBudgetedCount;
474 fBudgetedBytes += resource->gpuMemorySize();
475 }
424 } 476 }
425 const GrContentKey& contentKey = resource->getContentKey(); 477 };
426 if (contentKey.isValid()) {
427 ++content;
428 SkASSERT(fContentHash.find(contentKey) == resource);
429 SkASSERT(!resource->cacheAccess().isWrapped());
430 SkASSERT(resource->resourcePriv().isBudgeted());
431 }
432 478
433 if (resource->resourcePriv().isBudgeted()) { 479 Stats stats(this);
434 ++budgetedCount;
435 budgetedBytes += resource->gpuMemorySize();
436 }
437 480
438 if (!resource->isPurgeable()) { 481 for (int i = 0; i < fNonpurgeableResources.count(); ++i) {
439 SkASSERT(-1 == *resource->cacheAccess().accessCacheIndex()); 482 SkASSERT(!fNonpurgeableResources[i]->isPurgeable());
440 } 483 SkASSERT(*fNonpurgeableResources[i]->cacheAccess().accessCacheIndex() == i);
484 SkASSERT(!fNonpurgeableResources[i]->wasDestroyed());
485 stats.update(fNonpurgeableResources[i]);
486 }
487 for (int i = 0; i < fPurgeableQueue.count(); ++i) {
488 SkASSERT(fPurgeableQueue.at(i)->isPurgeable());
489 SkASSERT(*fPurgeableQueue.at(i)->cacheAccess().accessCacheIndex() == i);
490 SkASSERT(!fPurgeableQueue.at(i)->wasDestroyed());
491 stats.update(fPurgeableQueue.at(i));
441 } 492 }
442 493
443 for (int i = 0; i < fPurgeableQueue.count(); ++i) { 494 SkASSERT(fCount == this->getResourceCount());
444 SkASSERT(fPurgeableQueue.at(i)->isPurgeable());
445 }
446
447 SkASSERT(fCount - locked == fPurgeableQueue.count());
448 SkASSERT(fBudgetedCount <= fCount); 495 SkASSERT(fBudgetedCount <= fCount);
449 SkASSERT(fBudgetedBytes <= fBudgetedBytes); 496 SkASSERT(fBudgetedBytes <= fBytes);
450 SkASSERT(bytes == fBytes); 497 SkASSERT(stats.fBytes == fBytes);
451 SkASSERT(count == fCount); 498 SkASSERT(stats.fBudgetedBytes == fBudgetedBytes);
452 SkASSERT(budgetedBytes == fBudgetedBytes); 499 SkASSERT(stats.fBudgetedCount == fBudgetedCount);
453 SkASSERT(budgetedCount == fBudgetedCount);
454 #if GR_CACHE_STATS 500 #if GR_CACHE_STATS
455 SkASSERT(fBudgetedHighWaterCount <= fHighWaterCount); 501 SkASSERT(fBudgetedHighWaterCount <= fHighWaterCount);
456 SkASSERT(fBudgetedHighWaterBytes <= fHighWaterBytes); 502 SkASSERT(fBudgetedHighWaterBytes <= fHighWaterBytes);
457 SkASSERT(bytes <= fHighWaterBytes); 503 SkASSERT(fBytes <= fHighWaterBytes);
458 SkASSERT(count <= fHighWaterCount); 504 SkASSERT(fCount <= fHighWaterCount);
459 SkASSERT(budgetedBytes <= fBudgetedHighWaterBytes); 505 SkASSERT(fBudgetedBytes <= fBudgetedHighWaterBytes);
460 SkASSERT(budgetedCount <= fBudgetedHighWaterCount); 506 SkASSERT(fBudgetedCount <= fBudgetedHighWaterCount);
461 #endif 507 #endif
462 SkASSERT(content == fContentHash.count()); 508 SkASSERT(stats.fContent == fContentHash.count());
463 SkASSERT(scratch + couldBeScratch == fScratchMap.count()); 509 SkASSERT(stats.fScratch + stats.fCouldBeScratch == fScratchMap.count());
464 510
465 // This assertion is not currently valid because we can be in recursive noti fyIsPurgeable() 511 // This assertion is not currently valid because we can be in recursive noti fyIsPurgeable()
466 // calls. This will be fixed when subresource registration is explicit. 512 // calls. This will be fixed when subresource registration is explicit.
467 // bool overBudget = budgetedBytes > fMaxBytes || budgetedCount > fMaxCount; 513 // bool overBudget = budgetedBytes > fMaxBytes || budgetedCount > fMaxCount;
468 // SkASSERT(!overBudget || locked == count || fPurging); 514 // SkASSERT(!overBudget || locked == count || fPurging);
469 } 515 }
516
517 bool GrResourceCache::isInCache(const GrGpuResource* resource) const {
518 int index = *resource->cacheAccess().accessCacheIndex();
519 if (index < 0) {
520 return false;
521 }
522 if (index < fPurgeableQueue.count() && fPurgeableQueue.at(index) == resource ) {
523 return true;
524 }
525 if (index < fNonpurgeableResources.count() && fNonpurgeableResources[index] == resource) {
526 return true;
527 }
robertphillips 2015/02/17 18:32:23 Shouldn't we assert here?
bsalomon 2015/02/17 19:32:51 Hm, I suppose so.
528 return false;
529 }
530
470 #endif 531 #endif
OLDNEW
« src/gpu/GrResourceCache.h ('K') | « src/gpu/GrResourceCache.h ('k') | src/gpu/GrTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698