Chromium Code Reviews| Index: src/lazy/SkLazyPixelRef.cpp |
| diff --git a/src/lazy/SkLazyPixelRef.cpp b/src/lazy/SkLazyPixelRef.cpp |
| index 0454362b942f4e5ceb1aa5ece04270caa3e8f710..27285f137cb46f2486440b96e956112755993e59 100644 |
| --- a/src/lazy/SkLazyPixelRef.cpp |
| +++ b/src/lazy/SkLazyPixelRef.cpp |
| @@ -11,6 +11,7 @@ |
| #include "SkData.h" |
| #include "SkImageCache.h" |
| #include "SkImagePriv.h" |
| +#include "SkScaledImageCache.h" |
| #if LAZY_CACHE_STATS |
| #include "SkThread.h" |
| @@ -22,10 +23,12 @@ int32_t SkLazyPixelRef::gCacheMisses; |
| SkLazyPixelRef::SkLazyPixelRef(SkData* data, SkBitmapFactory::DecodeProc proc, SkImageCache* cache) |
| // Pass NULL for the Mutex so that the default (ring buffer) will be used. |
| : INHERITED(NULL) |
| + , fErrorInDecoding(false) |
| , fDecodeProc(proc) |
| , fImageCache(cache) |
| - , fCacheId(SkImageCache::UNINITIALIZED_ID) |
| - , fRowBytes(0) { |
| + , fCacheId(0) |
|
scroggo
2013/10/23 15:27:49
Could you add a comment or an assert that 0 is an
hal.canary
2013/10/23 16:11:52
Done.
|
| + , fRowBytes(0) |
| + , fAllocator(NULL) { |
| SkASSERT(fDecodeProc != NULL); |
| if (NULL == data) { |
| fData = SkData::NewEmpty(); |
| @@ -35,8 +38,9 @@ SkLazyPixelRef::SkLazyPixelRef(SkData* data, SkBitmapFactory::DecodeProc proc, S |
| fData->ref(); |
| fErrorInDecoding = data->size() == 0; |
| } |
| - SkASSERT(cache != NULL); |
| - cache->ref(); |
| + if (cache != NULL) { |
|
mtklein
2013/10/23 18:50:14
I'd slightly prefer it if you started calling it f
hal.canary
2013/10/23 22:57:41
Done.
|
| + cache->ref(); |
|
scroggo
2013/10/23 15:27:49
nit: 4 spaces
You could also use SkSafeRef, which
hal.canary
2013/10/23 16:11:52
Done.
|
| + } // else use global SkScaledImageCache |
| // mark as uninitialized -- all fields are -1 |
| memset(&fLazilyCachedInfo, 0xFF, sizeof(fLazilyCachedInfo)); |
| @@ -48,6 +52,12 @@ SkLazyPixelRef::SkLazyPixelRef(SkData* data, SkBitmapFactory::DecodeProc proc, S |
| SkLazyPixelRef::~SkLazyPixelRef() { |
| SkASSERT(fData != NULL); |
| fData->unref(); |
| + if (fImageCache == NULL) { |
|
scroggo
2013/10/23 15:27:49
nit: NULL == fImageCache
hal.canary
2013/10/23 16:11:52
Done.
|
| + if (fCacheId != 0) { |
| + SkScaledImageCache::Unlock((SkScaledImageCache::ID *)(fCacheId)); |
|
mtklein
2013/10/23 18:50:14
This sort of cast makes me nervous. Can we make f
hal.canary
2013/10/23 22:57:41
Can you show me what that would look like? I don'
mtklein
2013/10/24 16:52:12
In the header, replace this:
// fCacheId is a (S
|
| + } |
| + return; |
| + } |
| SkASSERT(fImageCache); |
| if (fCacheId != SkImageCache::UNINITIALIZED_ID) { |
| fImageCache->throwAwayCache(fCacheId); |
| @@ -79,10 +89,66 @@ const SkImage::Info* SkLazyPixelRef::getCachedInfo() { |
| return &fLazilyCachedInfo; |
| } |
| +/** |
| + Returns bitmap->getPixels() on success; NULL on failure */ |
| +static void * decode_into_bitmap(SkImage::Info * info, |
|
mtklein
2013/10/23 18:50:14
These *'s look wishy washy! Pick a side! (Choose
hal.canary
2013/10/23 22:57:41
Done.
|
| + SkBitmapFactory::DecodeProc decodeProc, |
| + size_t * rowBytes, |
| + SkData * data, |
| + SkBitmap::Allocator * allocator, |
| + SkBitmap * bm) { |
|
scroggo
2013/10/23 15:27:49
Maybe assert that none of these parameters are NUL
hal.canary
2013/10/23 16:11:52
Done.
|
| + if (!(bm->setConfig(SkImageInfoToBitmapConfig(*info), info->fWidth, |
| + info->fHeight, *rowBytes, info->fAlphaType) |
| + && bm->allocPixels(allocator, NULL))) { |
| + return NULL; |
| + } |
| + SkBitmapFactory::Target target; |
| + target.fAddr = bm->getPixels(); |
| + target.fRowBytes = bm->rowBytes(); |
| + *rowBytes = target.fRowBytes; |
| + if (!decodeProc(data->data(), data->size(), info, &target)) { |
| + return NULL; |
| + } |
| + return target.fAddr; |
| +} |
| + |
| void* SkLazyPixelRef::onLockPixels(SkColorTable**) { |
| if (fErrorInDecoding) { |
| return NULL; |
| } |
| + if (NULL == fImageCache) { |
|
mtklein
2013/10/23 18:50:14
Usually when the nesting gets this deep I think it
|
| + SkBitmap bitmap; |
| + if (fLazilyCachedInfo.fWidth > 0) { // fInfo already populated |
|
mtklein
2013/10/23 18:50:14
Sometimes a little private inline method can be he
mtklein
2013/10/23 18:50:14
We've got about three levels of code jammed into o
|
| + fCacheId = (intptr_t)(SkScaledImageCache::FindAndLock( |
| + this->getGenerationID(), |
| + fLazilyCachedInfo.fWidth, |
| + fLazilyCachedInfo.fHeight, |
| + SK_Scalar1, SK_Scalar1, &bitmap)); |
| + if (fCacheId != 0) { |
| + return bitmap.getPixels(); |
| + } // else cache has been purged, must re-decode. |
| + } else { // first time through this code, must populate info |
| + fErrorInDecoding = !fDecodeProc(fData->data(), fData->size(), |
| + &fLazilyCachedInfo, NULL); |
| + if (fErrorInDecoding) { |
| + return NULL; |
| + } |
| + } |
| + SkASSERT(fLazilyCachedInfo.fWidth > 0); |
| + void * ptr = decode_into_bitmap(&fLazilyCachedInfo, fDecodeProc, |
| + &fRowBytes, fData, fAllocator, &bitmap); |
| + if (NULL == ptr) { |
| + fErrorInDecoding = true; |
| + return NULL; |
| + } |
| + fCacheId = (intptr_t)(SkScaledImageCache::AddAndLock( |
| + this->getGenerationID(), |
| + fLazilyCachedInfo.fWidth, |
| + fLazilyCachedInfo.fHeight, |
| + SK_Scalar1, SK_Scalar1, bitmap)); |
| + return ptr; |
| + } |
| + // else use fImageCache |
| SkBitmapFactory::Target target; |
| // Check to see if the pixels still exist in the cache. |
| if (SkImageCache::UNINITIALIZED_ID == fCacheId) { |
| @@ -144,10 +210,14 @@ void* SkLazyPixelRef::onLockPixels(SkColorTable**) { |
| } |
| void SkLazyPixelRef::onUnlockPixels() { |
| - if (fErrorInDecoding) { |
| + if (fErrorInDecoding || (0 == fCacheId)) { |
| return; |
| } |
| - if (fCacheId != SkImageCache::UNINITIALIZED_ID) { |
| + if (NULL == fImageCache) { |
|
mtklein
2013/10/23 18:50:14
This guy is small enough that even I'd probably le
|
| + SkScaledImageCache::Unlock((SkScaledImageCache::ID *)(fCacheId)); |
| + fCacheId = 0; |
| + return; |
| + } else { // use fImageCache |
| fImageCache->releaseCache(fCacheId); |
| } |
| } |