| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkChecksum.h" | 8 #include "SkChecksum.h" |
| 9 #include "SkScaledImageCache.h" | 9 #include "SkResourceCache.h" |
| 10 #include "SkMipMap.h" | 10 #include "SkMipMap.h" |
| 11 #include "SkPixelRef.h" | 11 #include "SkPixelRef.h" |
| 12 | 12 |
| 13 // This can be defined by the caller's build system | 13 // This can be defined by the caller's build system |
| 14 //#define SK_USE_DISCARDABLE_SCALEDIMAGECACHE | 14 //#define SK_USE_DISCARDABLE_SCALEDIMAGECACHE |
| 15 | 15 |
| 16 #ifndef SK_DISCARDABLEMEMORY_SCALEDIMAGECACHE_COUNT_LIMIT | 16 #ifndef SK_DISCARDABLEMEMORY_SCALEDIMAGECACHE_COUNT_LIMIT |
| 17 # define SK_DISCARDABLEMEMORY_SCALEDIMAGECACHE_COUNT_LIMIT 1024 | 17 # define SK_DISCARDABLEMEMORY_SCALEDIMAGECACHE_COUNT_LIMIT 1024 |
| 18 #endif | 18 #endif |
| 19 | 19 |
| 20 #ifndef SK_DEFAULT_IMAGE_CACHE_LIMIT | 20 #ifndef SK_DEFAULT_IMAGE_CACHE_LIMIT |
| 21 #define SK_DEFAULT_IMAGE_CACHE_LIMIT (2 * 1024 * 1024) | 21 #define SK_DEFAULT_IMAGE_CACHE_LIMIT (2 * 1024 * 1024) |
| 22 #endif | 22 #endif |
| 23 | 23 |
| 24 void SkScaledImageCache::Key::init(size_t length) { | 24 void SkResourceCache::Key::init(size_t length) { |
| 25 SkASSERT(SkAlign4(length) == length); | 25 SkASSERT(SkAlign4(length) == length); |
| 26 // 2 is fCount32 and fHash | 26 // 2 is fCount32 and fHash |
| 27 fCount32 = SkToS32(2 + (length >> 2)); | 27 fCount32 = SkToS32(2 + (length >> 2)); |
| 28 // skip both of our fields whe computing the murmur | 28 // skip both of our fields whe computing the murmur |
| 29 fHash = SkChecksum::Murmur3(this->as32() + 2, (fCount32 - 2) << 2); | 29 fHash = SkChecksum::Murmur3(this->as32() + 2, (fCount32 - 2) << 2); |
| 30 } | 30 } |
| 31 | 31 |
| 32 #include "SkTDynamicHash.h" | 32 #include "SkTDynamicHash.h" |
| 33 | 33 |
| 34 class SkScaledImageCache::Hash : | 34 class SkResourceCache::Hash : |
| 35 public SkTDynamicHash<SkScaledImageCache::Rec, SkScaledImageCache::Key> {}; | 35 public SkTDynamicHash<SkResourceCache::Rec, SkResourceCache::Key> {}; |
| 36 | 36 |
| 37 | 37 |
| 38 /////////////////////////////////////////////////////////////////////////////// | 38 /////////////////////////////////////////////////////////////////////////////// |
| 39 | 39 |
| 40 // experimental hash to speed things up | 40 // experimental hash to speed things up |
| 41 #define USE_HASH | 41 #define USE_HASH |
| 42 | 42 |
| 43 #if !defined(USE_HASH) | 43 #if !defined(USE_HASH) |
| 44 static inline SkScaledImageCache::Rec* find_rec_in_list( | 44 static inline SkResourceCache::Rec* find_rec_in_list( |
| 45 SkScaledImageCache::Rec* head, const Key & key) { | 45 SkResourceCache::Rec* head, const Key & key) { |
| 46 SkScaledImageCache::Rec* rec = head; | 46 SkResourceCache::Rec* rec = head; |
| 47 while ((rec != NULL) && (rec->fKey != key)) { | 47 while ((rec != NULL) && (rec->fKey != key)) { |
| 48 rec = rec->fNext; | 48 rec = rec->fNext; |
| 49 } | 49 } |
| 50 return rec; | 50 return rec; |
| 51 } | 51 } |
| 52 #endif | 52 #endif |
| 53 | 53 |
| 54 void SkScaledImageCache::init() { | 54 void SkResourceCache::init() { |
| 55 fHead = NULL; | 55 fHead = NULL; |
| 56 fTail = NULL; | 56 fTail = NULL; |
| 57 #ifdef USE_HASH | 57 #ifdef USE_HASH |
| 58 fHash = new Hash; | 58 fHash = new Hash; |
| 59 #else | 59 #else |
| 60 fHash = NULL; | 60 fHash = NULL; |
| 61 #endif | 61 #endif |
| 62 fTotalBytesUsed = 0; | 62 fTotalBytesUsed = 0; |
| 63 fCount = 0; | 63 fCount = 0; |
| 64 fSingleAllocationByteLimit = 0; | 64 fSingleAllocationByteLimit = 0; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 | 135 |
| 136 void SkOneShotDiscardablePixelRef::onUnlockPixels() { | 136 void SkOneShotDiscardablePixelRef::onUnlockPixels() { |
| 137 SkASSERT(!fFirstTime); | 137 SkASSERT(!fFirstTime); |
| 138 fDM->unlock(); | 138 fDM->unlock(); |
| 139 } | 139 } |
| 140 | 140 |
| 141 size_t SkOneShotDiscardablePixelRef::getAllocatedSizeInBytes() const { | 141 size_t SkOneShotDiscardablePixelRef::getAllocatedSizeInBytes() const { |
| 142 return this->info().getSafeSize(fRB); | 142 return this->info().getSafeSize(fRB); |
| 143 } | 143 } |
| 144 | 144 |
| 145 class SkScaledImageCacheDiscardableAllocator : public SkBitmap::Allocator { | 145 class SkResourceCacheDiscardableAllocator : public SkBitmap::Allocator { |
| 146 public: | 146 public: |
| 147 SkScaledImageCacheDiscardableAllocator( | 147 SkResourceCacheDiscardableAllocator(SkResourceCache::DiscardableFactory fact
ory) { |
| 148 SkScaledImageCache::DiscardableFactory factory) { | |
| 149 SkASSERT(factory); | 148 SkASSERT(factory); |
| 150 fFactory = factory; | 149 fFactory = factory; |
| 151 } | 150 } |
| 152 | 151 |
| 153 virtual bool allocPixelRef(SkBitmap*, SkColorTable*) SK_OVERRIDE; | 152 virtual bool allocPixelRef(SkBitmap*, SkColorTable*) SK_OVERRIDE; |
| 154 | 153 |
| 155 private: | 154 private: |
| 156 SkScaledImageCache::DiscardableFactory fFactory; | 155 SkResourceCache::DiscardableFactory fFactory; |
| 157 }; | 156 }; |
| 158 | 157 |
| 159 bool SkScaledImageCacheDiscardableAllocator::allocPixelRef(SkBitmap* bitmap, | 158 bool SkResourceCacheDiscardableAllocator::allocPixelRef(SkBitmap* bitmap, SkColo
rTable* ctable) { |
| 160 SkColorTable* ctable) { | |
| 161 size_t size = bitmap->getSize(); | 159 size_t size = bitmap->getSize(); |
| 162 uint64_t size64 = bitmap->computeSize64(); | 160 uint64_t size64 = bitmap->computeSize64(); |
| 163 if (0 == size || size64 > (uint64_t)size) { | 161 if (0 == size || size64 > (uint64_t)size) { |
| 164 return false; | 162 return false; |
| 165 } | 163 } |
| 166 | 164 |
| 167 SkDiscardableMemory* dm = fFactory(size); | 165 SkDiscardableMemory* dm = fFactory(size); |
| 168 if (NULL == dm) { | 166 if (NULL == dm) { |
| 169 return false; | 167 return false; |
| 170 } | 168 } |
| 171 | 169 |
| 172 // can we relax this? | 170 // can we relax this? |
| 173 if (kN32_SkColorType != bitmap->colorType()) { | 171 if (kN32_SkColorType != bitmap->colorType()) { |
| 174 return false; | 172 return false; |
| 175 } | 173 } |
| 176 | 174 |
| 177 SkImageInfo info = bitmap->info(); | 175 SkImageInfo info = bitmap->info(); |
| 178 bitmap->setPixelRef(SkNEW_ARGS(SkOneShotDiscardablePixelRef, | 176 bitmap->setPixelRef(SkNEW_ARGS(SkOneShotDiscardablePixelRef, |
| 179 (info, dm, bitmap->rowBytes())))->unref(); | 177 (info, dm, bitmap->rowBytes())))->unref(); |
| 180 bitmap->lockPixels(); | 178 bitmap->lockPixels(); |
| 181 return bitmap->readyToDraw(); | 179 return bitmap->readyToDraw(); |
| 182 } | 180 } |
| 183 | 181 |
| 184 SkScaledImageCache::SkScaledImageCache(DiscardableFactory factory) { | 182 SkResourceCache::SkResourceCache(DiscardableFactory factory) { |
| 185 this->init(); | 183 this->init(); |
| 186 fDiscardableFactory = factory; | 184 fDiscardableFactory = factory; |
| 187 | 185 |
| 188 fAllocator = SkNEW_ARGS(SkScaledImageCacheDiscardableAllocator, (factory)); | 186 fAllocator = SkNEW_ARGS(SkResourceCacheDiscardableAllocator, (factory)); |
| 189 } | 187 } |
| 190 | 188 |
| 191 SkScaledImageCache::SkScaledImageCache(size_t byteLimit) { | 189 SkResourceCache::SkResourceCache(size_t byteLimit) { |
| 192 this->init(); | 190 this->init(); |
| 193 fTotalByteLimit = byteLimit; | 191 fTotalByteLimit = byteLimit; |
| 194 } | 192 } |
| 195 | 193 |
| 196 SkScaledImageCache::~SkScaledImageCache() { | 194 SkResourceCache::~SkResourceCache() { |
| 197 SkSafeUnref(fAllocator); | 195 SkSafeUnref(fAllocator); |
| 198 | 196 |
| 199 Rec* rec = fHead; | 197 Rec* rec = fHead; |
| 200 while (rec) { | 198 while (rec) { |
| 201 Rec* next = rec->fNext; | 199 Rec* next = rec->fNext; |
| 202 SkDELETE(rec); | 200 SkDELETE(rec); |
| 203 rec = next; | 201 rec = next; |
| 204 } | 202 } |
| 205 delete fHash; | 203 delete fHash; |
| 206 } | 204 } |
| 207 | 205 |
| 208 //////////////////////////////////////////////////////////////////////////////// | 206 //////////////////////////////////////////////////////////////////////////////// |
| 209 | 207 |
| 210 const SkScaledImageCache::Rec* SkScaledImageCache::findAndLock(const Key& key) { | 208 const SkResourceCache::Rec* SkResourceCache::findAndLock(const Key& key) { |
| 211 #ifdef USE_HASH | 209 #ifdef USE_HASH |
| 212 Rec* rec = fHash->find(key); | 210 Rec* rec = fHash->find(key); |
| 213 #else | 211 #else |
| 214 Rec* rec = find_rec_in_list(fHead, key); | 212 Rec* rec = find_rec_in_list(fHead, key); |
| 215 #endif | 213 #endif |
| 216 if (rec) { | 214 if (rec) { |
| 217 this->moveToHead(rec); // for our LRU | 215 this->moveToHead(rec); // for our LRU |
| 218 rec->fLockCount += 1; | 216 rec->fLockCount += 1; |
| 219 } | 217 } |
| 220 return rec; | 218 return rec; |
| 221 } | 219 } |
| 222 | 220 |
| 223 const SkScaledImageCache::Rec* SkScaledImageCache::addAndLock(Rec* rec) { | 221 const SkResourceCache::Rec* SkResourceCache::addAndLock(Rec* rec) { |
| 224 SkASSERT(rec); | 222 SkASSERT(rec); |
| 225 // See if we already have this key (racy inserts, etc.) | 223 // See if we already have this key (racy inserts, etc.) |
| 226 const Rec* existing = this->findAndLock(rec->getKey()); | 224 const Rec* existing = this->findAndLock(rec->getKey()); |
| 227 if (NULL != existing) { | 225 if (NULL != existing) { |
| 228 SkDELETE(rec); | 226 SkDELETE(rec); |
| 229 return existing; | 227 return existing; |
| 230 } | 228 } |
| 231 | 229 |
| 232 this->addToHead(rec); | 230 this->addToHead(rec); |
| 233 SkASSERT(1 == rec->fLockCount); | 231 SkASSERT(1 == rec->fLockCount); |
| 234 #ifdef USE_HASH | 232 #ifdef USE_HASH |
| 235 SkASSERT(fHash); | 233 SkASSERT(fHash); |
| 236 fHash->add(rec); | 234 fHash->add(rec); |
| 237 #endif | 235 #endif |
| 238 // We may (now) be overbudget, so see if we need to purge something. | 236 // We may (now) be overbudget, so see if we need to purge something. |
| 239 this->purgeAsNeeded(); | 237 this->purgeAsNeeded(); |
| 240 return rec; | 238 return rec; |
| 241 } | 239 } |
| 242 | 240 |
| 243 void SkScaledImageCache::add(Rec* rec) { | 241 void SkResourceCache::add(Rec* rec) { |
| 244 SkASSERT(rec); | 242 SkASSERT(rec); |
| 245 // See if we already have this key (racy inserts, etc.) | 243 // See if we already have this key (racy inserts, etc.) |
| 246 const Rec* existing = this->findAndLock(rec->getKey()); | 244 const Rec* existing = this->findAndLock(rec->getKey()); |
| 247 if (NULL != existing) { | 245 if (NULL != existing) { |
| 248 SkDELETE(rec); | 246 SkDELETE(rec); |
| 249 this->unlock(existing); | 247 this->unlock(existing); |
| 250 return; | 248 return; |
| 251 } | 249 } |
| 252 | 250 |
| 253 this->addToHead(rec); | 251 this->addToHead(rec); |
| 254 SkASSERT(1 == rec->fLockCount); | 252 SkASSERT(1 == rec->fLockCount); |
| 255 #ifdef USE_HASH | 253 #ifdef USE_HASH |
| 256 SkASSERT(fHash); | 254 SkASSERT(fHash); |
| 257 fHash->add(rec); | 255 fHash->add(rec); |
| 258 #endif | 256 #endif |
| 259 this->unlock(rec); | 257 this->unlock(rec); |
| 260 } | 258 } |
| 261 | 259 |
| 262 void SkScaledImageCache::unlock(SkScaledImageCache::ID id) { | 260 void SkResourceCache::unlock(SkResourceCache::ID id) { |
| 263 SkASSERT(id); | 261 SkASSERT(id); |
| 264 | 262 |
| 265 #ifdef SK_DEBUG | 263 #ifdef SK_DEBUG |
| 266 { | 264 { |
| 267 bool found = false; | 265 bool found = false; |
| 268 Rec* rec = fHead; | 266 Rec* rec = fHead; |
| 269 while (rec != NULL) { | 267 while (rec != NULL) { |
| 270 if (rec == id) { | 268 if (rec == id) { |
| 271 found = true; | 269 found = true; |
| 272 break; | 270 break; |
| 273 } | 271 } |
| 274 rec = rec->fNext; | 272 rec = rec->fNext; |
| 275 } | 273 } |
| 276 SkASSERT(found); | 274 SkASSERT(found); |
| 277 } | 275 } |
| 278 #endif | 276 #endif |
| 279 const Rec* rec = id; | 277 const Rec* rec = id; |
| 280 SkASSERT(rec->fLockCount > 0); | 278 SkASSERT(rec->fLockCount > 0); |
| 281 // We're under our lock, and we're the only possible mutator, so unconsting
is fine. | 279 // We're under our lock, and we're the only possible mutator, so unconsting
is fine. |
| 282 const_cast<Rec*>(rec)->fLockCount -= 1; | 280 const_cast<Rec*>(rec)->fLockCount -= 1; |
| 283 | 281 |
| 284 // we may have been over-budget, but now have released something, so check | 282 // we may have been over-budget, but now have released something, so check |
| 285 // if we should purge. | 283 // if we should purge. |
| 286 if (0 == rec->fLockCount) { | 284 if (0 == rec->fLockCount) { |
| 287 this->purgeAsNeeded(); | 285 this->purgeAsNeeded(); |
| 288 } | 286 } |
| 289 } | 287 } |
| 290 | 288 |
| 291 void SkScaledImageCache::purgeAsNeeded() { | 289 void SkResourceCache::purgeAsNeeded() { |
| 292 size_t byteLimit; | 290 size_t byteLimit; |
| 293 int countLimit; | 291 int countLimit; |
| 294 | 292 |
| 295 if (fDiscardableFactory) { | 293 if (fDiscardableFactory) { |
| 296 countLimit = SK_DISCARDABLEMEMORY_SCALEDIMAGECACHE_COUNT_LIMIT; | 294 countLimit = SK_DISCARDABLEMEMORY_SCALEDIMAGECACHE_COUNT_LIMIT; |
| 297 byteLimit = SK_MaxU32; // no limit based on bytes | 295 byteLimit = SK_MaxU32; // no limit based on bytes |
| 298 } else { | 296 } else { |
| 299 countLimit = SK_MaxS32; // no limit based on count | 297 countLimit = SK_MaxS32; // no limit based on count |
| 300 byteLimit = fTotalByteLimit; | 298 byteLimit = fTotalByteLimit; |
| 301 } | 299 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 323 bytesUsed -= used; | 321 bytesUsed -= used; |
| 324 countUsed -= 1; | 322 countUsed -= 1; |
| 325 } | 323 } |
| 326 rec = prev; | 324 rec = prev; |
| 327 } | 325 } |
| 328 | 326 |
| 329 fTotalBytesUsed = bytesUsed; | 327 fTotalBytesUsed = bytesUsed; |
| 330 fCount = countUsed; | 328 fCount = countUsed; |
| 331 } | 329 } |
| 332 | 330 |
| 333 size_t SkScaledImageCache::setTotalByteLimit(size_t newLimit) { | 331 size_t SkResourceCache::setTotalByteLimit(size_t newLimit) { |
| 334 size_t prevLimit = fTotalByteLimit; | 332 size_t prevLimit = fTotalByteLimit; |
| 335 fTotalByteLimit = newLimit; | 333 fTotalByteLimit = newLimit; |
| 336 if (newLimit < prevLimit) { | 334 if (newLimit < prevLimit) { |
| 337 this->purgeAsNeeded(); | 335 this->purgeAsNeeded(); |
| 338 } | 336 } |
| 339 return prevLimit; | 337 return prevLimit; |
| 340 } | 338 } |
| 341 | 339 |
| 342 /////////////////////////////////////////////////////////////////////////////// | 340 /////////////////////////////////////////////////////////////////////////////// |
| 343 | 341 |
| 344 void SkScaledImageCache::detach(Rec* rec) { | 342 void SkResourceCache::detach(Rec* rec) { |
| 345 Rec* prev = rec->fPrev; | 343 Rec* prev = rec->fPrev; |
| 346 Rec* next = rec->fNext; | 344 Rec* next = rec->fNext; |
| 347 | 345 |
| 348 if (!prev) { | 346 if (!prev) { |
| 349 SkASSERT(fHead == rec); | 347 SkASSERT(fHead == rec); |
| 350 fHead = next; | 348 fHead = next; |
| 351 } else { | 349 } else { |
| 352 prev->fNext = next; | 350 prev->fNext = next; |
| 353 } | 351 } |
| 354 | 352 |
| 355 if (!next) { | 353 if (!next) { |
| 356 fTail = prev; | 354 fTail = prev; |
| 357 } else { | 355 } else { |
| 358 next->fPrev = prev; | 356 next->fPrev = prev; |
| 359 } | 357 } |
| 360 | 358 |
| 361 rec->fNext = rec->fPrev = NULL; | 359 rec->fNext = rec->fPrev = NULL; |
| 362 } | 360 } |
| 363 | 361 |
| 364 void SkScaledImageCache::moveToHead(Rec* rec) { | 362 void SkResourceCache::moveToHead(Rec* rec) { |
| 365 if (fHead == rec) { | 363 if (fHead == rec) { |
| 366 return; | 364 return; |
| 367 } | 365 } |
| 368 | 366 |
| 369 SkASSERT(fHead); | 367 SkASSERT(fHead); |
| 370 SkASSERT(fTail); | 368 SkASSERT(fTail); |
| 371 | 369 |
| 372 this->validate(); | 370 this->validate(); |
| 373 | 371 |
| 374 this->detach(rec); | 372 this->detach(rec); |
| 375 | 373 |
| 376 fHead->fPrev = rec; | 374 fHead->fPrev = rec; |
| 377 rec->fNext = fHead; | 375 rec->fNext = fHead; |
| 378 fHead = rec; | 376 fHead = rec; |
| 379 | 377 |
| 380 this->validate(); | 378 this->validate(); |
| 381 } | 379 } |
| 382 | 380 |
| 383 void SkScaledImageCache::addToHead(Rec* rec) { | 381 void SkResourceCache::addToHead(Rec* rec) { |
| 384 this->validate(); | 382 this->validate(); |
| 385 | 383 |
| 386 rec->fPrev = NULL; | 384 rec->fPrev = NULL; |
| 387 rec->fNext = fHead; | 385 rec->fNext = fHead; |
| 388 if (fHead) { | 386 if (fHead) { |
| 389 fHead->fPrev = rec; | 387 fHead->fPrev = rec; |
| 390 } | 388 } |
| 391 fHead = rec; | 389 fHead = rec; |
| 392 if (!fTail) { | 390 if (!fTail) { |
| 393 fTail = rec; | 391 fTail = rec; |
| 394 } | 392 } |
| 395 fTotalBytesUsed += rec->bytesUsed(); | 393 fTotalBytesUsed += rec->bytesUsed(); |
| 396 fCount += 1; | 394 fCount += 1; |
| 397 | 395 |
| 398 this->validate(); | 396 this->validate(); |
| 399 } | 397 } |
| 400 | 398 |
| 401 /////////////////////////////////////////////////////////////////////////////// | 399 /////////////////////////////////////////////////////////////////////////////// |
| 402 | 400 |
| 403 #ifdef SK_DEBUG | 401 #ifdef SK_DEBUG |
| 404 void SkScaledImageCache::validate() const { | 402 void SkResourceCache::validate() const { |
| 405 if (NULL == fHead) { | 403 if (NULL == fHead) { |
| 406 SkASSERT(NULL == fTail); | 404 SkASSERT(NULL == fTail); |
| 407 SkASSERT(0 == fTotalBytesUsed); | 405 SkASSERT(0 == fTotalBytesUsed); |
| 408 return; | 406 return; |
| 409 } | 407 } |
| 410 | 408 |
| 411 if (fHead == fTail) { | 409 if (fHead == fTail) { |
| 412 SkASSERT(NULL == fHead->fPrev); | 410 SkASSERT(NULL == fHead->fPrev); |
| 413 SkASSERT(NULL == fHead->fNext); | 411 SkASSERT(NULL == fHead->fNext); |
| 414 SkASSERT(fHead->bytesUsed() == fTotalBytesUsed); | 412 SkASSERT(fHead->bytesUsed() == fTotalBytesUsed); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 438 SkASSERT(used >= rec->bytesUsed()); | 436 SkASSERT(used >= rec->bytesUsed()); |
| 439 used -= rec->bytesUsed(); | 437 used -= rec->bytesUsed(); |
| 440 rec = rec->fPrev; | 438 rec = rec->fPrev; |
| 441 } | 439 } |
| 442 | 440 |
| 443 SkASSERT(0 == count); | 441 SkASSERT(0 == count); |
| 444 SkASSERT(0 == used); | 442 SkASSERT(0 == used); |
| 445 } | 443 } |
| 446 #endif | 444 #endif |
| 447 | 445 |
| 448 void SkScaledImageCache::dump() const { | 446 void SkResourceCache::dump() const { |
| 449 this->validate(); | 447 this->validate(); |
| 450 | 448 |
| 451 const Rec* rec = fHead; | 449 const Rec* rec = fHead; |
| 452 int locked = 0; | 450 int locked = 0; |
| 453 while (rec) { | 451 while (rec) { |
| 454 locked += rec->fLockCount > 0; | 452 locked += rec->fLockCount > 0; |
| 455 rec = rec->fNext; | 453 rec = rec->fNext; |
| 456 } | 454 } |
| 457 | 455 |
| 458 SkDebugf("SkScaledImageCache: count=%d bytes=%d locked=%d %s\n", | 456 SkDebugf("SkResourceCache: count=%d bytes=%d locked=%d %s\n", |
| 459 fCount, fTotalBytesUsed, locked, | 457 fCount, fTotalBytesUsed, locked, |
| 460 fDiscardableFactory ? "discardable" : "malloc"); | 458 fDiscardableFactory ? "discardable" : "malloc"); |
| 461 } | 459 } |
| 462 | 460 |
| 463 size_t SkScaledImageCache::setSingleAllocationByteLimit(size_t newLimit) { | 461 size_t SkResourceCache::setSingleAllocationByteLimit(size_t newLimit) { |
| 464 size_t oldLimit = fSingleAllocationByteLimit; | 462 size_t oldLimit = fSingleAllocationByteLimit; |
| 465 fSingleAllocationByteLimit = newLimit; | 463 fSingleAllocationByteLimit = newLimit; |
| 466 return oldLimit; | 464 return oldLimit; |
| 467 } | 465 } |
| 468 | 466 |
| 469 size_t SkScaledImageCache::getSingleAllocationByteLimit() const { | 467 size_t SkResourceCache::getSingleAllocationByteLimit() const { |
| 470 return fSingleAllocationByteLimit; | 468 return fSingleAllocationByteLimit; |
| 471 } | 469 } |
| 472 | 470 |
| 473 /////////////////////////////////////////////////////////////////////////////// | 471 /////////////////////////////////////////////////////////////////////////////// |
| 474 | 472 |
| 475 #include "SkThread.h" | 473 #include "SkThread.h" |
| 476 | 474 |
| 477 SK_DECLARE_STATIC_MUTEX(gMutex); | 475 SK_DECLARE_STATIC_MUTEX(gMutex); |
| 478 static SkScaledImageCache* gScaledImageCache = NULL; | 476 static SkResourceCache* gResourceCache = NULL; |
| 479 static void cleanup_gScaledImageCache() { | 477 static void cleanup_gResourceCache() { |
| 480 // We'll clean this up in our own tests, but disable for clients. | 478 // We'll clean this up in our own tests, but disable for clients. |
| 481 // Chrome seems to have funky multi-process things going on in unit tests th
at | 479 // Chrome seems to have funky multi-process things going on in unit tests th
at |
| 482 // makes this unsafe to delete when the main process atexit()s. | 480 // makes this unsafe to delete when the main process atexit()s. |
| 483 // SkLazyPtr does the same sort of thing. | 481 // SkLazyPtr does the same sort of thing. |
| 484 #if SK_DEVELOPER | 482 #if SK_DEVELOPER |
| 485 SkDELETE(gScaledImageCache); | 483 SkDELETE(gResourceCache); |
| 486 #endif | 484 #endif |
| 487 } | 485 } |
| 488 | 486 |
| 489 /** Must hold gMutex when calling. */ | 487 /** Must hold gMutex when calling. */ |
| 490 static SkScaledImageCache* get_cache() { | 488 static SkResourceCache* get_cache() { |
| 491 // gMutex is always held when this is called, so we don't need to be fancy i
n here. | 489 // gMutex is always held when this is called, so we don't need to be fancy i
n here. |
| 492 gMutex.assertHeld(); | 490 gMutex.assertHeld(); |
| 493 if (NULL == gScaledImageCache) { | 491 if (NULL == gResourceCache) { |
| 494 #ifdef SK_USE_DISCARDABLE_SCALEDIMAGECACHE | 492 #ifdef SK_USE_DISCARDABLE_SCALEDIMAGECACHE |
| 495 gScaledImageCache = SkNEW_ARGS(SkScaledImageCache, (SkDiscardableMemory:
:Create)); | 493 gResourceCache = SkNEW_ARGS(SkResourceCache, (SkDiscardableMemory::Creat
e)); |
| 496 #else | 494 #else |
| 497 gScaledImageCache = SkNEW_ARGS(SkScaledImageCache, (SK_DEFAULT_IMAGE_CAC
HE_LIMIT)); | 495 gResourceCache = SkNEW_ARGS(SkResourceCache, (SK_DEFAULT_IMAGE_CACHE_LIM
IT)); |
| 498 #endif | 496 #endif |
| 499 atexit(cleanup_gScaledImageCache); | 497 atexit(cleanup_gResourceCache); |
| 500 } | 498 } |
| 501 return gScaledImageCache; | 499 return gResourceCache; |
| 502 } | 500 } |
| 503 | 501 |
| 504 void SkScaledImageCache::Unlock(SkScaledImageCache::ID id) { | 502 void SkResourceCache::Unlock(SkResourceCache::ID id) { |
| 505 SkAutoMutexAcquire am(gMutex); | 503 SkAutoMutexAcquire am(gMutex); |
| 506 get_cache()->unlock(id); | 504 get_cache()->unlock(id); |
| 507 | 505 |
| 508 // get_cache()->dump(); | 506 // get_cache()->dump(); |
| 509 } | 507 } |
| 510 | 508 |
| 511 size_t SkScaledImageCache::GetTotalBytesUsed() { | 509 size_t SkResourceCache::GetTotalBytesUsed() { |
| 512 SkAutoMutexAcquire am(gMutex); | 510 SkAutoMutexAcquire am(gMutex); |
| 513 return get_cache()->getTotalBytesUsed(); | 511 return get_cache()->getTotalBytesUsed(); |
| 514 } | 512 } |
| 515 | 513 |
| 516 size_t SkScaledImageCache::GetTotalByteLimit() { | 514 size_t SkResourceCache::GetTotalByteLimit() { |
| 517 SkAutoMutexAcquire am(gMutex); | 515 SkAutoMutexAcquire am(gMutex); |
| 518 return get_cache()->getTotalByteLimit(); | 516 return get_cache()->getTotalByteLimit(); |
| 519 } | 517 } |
| 520 | 518 |
| 521 size_t SkScaledImageCache::SetTotalByteLimit(size_t newLimit) { | 519 size_t SkResourceCache::SetTotalByteLimit(size_t newLimit) { |
| 522 SkAutoMutexAcquire am(gMutex); | 520 SkAutoMutexAcquire am(gMutex); |
| 523 return get_cache()->setTotalByteLimit(newLimit); | 521 return get_cache()->setTotalByteLimit(newLimit); |
| 524 } | 522 } |
| 525 | 523 |
| 526 SkBitmap::Allocator* SkScaledImageCache::GetAllocator() { | 524 SkBitmap::Allocator* SkResourceCache::GetAllocator() { |
| 527 SkAutoMutexAcquire am(gMutex); | 525 SkAutoMutexAcquire am(gMutex); |
| 528 return get_cache()->allocator(); | 526 return get_cache()->allocator(); |
| 529 } | 527 } |
| 530 | 528 |
| 531 void SkScaledImageCache::Dump() { | 529 void SkResourceCache::Dump() { |
| 532 SkAutoMutexAcquire am(gMutex); | 530 SkAutoMutexAcquire am(gMutex); |
| 533 get_cache()->dump(); | 531 get_cache()->dump(); |
| 534 } | 532 } |
| 535 | 533 |
| 536 size_t SkScaledImageCache::SetSingleAllocationByteLimit(size_t size) { | 534 size_t SkResourceCache::SetSingleAllocationByteLimit(size_t size) { |
| 537 SkAutoMutexAcquire am(gMutex); | 535 SkAutoMutexAcquire am(gMutex); |
| 538 return get_cache()->setSingleAllocationByteLimit(size); | 536 return get_cache()->setSingleAllocationByteLimit(size); |
| 539 } | 537 } |
| 540 | 538 |
| 541 size_t SkScaledImageCache::GetSingleAllocationByteLimit() { | 539 size_t SkResourceCache::GetSingleAllocationByteLimit() { |
| 542 SkAutoMutexAcquire am(gMutex); | 540 SkAutoMutexAcquire am(gMutex); |
| 543 return get_cache()->getSingleAllocationByteLimit(); | 541 return get_cache()->getSingleAllocationByteLimit(); |
| 544 } | 542 } |
| 545 | 543 |
| 546 const SkScaledImageCache::Rec* SkScaledImageCache::FindAndLock(const Key& key) { | 544 const SkResourceCache::Rec* SkResourceCache::FindAndLock(const Key& key) { |
| 547 SkAutoMutexAcquire am(gMutex); | 545 SkAutoMutexAcquire am(gMutex); |
| 548 return get_cache()->findAndLock(key); | 546 return get_cache()->findAndLock(key); |
| 549 } | 547 } |
| 550 | 548 |
| 551 const SkScaledImageCache::Rec* SkScaledImageCache::AddAndLock(Rec* rec) { | 549 const SkResourceCache::Rec* SkResourceCache::AddAndLock(Rec* rec) { |
| 552 SkAutoMutexAcquire am(gMutex); | 550 SkAutoMutexAcquire am(gMutex); |
| 553 return get_cache()->addAndLock(rec); | 551 return get_cache()->addAndLock(rec); |
| 554 } | 552 } |
| 555 | 553 |
| 556 void SkScaledImageCache::Add(Rec* rec) { | 554 void SkResourceCache::Add(Rec* rec) { |
| 557 SkAutoMutexAcquire am(gMutex); | 555 SkAutoMutexAcquire am(gMutex); |
| 558 get_cache()->add(rec); | 556 get_cache()->add(rec); |
| 559 } | 557 } |
| 560 | 558 |
| 561 /////////////////////////////////////////////////////////////////////////////// | 559 /////////////////////////////////////////////////////////////////////////////// |
| 562 | 560 |
| 563 #include "SkGraphics.h" | 561 #include "SkGraphics.h" |
| 564 | 562 |
| 565 size_t SkGraphics::GetImageCacheTotalBytesUsed() { | 563 size_t SkGraphics::GetResourceCacheTotalBytesUsed() { |
| 566 return SkScaledImageCache::GetTotalBytesUsed(); | 564 return SkResourceCache::GetTotalBytesUsed(); |
| 567 } | 565 } |
| 568 | 566 |
| 569 size_t SkGraphics::GetImageCacheTotalByteLimit() { | 567 size_t SkGraphics::GetResourceCacheTotalByteLimit() { |
| 570 return SkScaledImageCache::GetTotalByteLimit(); | 568 return SkResourceCache::GetTotalByteLimit(); |
| 571 } | 569 } |
| 572 | 570 |
| 573 size_t SkGraphics::SetImageCacheTotalByteLimit(size_t newLimit) { | 571 size_t SkGraphics::SetResourceCacheTotalByteLimit(size_t newLimit) { |
| 574 return SkScaledImageCache::SetTotalByteLimit(newLimit); | 572 return SkResourceCache::SetTotalByteLimit(newLimit); |
| 575 } | 573 } |
| 576 | 574 |
| 577 size_t SkGraphics::GetImageCacheSingleAllocationByteLimit() { | 575 size_t SkGraphics::GetResourceCacheSingleAllocationByteLimit() { |
| 578 return SkScaledImageCache::GetSingleAllocationByteLimit(); | 576 return SkResourceCache::GetSingleAllocationByteLimit(); |
| 579 } | 577 } |
| 580 | 578 |
| 581 size_t SkGraphics::SetImageCacheSingleAllocationByteLimit(size_t newLimit) { | 579 size_t SkGraphics::SetResourceCacheSingleAllocationByteLimit(size_t newLimit) { |
| 582 return SkScaledImageCache::SetSingleAllocationByteLimit(newLimit); | 580 return SkResourceCache::SetSingleAllocationByteLimit(newLimit); |
| 583 } | 581 } |
| 584 | 582 |
| OLD | NEW |