OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2010 Google Inc. | 3 * Copyright 2010 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 | 10 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 } | 75 } |
76 | 76 |
77 /////////////////////////////////////////////////////////////////////////////// | 77 /////////////////////////////////////////////////////////////////////////////// |
78 | 78 |
79 GrResourceCache::GrResourceCache(int maxCount, size_t maxBytes) : | 79 GrResourceCache::GrResourceCache(int maxCount, size_t maxBytes) : |
80 fMaxCount(maxCount), | 80 fMaxCount(maxCount), |
81 fMaxBytes(maxBytes) { | 81 fMaxBytes(maxBytes) { |
82 #if GR_CACHE_STATS | 82 #if GR_CACHE_STATS |
83 fHighWaterEntryCount = 0; | 83 fHighWaterEntryCount = 0; |
84 fHighWaterEntryBytes = 0; | 84 fHighWaterEntryBytes = 0; |
| 85 fHighWaterClientDetachedCount = 0; |
| 86 fHighWaterClientDetachedBytes = 0; |
85 #endif | 87 #endif |
86 | 88 |
87 fEntryCount = 0; | 89 fEntryCount = 0; |
88 fEntryBytes = 0; | 90 fEntryBytes = 0; |
| 91 fClientDetachedCount = 0; |
| 92 fClientDetachedBytes = 0; |
89 | 93 |
90 fPurging = false; | 94 fPurging = false; |
91 | 95 |
92 fOverbudgetCB = NULL; | 96 fOverbudgetCB = NULL; |
93 fOverbudgetData = NULL; | 97 fOverbudgetData = NULL; |
94 } | 98 } |
95 | 99 |
96 GrResourceCache::~GrResourceCache() { | 100 GrResourceCache::~GrResourceCache() { |
97 GrAutoResourceCacheValidate atcv(this); | 101 GrAutoResourceCacheValidate atcv(this); |
98 | 102 |
(...skipping 26 matching lines...) Expand all Loading... |
125 bool smaller = (maxResources < fMaxCount) || (maxResourceBytes < fMaxBytes); | 129 bool smaller = (maxResources < fMaxCount) || (maxResourceBytes < fMaxBytes); |
126 | 130 |
127 fMaxCount = maxResources; | 131 fMaxCount = maxResources; |
128 fMaxBytes = maxResourceBytes; | 132 fMaxBytes = maxResourceBytes; |
129 | 133 |
130 if (smaller) { | 134 if (smaller) { |
131 this->purgeAsNeeded(); | 135 this->purgeAsNeeded(); |
132 } | 136 } |
133 } | 137 } |
134 | 138 |
135 void GrResourceCache::internalDetach(GrResourceCacheEntry* entry) { | 139 void GrResourceCache::internalDetach(GrResourceCacheEntry* entry, |
| 140 BudgetBehaviors behavior) { |
136 fList.remove(entry); | 141 fList.remove(entry); |
137 fEntryCount -= 1; | 142 |
138 fEntryBytes -= entry->fCachedSize; | 143 // update our stats |
| 144 if (kIgnore_BudgetBehavior == behavior) { |
| 145 fClientDetachedCount += 1; |
| 146 fClientDetachedBytes += entry->fCachedSize; |
| 147 |
| 148 #if GR_CACHE_STATS |
| 149 if (fHighWaterClientDetachedCount < fClientDetachedCount) { |
| 150 fHighWaterClientDetachedCount = fClientDetachedCount; |
| 151 } |
| 152 if (fHighWaterClientDetachedBytes < fClientDetachedBytes) { |
| 153 fHighWaterClientDetachedBytes = fClientDetachedBytes; |
| 154 } |
| 155 #endif |
| 156 |
| 157 } else { |
| 158 SkASSERT(kAccountFor_BudgetBehavior == behavior); |
| 159 |
| 160 fEntryCount -= 1; |
| 161 fEntryBytes -= entry->fCachedSize; |
| 162 } |
139 } | 163 } |
140 | 164 |
141 void GrResourceCache::attachToHead(GrResourceCacheEntry* entry) { | 165 void GrResourceCache::attachToHead(GrResourceCacheEntry* entry, |
| 166 BudgetBehaviors behavior) { |
142 fList.addToHead(entry); | 167 fList.addToHead(entry); |
143 | 168 |
144 fEntryCount += 1; | 169 // update our stats |
145 fEntryBytes += entry->fCachedSize; | 170 if (kIgnore_BudgetBehavior == behavior) { |
| 171 fClientDetachedCount -= 1; |
| 172 fClientDetachedBytes -= entry->fCachedSize; |
| 173 } else { |
| 174 SkASSERT(kAccountFor_BudgetBehavior == behavior); |
| 175 |
| 176 fEntryCount += 1; |
| 177 fEntryBytes += entry->fCachedSize; |
146 | 178 |
147 #if GR_CACHE_STATS | 179 #if GR_CACHE_STATS |
148 if (fHighWaterEntryCount < fEntryCount) { | 180 if (fHighWaterEntryCount < fEntryCount) { |
149 fHighWaterEntryCount = fEntryCount; | 181 fHighWaterEntryCount = fEntryCount; |
| 182 } |
| 183 if (fHighWaterEntryBytes < fEntryBytes) { |
| 184 fHighWaterEntryBytes = fEntryBytes; |
| 185 } |
| 186 #endif |
150 } | 187 } |
151 if (fHighWaterEntryBytes < fEntryBytes) { | |
152 fHighWaterEntryBytes = fEntryBytes; | |
153 } | |
154 #endif | |
155 } | 188 } |
156 | 189 |
157 // This functor just searches for an entry with only a single ref (from | 190 // This functor just searches for an entry with only a single ref (from |
158 // the texture cache itself). Presumably in this situation no one else | 191 // the texture cache itself). Presumably in this situation no one else |
159 // is relying on the texture. | 192 // is relying on the texture. |
160 class GrTFindUnreffedFunctor { | 193 class GrTFindUnreffedFunctor { |
161 public: | 194 public: |
162 bool operator()(const GrResourceCacheEntry* entry) const { | 195 bool operator()(const GrResourceCacheEntry* entry) const { |
163 return entry->resource()->isPurgable(); | 196 return entry->resource()->unique(); |
164 } | 197 } |
165 }; | 198 }; |
166 | 199 |
167 | 200 GrGpuResource* GrResourceCache::find(const GrResourceKey& key, uint32_t ownershi
pFlags) { |
168 void GrResourceCache::makeResourceMRU(GrGpuResource* resource) { | |
169 GrResourceCacheEntry* entry = resource->getCacheEntry(); | |
170 if (entry) { | |
171 this->internalDetach(entry); | |
172 this->attachToHead(entry); | |
173 } | |
174 } | |
175 | |
176 GrGpuResource* GrResourceCache::find(const GrResourceKey& key) { | |
177 GrAutoResourceCacheValidate atcv(this); | 201 GrAutoResourceCacheValidate atcv(this); |
178 | 202 |
179 GrResourceCacheEntry* entry = NULL; | 203 GrResourceCacheEntry* entry = NULL; |
180 | 204 |
181 entry = fCache.find(key); | 205 if (ownershipFlags & kNoOtherOwners_OwnershipFlag) { |
| 206 GrTFindUnreffedFunctor functor; |
| 207 |
| 208 entry = fCache.find<GrTFindUnreffedFunctor>(key, functor); |
| 209 } else { |
| 210 entry = fCache.find(key); |
| 211 } |
182 | 212 |
183 if (NULL == entry) { | 213 if (NULL == entry) { |
184 return NULL; | 214 return NULL; |
185 } | 215 } |
186 | 216 |
187 // Make this resource MRU | 217 if (ownershipFlags & kHide_OwnershipFlag) { |
188 this->internalDetach(entry); | 218 this->makeExclusive(entry); |
189 this->attachToHead(entry); | 219 } else { |
| 220 // Make this resource MRU |
| 221 this->internalDetach(entry); |
| 222 this->attachToHead(entry); |
| 223 } |
190 | 224 |
191 // GrResourceCache2 is responsible for scratch resources. | |
192 SkASSERT(GrIORef::kNo_IsScratch == entry->resource()->fIsScratch); | |
193 return entry->fResource; | 225 return entry->fResource; |
194 } | 226 } |
195 | 227 |
196 void GrResourceCache::addResource(const GrResourceKey& key, GrGpuResource* resou
rce) { | 228 void GrResourceCache::addResource(const GrResourceKey& key, |
| 229 GrGpuResource* resource, |
| 230 uint32_t ownershipFlags) { |
197 SkASSERT(NULL == resource->getCacheEntry()); | 231 SkASSERT(NULL == resource->getCacheEntry()); |
198 // we don't expect to create new resources during a purge. In theory | 232 // we don't expect to create new resources during a purge. In theory |
199 // this could cause purgeAsNeeded() into an infinite loop (e.g. | 233 // this could cause purgeAsNeeded() into an infinite loop (e.g. |
200 // each resource destroyed creates and locks 2 resources and | 234 // each resource destroyed creates and locks 2 resources and |
201 // unlocks 1 thereby causing a new purge). | 235 // unlocks 1 thereby causing a new purge). |
202 SkASSERT(!fPurging); | 236 SkASSERT(!fPurging); |
203 GrAutoResourceCacheValidate atcv(this); | 237 GrAutoResourceCacheValidate atcv(this); |
204 | 238 |
205 GrResourceCacheEntry* entry = SkNEW_ARGS(GrResourceCacheEntry, (this, key, r
esource)); | 239 GrResourceCacheEntry* entry = SkNEW_ARGS(GrResourceCacheEntry, (this, key, r
esource)); |
206 resource->setCacheEntry(entry); | 240 resource->setCacheEntry(entry); |
207 | 241 |
208 this->attachToHead(entry); | 242 this->attachToHead(entry); |
209 fCache.insert(key, entry); | 243 fCache.insert(key, entry); |
| 244 |
| 245 if (ownershipFlags & kHide_OwnershipFlag) { |
| 246 this->makeExclusive(entry); |
| 247 } |
| 248 |
| 249 } |
| 250 |
| 251 void GrResourceCache::makeExclusive(GrResourceCacheEntry* entry) { |
| 252 GrAutoResourceCacheValidate atcv(this); |
| 253 |
| 254 SkASSERT(!entry->fIsExclusive); |
| 255 entry->fIsExclusive = true; |
| 256 |
| 257 // When scratch textures are detached (to hide them from future finds) they |
| 258 // still count against the resource budget |
| 259 this->internalDetach(entry, kIgnore_BudgetBehavior); |
| 260 fCache.remove(entry->key(), entry); |
| 261 |
| 262 #ifdef SK_DEBUG |
| 263 fExclusiveList.addToHead(entry); |
| 264 #endif |
| 265 } |
| 266 |
| 267 void GrResourceCache::removeInvalidResource(GrResourceCacheEntry* entry) { |
| 268 // If the resource went invalid while it was detached then purge it |
| 269 // This can happen when a 3D context was lost, |
| 270 // the client called GrContext::abandonContext() to notify Gr, |
| 271 // and then later an SkGpuDevice's destructor releases its backing |
| 272 // texture (which was invalidated at contextDestroyed time). |
| 273 // TODO: Safely delete the GrResourceCacheEntry as well. |
| 274 fClientDetachedCount -= 1; |
| 275 fEntryCount -= 1; |
| 276 fClientDetachedBytes -= entry->fCachedSize; |
| 277 fEntryBytes -= entry->fCachedSize; |
| 278 entry->fCachedSize = 0; |
| 279 } |
| 280 |
| 281 void GrResourceCache::makeNonExclusive(GrResourceCacheEntry* entry) { |
| 282 GrAutoResourceCacheValidate atcv(this); |
| 283 |
| 284 #ifdef SK_DEBUG |
| 285 fExclusiveList.remove(entry); |
| 286 #endif |
| 287 |
| 288 if (!entry->resource()->wasDestroyed()) { |
| 289 // Since scratch textures still count against the cache budget even |
| 290 // when they have been removed from the cache, re-adding them doesn't |
| 291 // alter the budget information. |
| 292 attachToHead(entry, kIgnore_BudgetBehavior); |
| 293 fCache.insert(entry->key(), entry); |
| 294 |
| 295 SkASSERT(entry->fIsExclusive); |
| 296 entry->fIsExclusive = false; |
| 297 } else { |
| 298 this->removeInvalidResource(entry); |
| 299 } |
210 } | 300 } |
211 | 301 |
212 void GrResourceCache::didIncreaseResourceSize(const GrResourceCacheEntry* entry,
size_t amountInc) { | 302 void GrResourceCache::didIncreaseResourceSize(const GrResourceCacheEntry* entry,
size_t amountInc) { |
213 fEntryBytes += amountInc; | 303 fEntryBytes += amountInc; |
| 304 if (entry->fIsExclusive) { |
| 305 fClientDetachedBytes += amountInc; |
| 306 } |
214 this->purgeAsNeeded(); | 307 this->purgeAsNeeded(); |
215 } | 308 } |
216 | 309 |
217 void GrResourceCache::didDecreaseResourceSize(const GrResourceCacheEntry* entry,
size_t amountDec) { | 310 void GrResourceCache::didDecreaseResourceSize(const GrResourceCacheEntry* entry,
size_t amountDec) { |
218 fEntryBytes -= amountDec; | 311 fEntryBytes -= amountDec; |
| 312 if (entry->fIsExclusive) { |
| 313 fClientDetachedBytes -= amountDec; |
| 314 } |
219 #ifdef SK_DEBUG | 315 #ifdef SK_DEBUG |
220 this->validate(); | 316 this->validate(); |
221 #endif | 317 #endif |
222 } | 318 } |
223 | 319 |
224 /** | 320 /** |
225 * Destroying a resource may potentially trigger the unlock of additional | 321 * Destroying a resource may potentially trigger the unlock of additional |
226 * resources which in turn will trigger a nested purge. We block the nested | 322 * resources which in turn will trigger a nested purge. We block the nested |
227 * purge using the fPurging variable. However, the initial purge will keep | 323 * purge using the fPurging variable. However, the initial purge will keep |
228 * looping until either all resources in the cache are unlocked or we've met | 324 * looping until either all resources in the cache are unlocked or we've met |
(...skipping 27 matching lines...) Expand all Loading... |
256 } | 352 } |
257 | 353 |
258 fPurging = false; | 354 fPurging = false; |
259 } | 355 } |
260 | 356 |
261 void GrResourceCache::purgeInvalidated() { | 357 void GrResourceCache::purgeInvalidated() { |
262 SkTDArray<GrResourceInvalidatedMessage> invalidated; | 358 SkTDArray<GrResourceInvalidatedMessage> invalidated; |
263 fInvalidationInbox.poll(&invalidated); | 359 fInvalidationInbox.poll(&invalidated); |
264 | 360 |
265 for (int i = 0; i < invalidated.count(); i++) { | 361 for (int i = 0; i < invalidated.count(); i++) { |
| 362 // We're somewhat missing an opportunity here. We could use the |
| 363 // default find functor that gives us back resources whether we own |
| 364 // them exclusively or not, and when they're not exclusively owned mark |
| 365 // them for purging later when they do become exclusively owned. |
| 366 // |
| 367 // This is complicated and confusing. May try this in the future. For |
| 368 // now, these resources are just LRU'd as if we never got the message. |
266 while (GrResourceCacheEntry* entry = fCache.find(invalidated[i].key, GrT
FindUnreffedFunctor())) { | 369 while (GrResourceCacheEntry* entry = fCache.find(invalidated[i].key, GrT
FindUnreffedFunctor())) { |
267 this->deleteResource(entry); | 370 this->deleteResource(entry); |
268 } | 371 } |
269 } | 372 } |
270 } | 373 } |
271 | 374 |
272 void GrResourceCache::deleteResource(GrResourceCacheEntry* entry) { | 375 void GrResourceCache::deleteResource(GrResourceCacheEntry* entry) { |
273 SkASSERT(entry->fResource->isPurgable()); | 376 SkASSERT(entry->fResource->unique()); |
274 | 377 |
275 // remove from our cache | 378 // remove from our cache |
276 fCache.remove(entry->key(), entry); | 379 fCache.remove(entry->key(), entry); |
277 | 380 |
278 // remove from our llist | 381 // remove from our llist |
279 this->internalDetach(entry); | 382 this->internalDetach(entry); |
280 delete entry; | 383 delete entry; |
281 } | 384 } |
282 | 385 |
283 void GrResourceCache::internalPurge(int extraCount, size_t extraBytes) { | 386 void GrResourceCache::internalPurge(int extraCount, size_t extraBytes) { |
(...skipping 18 matching lines...) Expand all Loading... |
302 while (entry) { | 405 while (entry) { |
303 GrAutoResourceCacheValidate atcv(this); | 406 GrAutoResourceCacheValidate atcv(this); |
304 | 407 |
305 if ((fEntryCount+extraCount) <= fMaxCount && | 408 if ((fEntryCount+extraCount) <= fMaxCount && |
306 (fEntryBytes+extraBytes) <= fMaxBytes) { | 409 (fEntryBytes+extraBytes) <= fMaxBytes) { |
307 withinBudget = true; | 410 withinBudget = true; |
308 break; | 411 break; |
309 } | 412 } |
310 | 413 |
311 GrResourceCacheEntry* prev = iter.prev(); | 414 GrResourceCacheEntry* prev = iter.prev(); |
312 if (entry->fResource->isPurgable()) { | 415 if (entry->fResource->unique()) { |
313 changed = true; | 416 changed = true; |
314 this->deleteResource(entry); | 417 this->deleteResource(entry); |
315 } | 418 } |
316 entry = prev; | 419 entry = prev; |
317 } | 420 } |
318 } while (!withinBudget && changed); | 421 } while (!withinBudget && changed); |
319 } | 422 } |
320 | 423 |
321 void GrResourceCache::purgeAllUnlocked() { | 424 void GrResourceCache::purgeAllUnlocked() { |
322 GrAutoResourceCacheValidate atcv(this); | 425 GrAutoResourceCacheValidate atcv(this); |
323 | 426 |
324 // we can have one GrCacheable holding a lock on another | 427 // we can have one GrCacheable holding a lock on another |
325 // so we don't want to just do a simple loop kicking each | 428 // so we don't want to just do a simple loop kicking each |
326 // entry out. Instead change the budget and purge. | 429 // entry out. Instead change the budget and purge. |
327 | 430 |
328 size_t savedMaxBytes = fMaxBytes; | 431 size_t savedMaxBytes = fMaxBytes; |
329 int savedMaxCount = fMaxCount; | 432 int savedMaxCount = fMaxCount; |
330 fMaxBytes = (size_t) -1; | 433 fMaxBytes = (size_t) -1; |
331 fMaxCount = 0; | 434 fMaxCount = 0; |
332 this->purgeAsNeeded(); | 435 this->purgeAsNeeded(); |
333 | 436 |
334 #ifdef SK_DEBUG | 437 #ifdef SK_DEBUG |
| 438 SkASSERT(fExclusiveList.countEntries() == fClientDetachedCount); |
| 439 SkASSERT(countBytes(fExclusiveList) == fClientDetachedBytes); |
335 if (!fCache.count()) { | 440 if (!fCache.count()) { |
| 441 // Items may have been detached from the cache (such as the backing |
| 442 // texture for an SkGpuDevice). The above purge would not have removed |
| 443 // them. |
| 444 SkASSERT(fEntryCount == fClientDetachedCount); |
| 445 SkASSERT(fEntryBytes == fClientDetachedBytes); |
336 SkASSERT(fList.isEmpty()); | 446 SkASSERT(fList.isEmpty()); |
337 } | 447 } |
338 #endif | 448 #endif |
339 | 449 |
340 fMaxBytes = savedMaxBytes; | 450 fMaxBytes = savedMaxBytes; |
341 fMaxCount = savedMaxCount; | 451 fMaxCount = savedMaxCount; |
342 } | 452 } |
343 | 453 |
344 /////////////////////////////////////////////////////////////////////////////// | 454 /////////////////////////////////////////////////////////////////////////////// |
345 | 455 |
(...skipping 11 matching lines...) Expand all Loading... |
357 } | 467 } |
358 return bytes; | 468 return bytes; |
359 } | 469 } |
360 | 470 |
361 static bool both_zero_or_nonzero(int count, size_t bytes) { | 471 static bool both_zero_or_nonzero(int count, size_t bytes) { |
362 return (count == 0 && bytes == 0) || (count > 0 && bytes > 0); | 472 return (count == 0 && bytes == 0) || (count > 0 && bytes > 0); |
363 } | 473 } |
364 | 474 |
365 void GrResourceCache::validate() const { | 475 void GrResourceCache::validate() const { |
366 fList.validate(); | 476 fList.validate(); |
| 477 fExclusiveList.validate(); |
367 SkASSERT(both_zero_or_nonzero(fEntryCount, fEntryBytes)); | 478 SkASSERT(both_zero_or_nonzero(fEntryCount, fEntryBytes)); |
368 SkASSERT(fEntryCount == fCache.count()); | 479 SkASSERT(both_zero_or_nonzero(fClientDetachedCount, fClientDetachedBytes)); |
| 480 SkASSERT(fClientDetachedBytes <= fEntryBytes); |
| 481 SkASSERT(fClientDetachedCount <= fEntryCount); |
| 482 SkASSERT((fEntryCount - fClientDetachedCount) == fCache.count()); |
369 | 483 |
370 EntryList::Iter iter; | 484 EntryList::Iter iter; |
371 | 485 |
| 486 // check that the exclusively held entries are okay |
| 487 const GrResourceCacheEntry* entry = iter.init(const_cast<EntryList&>(fExclus
iveList), |
| 488 EntryList::Iter::kHead_IterSta
rt); |
| 489 |
| 490 for ( ; entry; entry = iter.next()) { |
| 491 entry->validate(); |
| 492 } |
| 493 |
372 // check that the shareable entries are okay | 494 // check that the shareable entries are okay |
373 const GrResourceCacheEntry* entry = iter.init(const_cast<EntryList&>(fList), | 495 entry = iter.init(const_cast<EntryList&>(fList), EntryList::Iter::kHead_Iter
Start); |
374 EntryList::Iter::kHead_IterSta
rt); | |
375 | 496 |
376 int count = 0; | 497 int count = 0; |
377 for ( ; entry; entry = iter.next()) { | 498 for ( ; entry; entry = iter.next()) { |
378 entry->validate(); | 499 entry->validate(); |
379 SkASSERT(fCache.find(entry->key())); | 500 SkASSERT(fCache.find(entry->key())); |
380 count += 1; | 501 count += 1; |
381 } | 502 } |
382 SkASSERT(count == fEntryCount); | 503 SkASSERT(count == fEntryCount - fClientDetachedCount); |
383 | 504 |
384 size_t bytes = this->countBytes(fList); | 505 size_t bytes = countBytes(fList); |
385 SkASSERT(bytes == fEntryBytes); | 506 SkASSERT(bytes == fEntryBytes - fClientDetachedBytes); |
386 SkASSERT(fList.countEntries() == fEntryCount); | 507 |
| 508 bytes = countBytes(fExclusiveList); |
| 509 SkASSERT(bytes == fClientDetachedBytes); |
| 510 |
| 511 SkASSERT(fList.countEntries() == fEntryCount - fClientDetachedCount); |
| 512 |
| 513 SkASSERT(fExclusiveList.countEntries() == fClientDetachedCount); |
387 } | 514 } |
388 #endif // SK_DEBUG | 515 #endif // SK_DEBUG |
389 | 516 |
390 #if GR_CACHE_STATS | 517 #if GR_CACHE_STATS |
391 | 518 |
392 void GrResourceCache::printStats() { | 519 void GrResourceCache::printStats() { |
393 int locked = 0; | 520 int locked = 0; |
394 | 521 |
395 EntryList::Iter iter; | 522 EntryList::Iter iter; |
396 | 523 |
397 GrResourceCacheEntry* entry = iter.init(fList, EntryList::Iter::kTail_IterSt
art); | 524 GrResourceCacheEntry* entry = iter.init(fList, EntryList::Iter::kTail_IterSt
art); |
398 | 525 |
399 for ( ; entry; entry = iter.prev()) { | 526 for ( ; entry; entry = iter.prev()) { |
400 if (entry->fResource->getRefCnt() > 1) { | 527 if (entry->fResource->getRefCnt() > 1) { |
401 ++locked; | 528 ++locked; |
402 } | 529 } |
403 } | 530 } |
404 | 531 |
405 SkDebugf("Budget: %d items %d bytes\n", fMaxCount, fMaxBytes); | 532 SkDebugf("Budget: %d items %d bytes\n", fMaxCount, fMaxBytes); |
406 SkDebugf("\t\tEntry Count: current %d (%d locked) high %d\n", | 533 SkDebugf("\t\tEntry Count: current %d (%d locked) high %d\n", |
407 fEntryCount, locked, fHighWaterEntryCount); | 534 fEntryCount, locked, fHighWaterEntryCount); |
408 SkDebugf("\t\tEntry Bytes: current %d high %d\n", | 535 SkDebugf("\t\tEntry Bytes: current %d high %d\n", |
409 fEntryBytes, fHighWaterEntryBytes); | 536 fEntryBytes, fHighWaterEntryBytes); |
| 537 SkDebugf("\t\tDetached Entry Count: current %d high %d\n", |
| 538 fClientDetachedCount, fHighWaterClientDetachedCount); |
| 539 SkDebugf("\t\tDetached Bytes: current %d high %d\n", |
| 540 fClientDetachedBytes, fHighWaterClientDetachedBytes); |
410 } | 541 } |
411 | 542 |
412 #endif | 543 #endif |
413 | 544 |
414 /////////////////////////////////////////////////////////////////////////////// | 545 /////////////////////////////////////////////////////////////////////////////// |
OLD | NEW |