Chromium Code Reviews| Index: src/lazy/SkBitmapFactory.cpp |
| diff --git a/src/lazy/SkBitmapFactory.cpp b/src/lazy/SkBitmapFactory.cpp |
| index 1bbb6f0de7d7dc53dfb192ed4d7325f6134c048e..4283071394c216006129461774090cb90d1592e6 100644 |
| --- a/src/lazy/SkBitmapFactory.cpp |
| +++ b/src/lazy/SkBitmapFactory.cpp |
| @@ -9,9 +9,10 @@ |
| #include "SkBitmap.h" |
| #include "SkData.h" |
| +#include "SkDiscardablePixelRef.h" |
| #include "SkImageCache.h" |
| +#include "SkDecodingImageGenerator.h" |
| #include "SkImagePriv.h" |
| -#include "SkLazyPixelRef.h" |
| SK_DEFINE_INST_COUNT(SkBitmapFactory::CacheSelector) |
| @@ -43,38 +44,75 @@ void SkBitmapFactory::setCacheSelector(CacheSelector* selector) { |
| } |
| } |
| +namespace { |
| +class FlexibleImageGenerator : public SkImageGenerator { |
| +public: |
| + FlexibleImageGenerator(SkBitmapFactory::DecodeProc proc, |
| + SkData* data) |
| + : fProc(proc), fData(data) { |
| + SkASSERT(fData); |
| + SkASSERT(fProc); |
| + fData->ref(); |
| + } |
| + ~FlexibleImageGenerator() { |
| + fData->unref(); |
| + } |
| + SkData* refEncodedData() { |
| + fData->ref(); |
| + return fData; |
| + } |
| + bool getInfo(SkImageInfo* info) { |
| + SkASSERT(info != NULL); |
| + return fProc(fData->data(), fData->size(), info, NULL); |
| + } |
| + bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) { |
| + SkASSERT(pixels != NULL); |
| + SkBitmapFactory::Target target = {pixels, rowBytes}; |
| + SkImageInfo tmpInfo = info; |
| + return fProc(fData->data(), fData->size(), &tmpInfo, &target); |
| + } |
| + |
| +private: |
| + SkBitmapFactory::DecodeProc fProc; |
| + SkData* fData; |
| +}; |
| +} // namespace |
| + |
| bool SkBitmapFactory::installPixelRef(SkData* data, SkBitmap* dst) { |
| if (NULL == data || 0 == data->size() || dst == NULL) { |
| return false; |
| } |
| + SkAutoTDelete<SkImageGenerator> gen(SkNEW_ARGS(FlexibleImageGenerator, |
| + (fDecodeProc, data))); |
| SkImageInfo info; |
| - if (!fDecodeProc(data->data(), data->size(), &info, NULL)) { |
| + if (!gen->getInfo(&info)) { |
| return false; |
| } |
| - SkBitmap::Config config = SkImageInfoToBitmapConfig(info); |
| - |
| - Target target; |
| - // FIMXE: There will be a problem if this rowbytes is calculated differently from |
| - // in SkLazyPixelRef. |
| - target.fRowBytes = SkImageMinRowBytes(info); |
| - dst->setConfig(config, info.fWidth, info.fHeight, target.fRowBytes, info.fAlphaType); |
| - |
| // fImageCache and fCacheSelector are mutually exclusive. |
| SkASSERT(NULL == fImageCache || NULL == fCacheSelector); |
| SkImageCache* cache = NULL == fCacheSelector ? fImageCache : fCacheSelector->selectCache(info); |
| + // TODO(halcanary): the SkBitmapFactory::CacheSelector needs a way |
| + // to specify that SkDiscardableMemory should be created via |
| + // SkDiscardableMemory::Create(). Currently, if the cache |
| + // selector reutuns NULL, that is taken as an instruction to use |
|
scroggo
2013/12/02 19:00:09
returns*
|
| + // normal malloc()ed pixels. |
| + |
| if (cache != NULL) { |
| - // Now set a new LazyPixelRef on dst. |
| - SkAutoTUnref<SkLazyPixelRef> lazyRef(SkNEW_ARGS(SkLazyPixelRef, |
| - (data, fDecodeProc, cache))); |
| - dst->setPixelRef(lazyRef); |
| - return true; |
| + return SkDiscardablePixelRef::Install(gen.detach(), dst, cache); |
| } else { |
| - dst->allocPixels(); |
| - target.fAddr = dst->getPixels(); |
| - return fDecodeProc(data->data(), data->size(), &info, &target); |
| + SkBitmap tmp; |
| + if (!tmp.setConfig(info, 0)) { |
| + return false; |
| + } |
| + tmp.allocPixels(); |
| + if (!gen->getPixels(info, tmp.getPixels(), tmp.rowBytes())) { |
| + return false; |
| + } |
| + dst->swap(tmp); |
| + return true; |
| } |
| } |