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

Side by Side Diff: src/lazy/SkLazyPixelRef.cpp

Issue 37343002: Allow SkLazyPixelRef to use SkScaledImageCache (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: lint Created 7 years, 1 month 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 2012 Google Inc. 2 * Copyright 2012 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 "Sk64.h" 8 #include "Sk64.h"
9 #include "SkLazyPixelRef.h" 9 #include "SkLazyPixelRef.h"
10 #include "SkColorTable.h" 10 #include "SkColorTable.h"
11 #include "SkData.h" 11 #include "SkData.h"
12 #include "SkImageCache.h" 12 #include "SkImageCache.h"
13 #include "SkImagePriv.h" 13 #include "SkImagePriv.h"
14 #include "SkScaledImageCache.h"
14 15
15 #if LAZY_CACHE_STATS 16 #if LAZY_CACHE_STATS
16 #include "SkThread.h" 17 #include "SkThread.h"
17 18
18 int32_t SkLazyPixelRef::gCacheHits; 19 int32_t SkLazyPixelRef::gCacheHits;
19 int32_t SkLazyPixelRef::gCacheMisses; 20 int32_t SkLazyPixelRef::gCacheMisses;
20 #endif 21 #endif
21 22
22 SkLazyPixelRef::SkLazyPixelRef(SkData* data, SkBitmapFactory::DecodeProc proc, S kImageCache* cache) 23 SkLazyPixelRef::SkLazyPixelRef(SkData* data, SkBitmapFactory::DecodeProc proc, S kImageCache* cache)
23 // Pass NULL for the Mutex so that the default (ring buffer) will be used. 24 // Pass NULL for the Mutex so that the default (ring buffer) will be used.
24 : INHERITED(NULL) 25 : INHERITED(NULL)
26 , fErrorInDecoding(false)
25 , fDecodeProc(proc) 27 , fDecodeProc(proc)
26 , fImageCache(cache) 28 , fImageCache(cache)
27 , fCacheId(SkImageCache::UNINITIALIZED_ID) 29 , fRowBytes(0)
28 , fRowBytes(0) { 30 , fAllocator(NULL) {
29 SkASSERT(fDecodeProc != NULL); 31 SkASSERT(fDecodeProc != NULL);
30 if (NULL == data) { 32 if (NULL == data) {
31 fData = SkData::NewEmpty(); 33 fData = SkData::NewEmpty();
32 fErrorInDecoding = true; 34 fErrorInDecoding = true;
33 } else { 35 } else {
34 fData = data; 36 fData = data;
35 fData->ref(); 37 fData->ref();
36 fErrorInDecoding = data->size() == 0; 38 fErrorInDecoding = data->size() == 0;
37 } 39 }
38 SkASSERT(cache != NULL); 40 if (fImageCache != NULL) {
39 cache->ref(); 41 fImageCache->ref();
42 fCacheId = SkImageCache::UNINITIALIZED_ID;
43 } else {
44 fScaledCacheId = NULL;
45 }
40 46
41 // mark as uninitialized -- all fields are -1 47 // mark as uninitialized -- all fields are -1
42 memset(&fLazilyCachedInfo, 0xFF, sizeof(fLazilyCachedInfo)); 48 memset(&fLazilyCachedInfo, 0xFF, sizeof(fLazilyCachedInfo));
43 49
44 // Since this pixel ref bases its data on encoded data, it should never chan ge. 50 // Since this pixel ref bases its data on encoded data, it should never chan ge.
45 this->setImmutable(); 51 this->setImmutable();
46 } 52 }
47 53
48 SkLazyPixelRef::~SkLazyPixelRef() { 54 SkLazyPixelRef::~SkLazyPixelRef() {
49 SkASSERT(fData != NULL); 55 SkASSERT(fData != NULL);
50 fData->unref(); 56 fData->unref();
57 SkSafeUnref(fAllocator);
58 if (NULL == fImageCache) {
59 if (fScaledCacheId != NULL) {
60 SkScaledImageCache::Unlock(fScaledCacheId);
61 // TODO(halcanary): SkScaledImageCache needs a
62 // throwAwayCache(id) method.
63 }
64 return;
65 }
51 SkASSERT(fImageCache); 66 SkASSERT(fImageCache);
52 if (fCacheId != SkImageCache::UNINITIALIZED_ID) { 67 if (fCacheId != SkImageCache::UNINITIALIZED_ID) {
53 fImageCache->throwAwayCache(fCacheId); 68 fImageCache->throwAwayCache(fCacheId);
54 } 69 }
55 fImageCache->unref(); 70 fImageCache->unref();
56 } 71 }
57 72
58 static size_t ComputeMinRowBytesAndSize(const SkImage::Info& info, size_t* rowBy tes) { 73 static size_t ComputeMinRowBytesAndSize(const SkImage::Info& info, size_t* rowBy tes) {
59 *rowBytes = SkImageMinRowBytes(info); 74 *rowBytes = SkImageMinRowBytes(info);
60 75
(...skipping 11 matching lines...) Expand all
72 SkImage::Info info; 87 SkImage::Info info;
73 fErrorInDecoding = !fDecodeProc(fData->data(), fData->size(), &info, NUL L); 88 fErrorInDecoding = !fDecodeProc(fData->data(), fData->size(), &info, NUL L);
74 if (fErrorInDecoding) { 89 if (fErrorInDecoding) {
75 return NULL; 90 return NULL;
76 } 91 }
77 fLazilyCachedInfo = info; 92 fLazilyCachedInfo = info;
78 } 93 }
79 return &fLazilyCachedInfo; 94 return &fLazilyCachedInfo;
80 } 95 }
81 96
97 /**
98 Returns bitmap->getPixels() on success; NULL on failure */
99 static void* decode_into_bitmap(SkImage::Info* info,
100 SkBitmapFactory::DecodeProc decodeProc,
101 size_t* rowBytes,
102 SkData* data,
103 SkBitmap::Allocator* allocator,
104 SkBitmap* bm) {
105 SkASSERT(info && decodeProc && rowBytes && data && bm);
106 if (!(bm->setConfig(SkImageInfoToBitmapConfig(*info), info->fWidth,
107 info->fHeight, *rowBytes, info->fAlphaType)
108 && bm->allocPixels(allocator, NULL))) {
109 return NULL;
110 }
111 SkBitmapFactory::Target target;
112 target.fAddr = bm->getPixels();
113 target.fRowBytes = bm->rowBytes();
114 *rowBytes = target.fRowBytes;
115 // info must be non-const.
116 if (!decodeProc(data->data(), data->size(), info, &target)) {
117 return NULL;
118 }
119 return target.fAddr;
120 }
121
122 void* SkLazyPixelRef::lockScaledImageCachePixels() {
123 SkASSERT(!fErrorInDecoding);
124 SkASSERT(NULL == fImageCache);
125 SkBitmap bitmap;
126 SkImage::Info* info = const_cast<SkImage::Info*>(this->getCachedInfo());
127 if (info == NULL) {
128 return NULL;
129 }
130 // If this is the first time though, this is guaranteed to fail.
131 // Maybe we should have a flag that says "don't even bother looking"
132 fScaledCacheId = SkScaledImageCache::FindAndLock(this->getGenerationID(),
133 info->fWidth,
134 info->fHeight,
135 &bitmap);
136 if (fScaledCacheId != NULL) {
137 SkAutoLockPixels autoLockPixels(bitmap);
138 void* pixels = bitmap.getPixels();
139 SkASSERT(NULL != pixels);
140 // At this point, the autoLockPixels will unlockPixels()
141 // to remove bitmap's lock on the pixels. We will then
142 // destroy bitmap. The *only* guarantee that this pointer
143 // remains valid is the guarantee made by
144 // SkScaledImageCache that it will not destroy the *other*
145 // bitmap (SkScaledImageCache::Rec.fBitmap) that holds a
146 // reference to the concrete PixelRef while this record is
147 // locked.
148 return pixels;
149 } else {
150 // Cache has been purged, must re-decode.
151 void* pixels = decode_into_bitmap(info, fDecodeProc, &fRowBytes,
scroggo 2013/10/25 18:09:48 Since this is the only modifier of info, why not p
hal.canary 2013/10/25 20:49:38 Done.
152 fData, fAllocator, &bitmap);
153 if (NULL == pixels) {
154 fErrorInDecoding = true;
155 return NULL;
156 }
157 fScaledCacheId = SkScaledImageCache::AddAndLock(this->getGenerationID(),
158 info->fWidth,
159 info->fHeight,
160 bitmap);
161 SkASSERT(fScaledCacheId != NULL);
162 return pixels;
163 }
164 }
165
82 void* SkLazyPixelRef::onLockPixels(SkColorTable**) { 166 void* SkLazyPixelRef::onLockPixels(SkColorTable**) {
83 if (fErrorInDecoding) { 167 if (fErrorInDecoding) {
84 return NULL; 168 return NULL;
85 } 169 }
170 if (NULL == fImageCache) {
171 return this->lockScaledImageCachePixels();
172 } else {
173 return this->lockImageCachePixels();
174 }
175 }
176
177 void* SkLazyPixelRef::lockImageCachePixels() {
178 SkASSERT(fImageCache != NULL);
179 SkASSERT(!fErrorInDecoding);
86 SkBitmapFactory::Target target; 180 SkBitmapFactory::Target target;
87 // Check to see if the pixels still exist in the cache. 181 // Check to see if the pixels still exist in the cache.
88 if (SkImageCache::UNINITIALIZED_ID == fCacheId) { 182 if (SkImageCache::UNINITIALIZED_ID == fCacheId) {
89 target.fAddr = NULL; 183 target.fAddr = NULL;
90 } else { 184 } else {
91 SkImageCache::DataStatus status; 185 SkImageCache::DataStatus status;
92 target.fAddr = fImageCache->pinCache(fCacheId, &status); 186 target.fAddr = fImageCache->pinCache(fCacheId, &status);
93 if (target.fAddr == NULL) { 187 if (target.fAddr == NULL) {
94 fCacheId = SkImageCache::UNINITIALIZED_ID; 188 fCacheId = SkImageCache::UNINITIALIZED_ID;
95 } else { 189 } else {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 } 234 }
141 // Upon success, store fRowBytes so it can be used in case pinCache later re turns purged memory. 235 // Upon success, store fRowBytes so it can be used in case pinCache later re turns purged memory.
142 fRowBytes = target.fRowBytes; 236 fRowBytes = target.fRowBytes;
143 return target.fAddr; 237 return target.fAddr;
144 } 238 }
145 239
146 void SkLazyPixelRef::onUnlockPixels() { 240 void SkLazyPixelRef::onUnlockPixels() {
147 if (fErrorInDecoding) { 241 if (fErrorInDecoding) {
148 return; 242 return;
149 } 243 }
150 if (fCacheId != SkImageCache::UNINITIALIZED_ID) { 244 if (NULL == fImageCache) {
151 fImageCache->releaseCache(fCacheId); 245 // onUnlockPixels() should never be called a second time from
246 // PixelRef::Unlock() without calling onLockPixels() first.
247 SkASSERT(NULL != fScaledCacheId);
248 if (NULL != fScaledCacheId) {
249 SkScaledImageCache::Unlock(fScaledCacheId);
250 fScaledCacheId = NULL;
251 }
252 } else { // use fImageCache
253 SkASSERT(SkImageCache::UNINITIALIZED_ID != fCacheId);
254 if (SkImageCache::UNINITIALIZED_ID != fCacheId) {
255 fImageCache->releaseCache(fCacheId);
256 }
152 } 257 }
153 } 258 }
154 259
155 SkData* SkLazyPixelRef::onRefEncodedData() { 260 SkData* SkLazyPixelRef::onRefEncodedData() {
156 fData->ref(); 261 fData->ref();
157 return fData; 262 return fData;
158 } 263 }
159 264
160 #include "SkImagePriv.h"
161
162 static bool init_from_info(SkBitmap* bm, const SkImage::Info& info, 265 static bool init_from_info(SkBitmap* bm, const SkImage::Info& info,
163 size_t rowBytes) { 266 size_t rowBytes) {
164 SkBitmap::Config config = SkImageInfoToBitmapConfig(info); 267 SkBitmap::Config config = SkImageInfoToBitmapConfig(info);
165 if (SkBitmap::kNo_Config == config) { 268 if (SkBitmap::kNo_Config == config) {
166 return false; 269 return false;
167 } 270 }
168 271
169 return bm->setConfig(config, info.fWidth, info.fHeight, rowBytes, info.fAlph aType) 272 return bm->setConfig(config, info.fWidth, info.fHeight, rowBytes, info.fAlph aType)
170 && 273 &&
171 bm->allocPixels(); 274 bm->allocPixels();
(...skipping 27 matching lines...) Expand all
199 302
200 target.fAddr = tmp.getPixels(); 303 target.fAddr = tmp.getPixels();
201 fErrorInDecoding = !fDecodeProc(fData->data(), fData->size(), &info, &target ); 304 fErrorInDecoding = !fDecodeProc(fData->data(), fData->size(), &info, &target );
202 if (fErrorInDecoding) { 305 if (fErrorInDecoding) {
203 return false; 306 return false;
204 } 307 }
205 308
206 *bitmap = tmp; 309 *bitmap = tmp;
207 return true; 310 return true;
208 } 311 }
312
313 void SkLazyPixelRef::setAllocator(SkBitmap::Allocator* allocator) {
314 SkRefCnt_SafeAssign(fAllocator, allocator);
315 }
316
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698