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 |