Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(177)

Side by Side Diff: src/core/SkScaledImageCache.cpp

Issue 37343002: Allow SkLazyPixelRef to use SkScaledImageCache (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: more changes Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "SkOnce.h"
10 #include "SkPixelRef.h" 11 #include "SkPixelRef.h"
11 #include "SkRect.h" 12 #include "SkRect.h"
12 13
13 #ifndef SK_DEFAULT_IMAGE_CACHE_LIMIT 14 #ifndef SK_DEFAULT_IMAGE_CACHE_LIMIT
14 #define SK_DEFAULT_IMAGE_CACHE_LIMIT (2 * 1024 * 1024) 15 #define SK_DEFAULT_IMAGE_CACHE_LIMIT (2 * 1024 * 1024)
15 #endif 16 #endif
16 17
17 18
18 // Implemented from en.wikipedia.org/wiki/MurmurHash. 19 // Implemented from en.wikipedia.org/wiki/MurmurHash.
19 static uint32_t compute_hash(const uint32_t data[], int count) { 20 static uint32_t compute_hash(const uint32_t data[], int count) {
(...skipping 27 matching lines...) Expand all
47 if (!pr) { 48 if (!pr) {
48 return false; 49 return false;
49 } 50 }
50 51
51 size_t x, y; 52 size_t x, y;
52 SkTDivMod(bm.pixelRefOffset(), bm.rowBytes(), &y, &x); 53 SkTDivMod(bm.pixelRefOffset(), bm.rowBytes(), &y, &x);
53 x >>= 2; 54 x >>= 2;
54 55
55 fGenID = pr->getGenerationID(); 56 fGenID = pr->getGenerationID();
56 fBounds.set(x, y, x + bm.width(), y + bm.height()); 57 fBounds.set(x, y, x + bm.width(), y + bm.height());
57 fScaleX = scaleX; 58 fScaleX = SkScalarToFloat(scaleX);
58 fScaleY = scaleY; 59 fScaleY = SkScalarToFloat(scaleY);
59 60
60 fHash = compute_hash(&fGenID, 7); 61 fHash = compute_hash(&fGenID, 7);
61 return true; 62 return true;
62 } 63 }
63 64
65 void init(int32_t width,
66 int32_t height,
67 uint32_t genID,
68 SkScalar scaleX,
69 SkScalar scaleY) {
70 fBounds.set(0, 0, width, height);
71 fGenID = genID;
72 fScaleX = SkScalarToFloat(scaleX);
73 fScaleY = SkScalarToFloat(scaleY);
74 fHash = compute_hash(&fGenID, 7);
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
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 SkBitmap* scaled) {
225 Key key;
226 key.init(width, height, pixelGenerationID, SK_Scalar1, SK_Scalar1);
227 #ifdef USE_HASH
228 Rec* rec = fHash->find(key);
229 #else
230 Rec* rec = find_rec_in_list(fHead, key);
231 #endif
232 if (rec) {
233 this->moveToHead(rec); // for our LRU
234 rec->fLockCount += 1;
235 SkASSERT(NULL == rec->fMip);
236 SkASSERT(rec->fBitmap.pixelRef());
237 *scaled = rec->fBitmap;
238 }
239 return reinterpret_cast<ID*>(rec);
240 }
241
204 SkScaledImageCache::ID* SkScaledImageCache::findAndLock(const SkBitmap& orig, 242 SkScaledImageCache::ID* SkScaledImageCache::findAndLock(const SkBitmap& orig,
205 SkScalar scaleX, 243 SkScalar scaleX,
206 SkScalar scaleY, 244 SkScalar scaleY,
207 SkBitmap* scaled) { 245 SkBitmap* scaled) {
208 if (0 == scaleX || 0 == scaleY) { 246 if (0 == scaleX || 0 == scaleY) {
209 // degenerate, and the key we use for mipmaps 247 // degenerate, and the key we use for mipmaps
210 return NULL; 248 return NULL;
211 } 249 }
212 250
213 Rec* rec = this->findAndLock(orig, scaleX, scaleY); 251 Rec* rec = this->findAndLock(orig, scaleX, scaleY);
214 if (rec) { 252 if (rec) {
215 SkASSERT(NULL == rec->fMip); 253 SkASSERT(NULL == rec->fMip);
216 SkASSERT(rec->fBitmap.pixelRef()); 254 SkASSERT(rec->fBitmap.pixelRef());
217 *scaled = rec->fBitmap; 255 *scaled = rec->fBitmap;
218 } 256 }
219 return (ID*)rec; 257 return (ID*)rec;
220 } 258 }
221 259
222 SkScaledImageCache::ID* SkScaledImageCache::findAndLockMip(const SkBitmap& orig, 260 SkScaledImageCache::ID* SkScaledImageCache::findAndLockMip(const SkBitmap& orig,
223 SkMipMap const ** mip ) { 261 SkMipMap const ** mip ) {
224 Rec* rec = this->findAndLock(orig, 0, 0); 262 Rec* rec = this->findAndLock(orig, 0, 0);
225 if (rec) { 263 if (rec) {
226 SkASSERT(rec->fMip); 264 SkASSERT(rec->fMip);
227 SkASSERT(NULL == rec->fBitmap.pixelRef()); 265 SkASSERT(NULL == rec->fBitmap.pixelRef());
228 *mip = rec->fMip; 266 *mip = rec->fMip;
229 } 267 }
230 return (ID*)rec; 268 return (ID*)rec;
231 } 269 }
232 270
271 SkScaledImageCache::ID* SkScaledImageCache::addAndLock(
272 uint32_t pixelGenerationID,
273 int32_t width,
274 int32_t height,
275 const SkBitmap& scaled) {
276 Key key;
277 key.init(width, height, pixelGenerationID, SK_Scalar1, SK_Scalar1);
278 Rec* rec = SkNEW_ARGS(Rec, (key, scaled));
279 this->addToHead(rec);
280 SkASSERT(1 == rec->fLockCount);
281
282 #ifdef USE_HASH
283 fHash->add(rec);
284 #endif
285
286 // We may (now) be overbudget, so see if we need to purge something.
287 this->purgeAsNeeded();
288 return reinterpret_cast<ID*>(rec);
289 }
290
233 SkScaledImageCache::ID* SkScaledImageCache::addAndLock(const SkBitmap& orig, 291 SkScaledImageCache::ID* SkScaledImageCache::addAndLock(const SkBitmap& orig,
234 SkScalar scaleX, 292 SkScalar scaleX,
235 SkScalar scaleY, 293 SkScalar scaleY,
236 const SkBitmap& scaled) { 294 const SkBitmap& scaled) {
237 if (0 == scaleX || 0 == scaleY) { 295 if (0 == scaleX || 0 == scaleY) {
238 // degenerate, and the key we use for mipmaps 296 // degenerate, and the key we use for mipmaps
239 return NULL; 297 return NULL;
240 } 298 }
241 299
242 Key key; 300 Key key;
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 SkASSERT(0 == used); 502 SkASSERT(0 == used);
445 } 503 }
446 #endif 504 #endif
447 505
448 /////////////////////////////////////////////////////////////////////////////// 506 ///////////////////////////////////////////////////////////////////////////////
449 507
450 #include "SkThread.h" 508 #include "SkThread.h"
451 509
452 SK_DECLARE_STATIC_MUTEX(gMutex); 510 SK_DECLARE_STATIC_MUTEX(gMutex);
453 511
512 static void create_cache(SkScaledImageCache** cache) {
513 *cache = SkNEW_ARGS(SkScaledImageCache, (SK_DEFAULT_IMAGE_CACHE_LIMIT));
514 }
515
454 static SkScaledImageCache* get_cache() { 516 static SkScaledImageCache* get_cache() {
455 static SkScaledImageCache* gCache; 517 static SkScaledImageCache* gCache(NULL);
456 if (!gCache) { 518 SK_DECLARE_STATIC_ONCE(create_cache_once);
457 gCache = SkNEW_ARGS(SkScaledImageCache, (SK_DEFAULT_IMAGE_CACHE_LIMIT)); 519 SkOnce<SkScaledImageCache**>(&create_cache_once, create_cache, &gCache);
mtklein 2013/10/24 17:03:25 Just FYI, I think the <SkScaledImageCache**> will
458 } 520 SkASSERT(NULL != gCache);
459 return gCache; 521 return gCache;
460 } 522 }
461 523
524
525 SkScaledImageCache::ID* SkScaledImageCache::FindAndLock(
526 uint32_t pixelGenerationID,
527 int32_t width,
528 int32_t height,
529 SkBitmap* scaled) {
530 SkAutoMutexAcquire am(gMutex);
531 return get_cache()->findAndLock(pixelGenerationID, width, height, scaled);
532 }
533
534 SkScaledImageCache::ID* SkScaledImageCache::AddAndLock(
535 uint32_t pixelGenerationID,
536 int32_t width,
537 int32_t height,
538 const SkBitmap& scaled) {
539 SkAutoMutexAcquire am(gMutex);
540 return get_cache()->addAndLock(pixelGenerationID, width, height, scaled);
541 }
542
543
462 SkScaledImageCache::ID* SkScaledImageCache::FindAndLock(const SkBitmap& orig, 544 SkScaledImageCache::ID* SkScaledImageCache::FindAndLock(const SkBitmap& orig,
463 SkScalar scaleX, 545 SkScalar scaleX,
464 SkScalar scaleY, 546 SkScalar scaleY,
465 SkBitmap* scaled) { 547 SkBitmap* scaled) {
466 SkAutoMutexAcquire am(gMutex); 548 SkAutoMutexAcquire am(gMutex);
467 return get_cache()->findAndLock(orig, scaleX, scaleY, scaled); 549 return get_cache()->findAndLock(orig, scaleX, scaleY, scaled);
468 } 550 }
469 551
470 SkScaledImageCache::ID* SkScaledImageCache::FindAndLockMip(const SkBitmap& orig, 552 SkScaledImageCache::ID* SkScaledImageCache::FindAndLockMip(const SkBitmap& orig,
471 SkMipMap const ** mip) { 553 SkMipMap const ** mip) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 return SkScaledImageCache::GetBytesUsed(); 597 return SkScaledImageCache::GetBytesUsed();
516 } 598 }
517 599
518 size_t SkGraphics::GetImageCacheByteLimit() { 600 size_t SkGraphics::GetImageCacheByteLimit() {
519 return SkScaledImageCache::GetByteLimit(); 601 return SkScaledImageCache::GetByteLimit();
520 } 602 }
521 603
522 size_t SkGraphics::SetImageCacheByteLimit(size_t newLimit) { 604 size_t SkGraphics::SetImageCacheByteLimit(size_t newLimit) {
523 return SkScaledImageCache::SetByteLimit(newLimit); 605 return SkScaledImageCache::SetByteLimit(newLimit);
524 } 606 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698