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