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

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

Issue 68973005: Expand pixelref to return SkImageInfo and rowbytes (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: new convention: require SkImageInfo in constructor Created 7 years 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 #include "SkScaledImageCache.h"
15 15
16 #if LAZY_CACHE_STATS 16 #if LAZY_CACHE_STATS
17 #include "SkThread.h" 17 #include "SkThread.h"
18 18
19 int32_t SkLazyPixelRef::gCacheHits; 19 int32_t SkLazyPixelRef::gCacheHits;
20 int32_t SkLazyPixelRef::gCacheMisses; 20 int32_t SkLazyPixelRef::gCacheMisses;
21 #endif 21 #endif
22 22
23 SkLazyPixelRef::SkLazyPixelRef(SkData* data, SkBitmapFactory::DecodeProc proc, S kImageCache* cache) 23 SkLazyPixelRef::SkLazyPixelRef(const SkImageInfo& info, SkData* data,
24 SkBitmapFactory::DecodeProc proc,
25 SkImageCache* cache)
24 // Pass NULL for the Mutex so that the default (ring buffer) will be used. 26 // Pass NULL for the Mutex so that the default (ring buffer) will be used.
25 : INHERITED(NULL) 27 : INHERITED(info)
26 , fErrorInDecoding(false) 28 , fErrorInDecoding(false)
27 , fDecodeProc(proc) 29 , fDecodeProc(proc)
28 , fImageCache(cache) 30 , fImageCache(cache)
29 , fRowBytes(0) { 31 , fRowBytes(0)
32 {
30 SkASSERT(fDecodeProc != NULL); 33 SkASSERT(fDecodeProc != NULL);
31 if (NULL == data) { 34 if (NULL == data) {
32 fData = SkData::NewEmpty(); 35 fData = SkData::NewEmpty();
33 fErrorInDecoding = true; 36 fErrorInDecoding = true;
34 } else { 37 } else {
35 fData = data; 38 fData = data;
36 fData->ref(); 39 fData->ref();
37 fErrorInDecoding = data->size() == 0; 40 fErrorInDecoding = data->size() == 0;
38 } 41 }
39 if (fImageCache != NULL) { 42 if (fImageCache != NULL) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 SkBitmapFactory::Target target; 114 SkBitmapFactory::Target target;
112 target.fAddr = bm->getPixels(); 115 target.fAddr = bm->getPixels();
113 target.fRowBytes = bm->rowBytes(); 116 target.fRowBytes = bm->rowBytes();
114 *rowBytes = target.fRowBytes; 117 *rowBytes = target.fRowBytes;
115 if (!decodeProc(data->data(), data->size(), info, &target)) { 118 if (!decodeProc(data->data(), data->size(), info, &target)) {
116 return NULL; 119 return NULL;
117 } 120 }
118 return target.fAddr; 121 return target.fAddr;
119 } 122 }
120 123
121 void* SkLazyPixelRef::lockScaledImageCachePixels() { 124 bool SkLazyPixelRef::lockScaledImageCachePixels(LockRec* rec) {
122 SkASSERT(!fErrorInDecoding); 125 SkASSERT(!fErrorInDecoding);
123 SkASSERT(NULL == fImageCache); 126 SkASSERT(NULL == fImageCache);
124 SkBitmap bitmap; 127 SkBitmap bitmap;
125 const SkImageInfo* info = this->getCachedInfo(); 128 const SkImageInfo* info = this->getCachedInfo();
126 if (info == NULL) { 129 if (NULL == info) {
127 return NULL; 130 return false;
128 } 131 }
132
129 // If this is the first time though, this is guaranteed to fail. 133 // If this is the first time though, this is guaranteed to fail.
130 // Maybe we should have a flag that says "don't even bother looking" 134 // Maybe we should have a flag that says "don't even bother looking"
131 fScaledCacheId = SkScaledImageCache::FindAndLock(this->getGenerationID(), 135 fScaledCacheId = SkScaledImageCache::FindAndLock(this->getGenerationID(),
132 info->fWidth, 136 info->fWidth,
133 info->fHeight, 137 info->fHeight,
134 &bitmap); 138 &bitmap);
139 void* pixels;
135 if (fScaledCacheId != NULL) { 140 if (fScaledCacheId != NULL) {
136 SkAutoLockPixels autoLockPixels(bitmap); 141 SkAutoLockPixels autoLockPixels(bitmap);
137 void* pixels = bitmap.getPixels(); 142 pixels = bitmap.getPixels();
138 SkASSERT(NULL != pixels); 143 SkASSERT(NULL != pixels);
139 // At this point, the autoLockPixels will unlockPixels() 144 // At this point, the autoLockPixels will unlockPixels()
140 // to remove bitmap's lock on the pixels. We will then 145 // to remove bitmap's lock on the pixels. We will then
141 // destroy bitmap. The *only* guarantee that this pointer 146 // destroy bitmap. The *only* guarantee that this pointer
142 // remains valid is the guarantee made by 147 // remains valid is the guarantee made by
143 // SkScaledImageCache that it will not destroy the *other* 148 // SkScaledImageCache that it will not destroy the *other*
144 // bitmap (SkScaledImageCache::Rec.fBitmap) that holds a 149 // bitmap (SkScaledImageCache::Rec.fBitmap) that holds a
145 // reference to the concrete PixelRef while this record is 150 // reference to the concrete PixelRef while this record is
146 // locked. 151 // locked.
147 return pixels;
148 } else { 152 } else {
149 // Cache has been purged, must re-decode. 153 // Cache has been purged, must re-decode.
150 void* pixels = decode_into_bitmap(const_cast<SkImageInfo*>(info), 154 pixels = decode_into_bitmap(const_cast<SkImageInfo*>(info), fDecodeProc,
151 fDecodeProc, &fRowBytes, fData, 155 &fRowBytes, fData, &bitmap);
152 &bitmap);
153 if (NULL == pixels) { 156 if (NULL == pixels) {
154 fErrorInDecoding = true; 157 fErrorInDecoding = true;
155 return NULL; 158 return NULL;
156 } 159 }
157 fScaledCacheId = SkScaledImageCache::AddAndLock(this->getGenerationID(), 160 fScaledCacheId = SkScaledImageCache::AddAndLock(this->getGenerationID(),
158 info->fWidth, 161 info->fWidth,
159 info->fHeight, 162 info->fHeight,
160 bitmap); 163 bitmap);
161 SkASSERT(fScaledCacheId != NULL); 164 SkASSERT(fScaledCacheId != NULL);
162 return pixels;
163 } 165 }
166
167 rec->fPixels = pixels;
168 rec->fColorTable = NULL;
169 rec->fRowBytes = bitmap.rowBytes();
170 return true;
164 } 171 }
165 172
166 void* SkLazyPixelRef::onLockPixels(SkColorTable**) { 173 bool SkLazyPixelRef::lockImageCachePixels(LockRec* rec) {
167 if (fErrorInDecoding) {
168 return NULL;
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); 174 SkASSERT(fImageCache != NULL);
179 SkASSERT(!fErrorInDecoding); 175 SkASSERT(!fErrorInDecoding);
180 SkBitmapFactory::Target target; 176 SkBitmapFactory::Target target;
181 // Check to see if the pixels still exist in the cache. 177 // Check to see if the pixels still exist in the cache.
182 if (SkImageCache::UNINITIALIZED_ID == fCacheId) { 178 if (SkImageCache::UNINITIALIZED_ID == fCacheId) {
183 target.fAddr = NULL; 179 target.fAddr = NULL;
184 } else { 180 } else {
185 SkImageCache::DataStatus status; 181 SkImageCache::DataStatus status;
186 target.fAddr = fImageCache->pinCache(fCacheId, &status); 182 target.fAddr = fImageCache->pinCache(fCacheId, &status);
187 if (target.fAddr == NULL) { 183 if (target.fAddr == NULL) {
(...skipping 12 matching lines...) Expand all
200 #if LAZY_CACHE_STATS 196 #if LAZY_CACHE_STATS
201 sk_atomic_inc(&gCacheMisses); 197 sk_atomic_inc(&gCacheMisses);
202 #endif 198 #endif
203 } 199 }
204 200
205 SkASSERT(fData != NULL && fData->size() > 0); 201 SkASSERT(fData != NULL && fData->size() > 0);
206 if (NULL == target.fAddr) { 202 if (NULL == target.fAddr) {
207 const SkImageInfo* info = this->getCachedInfo(); 203 const SkImageInfo* info = this->getCachedInfo();
208 if (NULL == info) { 204 if (NULL == info) {
209 SkASSERT(SkImageCache::UNINITIALIZED_ID == fCacheId); 205 SkASSERT(SkImageCache::UNINITIALIZED_ID == fCacheId);
210 return NULL; 206 return false;
211 } 207 }
212 size_t bytes = ComputeMinRowBytesAndSize(*info, &target.fRowBytes); 208 size_t bytes = ComputeMinRowBytesAndSize(*info, &target.fRowBytes);
213 target.fAddr = fImageCache->allocAndPinCache(bytes, &fCacheId); 209 target.fAddr = fImageCache->allocAndPinCache(bytes, &fCacheId);
214 if (NULL == target.fAddr) { 210 if (NULL == target.fAddr) {
215 // Space could not be allocated. 211 // Space could not be allocated.
216 // Just like the last assert, fCacheId must be UNINITIALIZED_ID. 212 // Just like the last assert, fCacheId must be UNINITIALIZED_ID.
217 SkASSERT(SkImageCache::UNINITIALIZED_ID == fCacheId); 213 SkASSERT(SkImageCache::UNINITIALIZED_ID == fCacheId);
218 return NULL; 214 return false;
219 } 215 }
220 } else { 216 } else {
221 // pinCache returned purged memory to which target.fAddr already points. Set 217 // pinCache returned purged memory to which target.fAddr already points. Set
222 // target.fRowBytes properly. 218 // target.fRowBytes properly.
223 target.fRowBytes = fRowBytes; 219 target.fRowBytes = fRowBytes;
224 // Assume that the size is correct, since it was determined by this same function 220 // Assume that the size is correct, since it was determined by this same function
225 // previously. 221 // previously.
226 } 222 }
227 SkASSERT(target.fAddr != NULL); 223 SkASSERT(target.fAddr != NULL);
228 SkASSERT(SkImageCache::UNINITIALIZED_ID != fCacheId); 224 SkASSERT(SkImageCache::UNINITIALIZED_ID != fCacheId);
229 fErrorInDecoding = !fDecodeProc(fData->data(), fData->size(), NULL, &target) ; 225 fErrorInDecoding = !fDecodeProc(fData->data(), fData->size(), NULL, &target) ;
230 if (fErrorInDecoding) { 226 if (fErrorInDecoding) {
231 fImageCache->throwAwayCache(fCacheId); 227 fImageCache->throwAwayCache(fCacheId);
232 fCacheId = SkImageCache::UNINITIALIZED_ID; 228 fCacheId = SkImageCache::UNINITIALIZED_ID;
233 return NULL; 229 return NULL;
234 } 230 }
235 // Upon success, store fRowBytes so it can be used in case pinCache later re turns purged memory. 231 // Upon success, store fRowBytes so it can be used in case pinCache later re turns purged memory.
236 fRowBytes = target.fRowBytes; 232 fRowBytes = target.fRowBytes;
237 return target.fAddr; 233
234 rec->fPixels = target.fAddr;
235 rec->fColorTable = NULL;
236 rec->fRowBytes = target.fRowBytes;
237 return true;
238 }
239
240 ///////////////////////////////////////////////////////////////////////////////
241
242 bool SkLazyPixelRef::onNewLockPixels(LockRec* rec) {
243 if (fErrorInDecoding) {
244 return false;
245 }
246 if (NULL == fImageCache) {
247 return this->lockScaledImageCachePixels(rec);
248 } else {
249 return this->lockImageCachePixels(rec);
250 }
238 } 251 }
239 252
240 void SkLazyPixelRef::onUnlockPixels() { 253 void SkLazyPixelRef::onUnlockPixels() {
241 if (fErrorInDecoding) { 254 if (fErrorInDecoding) {
242 return; 255 return;
243 } 256 }
244 if (NULL == fImageCache) { 257 if (NULL == fImageCache) {
245 // onUnlockPixels() should never be called a second time from 258 // onUnlockPixels() should never be called a second time from
246 // PixelRef::Unlock() without calling onLockPixels() first. 259 // PixelRef::Unlock() without calling onLockPixels() first.
247 SkASSERT(NULL != fScaledCacheId); 260 SkASSERT(NULL != fScaledCacheId);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 315
303 target.fAddr = tmp.getPixels(); 316 target.fAddr = tmp.getPixels();
304 fErrorInDecoding = !fDecodeProc(fData->data(), fData->size(), &info, &target ); 317 fErrorInDecoding = !fDecodeProc(fData->data(), fData->size(), &info, &target );
305 if (fErrorInDecoding) { 318 if (fErrorInDecoding) {
306 return false; 319 return false;
307 } 320 }
308 321
309 *bitmap = tmp; 322 *bitmap = tmp;
310 return true; 323 return true;
311 } 324 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698