Chromium Code Reviews| 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 "SkScaledImageCache.h" | 8 #include "SkScaledImageCache.h" |
| 9 #include "SkMipMap.h" | 9 #include "SkMipMap.h" |
| 10 #include "SkPixelRef.h" | 10 #include "SkPixelRef.h" |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 54 | 54 |
| 55 fGenID = pr->getGenerationID(); | 55 fGenID = pr->getGenerationID(); |
| 56 fBounds.set(x, y, x + bm.width(), y + bm.height()); | 56 fBounds.set(x, y, x + bm.width(), y + bm.height()); |
| 57 fScaleX = scaleX; | 57 fScaleX = scaleX; |
| 58 fScaleY = scaleY; | 58 fScaleY = scaleY; |
| 59 | 59 |
| 60 fHash = compute_hash(&fGenID, 7); | 60 fHash = compute_hash(&fGenID, 7); |
| 61 return true; | 61 return true; |
| 62 } | 62 } |
| 63 | 63 |
| 64 bool init(int32_t width, | |
|
mtklein
2013/10/23 18:50:14
Can't hurt to have init take its parameters in the
hal.canary
2013/10/23 22:57:41
The parameters are in the order of the key's field
| |
| 65 int32_t height, | |
| 66 uint32_t genID, | |
| 67 SkScalar scaleX, | |
| 68 SkScalar scaleY) { | |
| 69 fBounds.set(0, 0, width, height); | |
| 70 fGenID = genID; | |
| 71 fScaleX = scaleX; | |
| 72 fScaleY = scaleY; | |
| 73 fHash = compute_hash(&fGenID, 7); | |
| 74 return true; | |
|
mtklein
2013/10/23 18:50:14
I'm skeptical of methods that always return true.
| |
| 75 } | |
| 76 | |
| 64 bool operator<(const Key& other) const { | 77 bool operator<(const Key& other) const { |
| 65 const uint32_t* a = &fGenID; | 78 const uint32_t* a = &fGenID; |
| 66 const uint32_t* b = &other.fGenID; | 79 const uint32_t* b = &other.fGenID; |
| 67 for (int i = 0; i < 7; ++i) { | 80 for (int i = 0; i < 7; ++i) { |
| 68 if (a[i] < b[i]) { | 81 if (a[i] < b[i]) { |
| 69 return true; | 82 return true; |
| 70 } | 83 } |
| 71 if (a[i] > b[i]) { | 84 if (a[i] > b[i]) { |
| 72 return false; | 85 return false; |
| 73 } | 86 } |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 167 SkScaledImageCache::~SkScaledImageCache() { | 180 SkScaledImageCache::~SkScaledImageCache() { |
| 168 Rec* rec = fHead; | 181 Rec* rec = fHead; |
| 169 while (rec) { | 182 while (rec) { |
| 170 Rec* next = rec->fNext; | 183 Rec* next = rec->fNext; |
| 171 SkDELETE(rec); | 184 SkDELETE(rec); |
| 172 rec = next; | 185 rec = next; |
| 173 } | 186 } |
| 174 delete fHash; | 187 delete fHash; |
| 175 } | 188 } |
| 176 | 189 |
| 190 static inline SkScaledImageCache::Rec* find_rec_in_list( | |
| 191 SkScaledImageCache::Rec* head, const Key & key) { | |
| 192 SkScaledImageCache::Rec* rec = head; | |
| 193 while ((rec != NULL) && !(rec->fKey == key)) { | |
| 194 rec = rec->fNext; | |
| 195 } | |
| 196 return rec; | |
| 197 } | |
| 198 | |
| 177 SkScaledImageCache::Rec* SkScaledImageCache::findAndLock(const SkBitmap& orig, | 199 SkScaledImageCache::Rec* SkScaledImageCache::findAndLock(const SkBitmap& orig, |
| 178 SkScalar scaleX, | 200 SkScalar scaleX, |
| 179 SkScalar scaleY) { | 201 SkScalar scaleY) { |
| 180 Key key; | 202 Key key; |
| 181 if (!key.init(orig, scaleX, scaleY)) { | 203 if (!key.init(orig, scaleX, scaleY)) { |
| 182 return NULL; | 204 return NULL; |
| 183 } | 205 } |
| 184 | 206 |
| 185 #ifdef USE_HASH | 207 #ifdef USE_HASH |
| 186 Rec* rec = fHash->find(key); | 208 Rec* rec = fHash->find(key); |
| 187 #else | 209 #else |
| 188 Rec* rec = fHead; | 210 Rec* rec = find_rec_in_list(fHead, key); |
| 189 while (rec != NULL) { | |
| 190 if (rec->fKey == key) { | |
| 191 break; | |
| 192 } | |
| 193 rec = rec->fNext; | |
| 194 } | |
| 195 #endif | 211 #endif |
| 196 | |
| 197 if (rec) { | 212 if (rec) { |
| 198 this->moveToHead(rec); // for our LRU | 213 this->moveToHead(rec); // for our LRU |
| 199 rec->fLockCount += 1; | 214 rec->fLockCount += 1; |
| 200 } | 215 } |
| 201 return rec; | 216 return rec; |
| 202 } | 217 } |
| 203 | 218 |
| 219 | |
| 220 SkScaledImageCache::ID* SkScaledImageCache::findAndLock( | |
| 221 uint32_t pixelGenerationID, | |
| 222 int32_t width, | |
| 223 int32_t height, | |
| 224 SkScalar scaleX, // SK_Scalar1 default | |
| 225 SkScalar scaleY, | |
| 226 SkBitmap* scaled) { | |
| 227 Key key; | |
| 228 if (!key.init(width, height, pixelGenerationID, scaleX, scaleY)) { | |
| 229 return NULL; | |
| 230 } | |
| 231 #ifdef USE_HASH | |
|
mtklein
2013/10/23 18:50:14
It would make me feel warmer and fuzzier if you fo
scroggo
2013/10/23 23:38:33
+1. It also means that if we fix a bug/modify beha
| |
| 232 Rec* rec = fHash->find(key); | |
| 233 #else | |
| 234 Rec* rec = find_rec_in_list(fHead, key); | |
| 235 #endif | |
| 236 if (rec) { | |
| 237 this->moveToHead(rec); // for our LRU | |
| 238 rec->fLockCount += 1; | |
| 239 SkASSERT(NULL == rec->fMip); | |
| 240 SkASSERT(rec->fBitmap.pixelRef()); | |
| 241 *scaled = rec->fBitmap; | |
| 242 } | |
| 243 return reinterpret_cast<ID*>(rec); | |
|
mtklein
2013/10/23 18:50:14
Most of these are using (ID*) to do the cast. Sho
| |
| 244 } | |
| 245 | |
| 204 SkScaledImageCache::ID* SkScaledImageCache::findAndLock(const SkBitmap& orig, | 246 SkScaledImageCache::ID* SkScaledImageCache::findAndLock(const SkBitmap& orig, |
| 205 SkScalar scaleX, | 247 SkScalar scaleX, |
| 206 SkScalar scaleY, | 248 SkScalar scaleY, |
| 207 SkBitmap* scaled) { | 249 SkBitmap* scaled) { |
| 208 if (0 == scaleX || 0 == scaleY) { | 250 if (0 == scaleX || 0 == scaleY) { |
| 209 // degenerate, and the key we use for mipmaps | 251 // degenerate, and the key we use for mipmaps |
| 210 return NULL; | 252 return NULL; |
| 211 } | 253 } |
| 212 | 254 |
| 213 Rec* rec = this->findAndLock(orig, scaleX, scaleY); | 255 Rec* rec = this->findAndLock(orig, scaleX, scaleY); |
| 214 if (rec) { | 256 if (rec) { |
| 215 SkASSERT(NULL == rec->fMip); | 257 SkASSERT(NULL == rec->fMip); |
| 216 SkASSERT(rec->fBitmap.pixelRef()); | 258 SkASSERT(rec->fBitmap.pixelRef()); |
| 217 *scaled = rec->fBitmap; | 259 *scaled = rec->fBitmap; |
| 218 } | 260 } |
| 219 return (ID*)rec; | 261 return (ID*)rec; |
| 220 } | 262 } |
| 221 | 263 |
| 222 SkScaledImageCache::ID* SkScaledImageCache::findAndLockMip(const SkBitmap& orig, | 264 SkScaledImageCache::ID* SkScaledImageCache::findAndLockMip(const SkBitmap& orig, |
| 223 SkMipMap const ** mip ) { | 265 SkMipMap const ** mip ) { |
| 224 Rec* rec = this->findAndLock(orig, 0, 0); | 266 Rec* rec = this->findAndLock(orig, 0, 0); |
| 225 if (rec) { | 267 if (rec) { |
| 226 SkASSERT(rec->fMip); | 268 SkASSERT(rec->fMip); |
| 227 SkASSERT(NULL == rec->fBitmap.pixelRef()); | 269 SkASSERT(NULL == rec->fBitmap.pixelRef()); |
| 228 *mip = rec->fMip; | 270 *mip = rec->fMip; |
| 229 } | 271 } |
| 230 return (ID*)rec; | 272 return (ID*)rec; |
| 231 } | 273 } |
| 232 | 274 |
| 275 SkScaledImageCache::ID* SkScaledImageCache::addAndLock( | |
| 276 uint32_t pixelGenerationID, | |
| 277 int32_t width, | |
| 278 int32_t height, | |
| 279 SkScalar scaleX, | |
| 280 SkScalar scaleY, | |
| 281 const SkBitmap& scaled) { | |
| 282 Key key; | |
| 283 if (!key.init(width, height, pixelGenerationID, scaleX, scaleY)) { | |
| 284 return NULL; | |
| 285 } | |
| 286 Rec* rec = SkNEW_ARGS(Rec, (key, scaled)); | |
| 287 this->addToHead(rec); | |
| 288 SkASSERT(1 == rec->fLockCount); | |
| 289 | |
| 290 #ifdef USE_HASH | |
| 291 fHash->add(rec); | |
| 292 #endif | |
| 293 | |
| 294 // We may (now) be overbudget, so see if we need to purge something. | |
| 295 this->purgeAsNeeded(); | |
| 296 return reinterpret_cast<ID*>(rec); | |
| 297 } | |
| 298 | |
| 233 SkScaledImageCache::ID* SkScaledImageCache::addAndLock(const SkBitmap& orig, | 299 SkScaledImageCache::ID* SkScaledImageCache::addAndLock(const SkBitmap& orig, |
| 234 SkScalar scaleX, | 300 SkScalar scaleX, |
| 235 SkScalar scaleY, | 301 SkScalar scaleY, |
| 236 const SkBitmap& scaled) { | 302 const SkBitmap& scaled) { |
| 237 if (0 == scaleX || 0 == scaleY) { | 303 if (0 == scaleX || 0 == scaleY) { |
| 238 // degenerate, and the key we use for mipmaps | 304 // degenerate, and the key we use for mipmaps |
| 239 return NULL; | 305 return NULL; |
| 240 } | 306 } |
| 241 | 307 |
| 242 Key key; | 308 Key key; |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 445 } | 511 } |
| 446 #endif | 512 #endif |
| 447 | 513 |
| 448 /////////////////////////////////////////////////////////////////////////////// | 514 /////////////////////////////////////////////////////////////////////////////// |
| 449 | 515 |
| 450 #include "SkThread.h" | 516 #include "SkThread.h" |
| 451 | 517 |
| 452 SK_DECLARE_STATIC_MUTEX(gMutex); | 518 SK_DECLARE_STATIC_MUTEX(gMutex); |
| 453 | 519 |
| 454 static SkScaledImageCache* get_cache() { | 520 static SkScaledImageCache* get_cache() { |
| 455 static SkScaledImageCache* gCache; | 521 static SkScaledImageCache* gCache; |
|
scroggo
2013/10/23 15:27:49
Doesn't need to be in this CL, but is this a candi
hal.canary
2013/10/23 16:11:52
I think so. I meant to ask mtklein. I'm not stro
mtklein
2013/10/23 18:50:14
Yep, perfect place for it.
#include "SkOnce.h"
s
hal.canary
2013/10/23 22:57:41
Done.
| |
| 456 if (!gCache) { | 522 if (!gCache) { |
| 457 gCache = SkNEW_ARGS(SkScaledImageCache, (SK_DEFAULT_IMAGE_CACHE_LIMIT)); | 523 gCache = SkNEW_ARGS(SkScaledImageCache, (SK_DEFAULT_IMAGE_CACHE_LIMIT)); |
| 458 } | 524 } |
| 459 return gCache; | 525 return gCache; |
| 460 } | 526 } |
| 461 | 527 |
| 528 | |
| 529 SkScaledImageCache::ID* SkScaledImageCache::FindAndLock( | |
| 530 uint32_t pixelGenerationID, | |
| 531 int32_t width, | |
| 532 int32_t height, | |
| 533 SkScalar scaleX, | |
| 534 SkScalar scaleY, | |
| 535 SkBitmap* scaled) { | |
| 536 SkAutoMutexAcquire am(gMutex); | |
| 537 return get_cache()->findAndLock(pixelGenerationID, width, height, | |
| 538 scaleX, scaleY, scaled); | |
| 539 } | |
| 540 | |
| 541 SkScaledImageCache::ID* SkScaledImageCache::AddAndLock( | |
| 542 uint32_t pixelGenerationID, | |
| 543 int32_t width, | |
| 544 int32_t height, | |
| 545 SkScalar scaleX, | |
| 546 SkScalar scaleY, | |
| 547 const SkBitmap& scaled) { | |
| 548 SkAutoMutexAcquire am(gMutex); | |
| 549 return get_cache()->addAndLock(pixelGenerationID, width, height, | |
| 550 scaleX, scaleY, scaled); | |
| 551 } | |
| 552 | |
| 553 | |
| 462 SkScaledImageCache::ID* SkScaledImageCache::FindAndLock(const SkBitmap& orig, | 554 SkScaledImageCache::ID* SkScaledImageCache::FindAndLock(const SkBitmap& orig, |
| 463 SkScalar scaleX, | 555 SkScalar scaleX, |
| 464 SkScalar scaleY, | 556 SkScalar scaleY, |
| 465 SkBitmap* scaled) { | 557 SkBitmap* scaled) { |
| 466 SkAutoMutexAcquire am(gMutex); | 558 SkAutoMutexAcquire am(gMutex); |
| 467 return get_cache()->findAndLock(orig, scaleX, scaleY, scaled); | 559 return get_cache()->findAndLock(orig, scaleX, scaleY, scaled); |
| 468 } | 560 } |
| 469 | 561 |
| 470 SkScaledImageCache::ID* SkScaledImageCache::FindAndLockMip(const SkBitmap& orig, | 562 SkScaledImageCache::ID* SkScaledImageCache::FindAndLockMip(const SkBitmap& orig, |
| 471 SkMipMap const ** mip) { | 563 SkMipMap const ** mip) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 515 return SkScaledImageCache::GetBytesUsed(); | 607 return SkScaledImageCache::GetBytesUsed(); |
| 516 } | 608 } |
| 517 | 609 |
| 518 size_t SkGraphics::GetImageCacheByteLimit() { | 610 size_t SkGraphics::GetImageCacheByteLimit() { |
| 519 return SkScaledImageCache::GetByteLimit(); | 611 return SkScaledImageCache::GetByteLimit(); |
| 520 } | 612 } |
| 521 | 613 |
| 522 size_t SkGraphics::SetImageCacheByteLimit(size_t newLimit) { | 614 size_t SkGraphics::SetImageCacheByteLimit(size_t newLimit) { |
| 523 return SkScaledImageCache::SetByteLimit(newLimit); | 615 return SkScaledImageCache::SetByteLimit(newLimit); |
| 524 } | 616 } |
| OLD | NEW |