Remove bitmap reuse from SkImageDecoder.

Now that Android is using an SkBitmap::Allocator to reuse bitmap
memory, remove the unnecessary code to handle bitmap reuse inside
the decoders themselves.

Leaves in the code for bitmap reuse in decodeSubset, which still
may reuse bitmaps, and cropBitmap, which is called by decodeSubset.

R=djsollen@google.com

Review URL: https://codereview.chromium.org/17620004

git-svn-id: http://skia.googlecode.com/svn/trunk@9931 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
scroggo@google.com 2013-07-09 15:45:14 +00:00
parent 4b60dbe661
commit bc69ce982f
10 changed files with 46 additions and 116 deletions

View File

@ -117,10 +117,10 @@ public:
Peeker* getPeeker() const { return fPeeker; } Peeker* getPeeker() const { return fPeeker; }
Peeker* setPeeker(Peeker*); Peeker* setPeeker(Peeker*);
/** \class Peeker /** \class Chooser
Base class for optional callbacks to retrieve meta/chunk data out of Base class for optional callbacks to choose an image from a format that
an image as it is being decoded. contains multiple images.
*/ */
class Chooser : public SkRefCnt { class Chooser : public SkRefCnt {
public: public:
@ -219,11 +219,20 @@ public:
* to pref if possible. Whether a conversion is feasible is * to pref if possible. Whether a conversion is feasible is
* tested by Bitmap::canCopyTo(pref). * tested by Bitmap::canCopyTo(pref).
note: document use of Allocator, Peeker and Chooser If an SkBitmap::Allocator is installed via setAllocator, it will be
used to allocate the pixel memory. A clever allocator can be used
to allocate the memory from a cache, volatile memory, or even from
an existing bitmap's memory.
If a Peeker is installed via setPeeker, it may be used to peek into
meta data during the decode.
If a Chooser is installed via setChooser, it may be used to select
which image to return from a format that contains multiple images.
*/ */
bool decode(SkStream*, SkBitmap* bitmap, SkBitmap::Config pref, Mode, bool reuseBitmap = false); bool decode(SkStream*, SkBitmap* bitmap, SkBitmap::Config pref, Mode);
bool decode(SkStream* stream, SkBitmap* bitmap, Mode mode, bool reuseBitmap = false) { bool decode(SkStream* stream, SkBitmap* bitmap, Mode mode) {
return this->decode(stream, bitmap, SkBitmap::kNo_Config, mode, reuseBitmap); return this->decode(stream, bitmap, SkBitmap::kNo_Config, mode);
} }
/** /**

View File

@ -164,19 +164,12 @@ SkBitmap::Config SkImageDecoder::getPrefConfig(SrcDepth srcDepth,
} }
bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm,
SkBitmap::Config pref, Mode mode, bool reuseBitmap) { SkBitmap::Config pref, Mode mode) {
// we reset this to false before calling onDecode // we reset this to false before calling onDecode
fShouldCancelDecode = false; fShouldCancelDecode = false;
// assign this, for use by getPrefConfig(), in case fUsePrefTable is false // assign this, for use by getPrefConfig(), in case fUsePrefTable is false
fDefaultPref = pref; fDefaultPref = pref;
if (reuseBitmap) {
SkAutoLockPixels alp(*bm);
if (NULL != bm->getPixels()) {
return this->onDecode(stream, bm, mode);
}
}
// pass a temporary bitmap, so that if we return false, we are assured of // pass a temporary bitmap, so that if we return false, we are assured of
// leaving the caller's bitmap untouched. // leaving the caller's bitmap untouched.
SkBitmap tmp; SkBitmap tmp;

View File

@ -130,19 +130,13 @@ bool SkBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
SkScaledBitmapSampler sampler(width, height, getSampleSize()); SkScaledBitmapSampler sampler(width, height, getSampleSize());
if (justBounds) {
bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight());
bm->setIsOpaque(true);
return true;
}
// No Bitmap reuse supported for this format
if (!bm->isNull()) {
return false;
}
bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight()); bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight());
bm->setIsOpaque(true); bm->setIsOpaque(true);
if (justBounds) {
return true;
}
if (!this->allocPixelRef(bm, NULL)) { if (!this->allocPixelRef(bm, NULL)) {
return false; return false;
} }

View File

@ -202,17 +202,11 @@ bool SkGIFImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* bm, Mode mode) {
return error_return(gif, *bm, "chooseFromOneChoice"); return error_return(gif, *bm, "chooseFromOneChoice");
} }
bm->setConfig(SkBitmap::kIndex8_Config, width, height);
if (SkImageDecoder::kDecodeBounds_Mode == mode) { if (SkImageDecoder::kDecodeBounds_Mode == mode) {
bm->setConfig(SkBitmap::kIndex8_Config, width, height);
return true; return true;
} }
// No Bitmap reuse supported for this format
if (!bm->isNull()) {
return false;
}
bm->setConfig(SkBitmap::kIndex8_Config, width, height);
SavedImage* image = &gif->SavedImages[gif->ImageCount-1]; SavedImage* image = &gif->SavedImages[gif->ImageCount-1];
const GifImageDesc& desc = image->ImageDesc; const GifImageDesc& desc = image->ImageDesc;

View File

@ -232,16 +232,12 @@ bool SkICOImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode)
//if the andbitmap (mask) is all zeroes, then we can easily do an index bitmap //if the andbitmap (mask) is all zeroes, then we can easily do an index bitmap
//however, with small images with large colortables, maybe it's better to still do argb_8888 //however, with small images with large colortables, maybe it's better to still do argb_8888
bm->setConfig(SkBitmap::kARGB_8888_Config, w, h, calculateRowBytesFor8888(w, bitCount));
if (SkImageDecoder::kDecodeBounds_Mode == mode) { if (SkImageDecoder::kDecodeBounds_Mode == mode) {
bm->setConfig(SkBitmap::kARGB_8888_Config, w, h, calculateRowBytesFor8888(w, bitCount));
delete[] colors; delete[] colors;
return true; return true;
} }
// No Bitmap reuse supported for this format
if (!bm->isNull()) {
return false;
}
bm->setConfig(SkBitmap::kARGB_8888_Config, w, h, calculateRowBytesFor8888(w, bitCount));
if (!this->allocPixelRef(bm, NULL)) if (!this->allocPixelRef(bm, NULL))
{ {

View File

@ -357,29 +357,13 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
} }
SkScaledBitmapSampler sampler(cinfo.output_width, cinfo.output_height, sampleSize); SkScaledBitmapSampler sampler(cinfo.output_width, cinfo.output_height, sampleSize);
bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight());
bm->lockPixels(); bm->setIsOpaque(true);
JSAMPLE* rowptr = (JSAMPLE*)bm->getPixels(); if (SkImageDecoder::kDecodeBounds_Mode == mode) {
bm->unlockPixels(); return true;
bool reuseBitmap = (rowptr != NULL); }
if (!this->allocPixelRef(bm, NULL)) {
if (reuseBitmap) { return return_false(cinfo, *bm, "allocPixelRef");
if (sampler.scaledWidth() != bm->width() ||
sampler.scaledHeight() != bm->height()) {
// Dimensions must match
return false;
} else if (SkImageDecoder::kDecodeBounds_Mode == mode) {
return true;
}
} else {
bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight());
bm->setIsOpaque(true);
if (SkImageDecoder::kDecodeBounds_Mode == mode) {
return true;
}
if (!this->allocPixelRef(bm, NULL)) {
return return_false(cinfo, *bm, "allocPixelRef");
}
} }
SkAutoLockPixels alp(*bm); SkAutoLockPixels alp(*bm);
@ -394,7 +378,7 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
(config == SkBitmap::kRGB_565_Config && (config == SkBitmap::kRGB_565_Config &&
cinfo.out_color_space == JCS_RGB_565))) cinfo.out_color_space == JCS_RGB_565)))
{ {
rowptr = (JSAMPLE*)bm->getPixels(); JSAMPLE* rowptr = (JSAMPLE*)bm->getPixels();
INT32 const bpr = bm->rowBytes(); INT32 const bpr = bm->rowBytes();
while (cinfo.output_scanline < cinfo.output_height) { while (cinfo.output_scanline < cinfo.output_height) {
@ -409,9 +393,6 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
} }
rowptr += bpr; rowptr += bpr;
} }
if (reuseBitmap) {
bm->notifyPixelsChanged();
}
jpeg_finish_decompress(&cinfo); jpeg_finish_decompress(&cinfo);
return true; return true;
} }
@ -481,9 +462,6 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
cinfo.output_height - cinfo.output_scanline)) { cinfo.output_height - cinfo.output_scanline)) {
return return_false(cinfo, *bm, "skip rows"); return return_false(cinfo, *bm, "skip rows");
} }
if (reuseBitmap) {
bm->notifyPixelsChanged();
}
jpeg_finish_decompress(&cinfo); jpeg_finish_decompress(&cinfo);
return true; return true;

View File

@ -299,21 +299,8 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap,
const int sampleSize = this->getSampleSize(); const int sampleSize = this->getSampleSize();
SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize); SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize);
decodedBitmap->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight());
decodedBitmap->lockPixels();
void* rowptr = (void*) decodedBitmap->getPixels();
bool reuseBitmap = (rowptr != NULL);
decodedBitmap->unlockPixels();
if (reuseBitmap && (sampler.scaledWidth() != decodedBitmap->width() ||
sampler.scaledHeight() != decodedBitmap->height())) {
// Dimensions must match
return false;
}
if (!reuseBitmap) {
decodedBitmap->setConfig(config, sampler.scaledWidth(),
sampler.scaledHeight());
}
if (SkImageDecoder::kDecodeBounds_Mode == mode) { if (SkImageDecoder::kDecodeBounds_Mode == mode) {
return true; return true;
} }
@ -332,11 +319,9 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap,
SkAutoUnref aur(colorTable); SkAutoUnref aur(colorTable);
if (!reuseBitmap) { if (!this->allocPixelRef(decodedBitmap,
if (!this->allocPixelRef(decodedBitmap, SkBitmap::kIndex8_Config == config ? colorTable : NULL)) {
SkBitmap::kIndex8_Config == config ? colorTable : NULL)) { return false;
return false;
}
} }
SkAutoLockPixels alp(*decodedBitmap); SkAutoLockPixels alp(*decodedBitmap);
@ -445,9 +430,6 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap,
return false; return false;
} }
decodedBitmap->setIsOpaque(!reallyHasAlpha); decodedBitmap->setIsOpaque(!reallyHasAlpha);
if (reuseBitmap) {
decodedBitmap->notifyPixelsChanged();
}
return true; return true;
} }

View File

@ -412,25 +412,16 @@ bool SkWEBPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap,
const int sampleSize = this->getSampleSize(); const int sampleSize = this->getSampleSize();
SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize); SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize);
// If only bounds are requested, done
if (SkImageDecoder::kDecodeBounds_Mode == mode) {
if (!setDecodeConfig(decodedBitmap, sampler.scaledWidth(),
sampler.scaledHeight())) {
return false;
}
return true;
}
// No Bitmap reuse supported for this format
if (!decodedBitmap->isNull()) {
return false;
}
if (!setDecodeConfig(decodedBitmap, sampler.scaledWidth(), if (!setDecodeConfig(decodedBitmap, sampler.scaledWidth(),
sampler.scaledHeight())) { sampler.scaledHeight())) {
return false; return false;
} }
// If only bounds are requested, done
if (SkImageDecoder::kDecodeBounds_Mode == mode) {
return true;
}
if (!this->allocPixelRef(decodedBitmap, NULL)) { if (!this->allocPixelRef(decodedBitmap, NULL)) {
return return_false(*decodedBitmap, "allocPixelRef"); return return_false(*decodedBitmap, "allocPixelRef");
} }

View File

@ -111,20 +111,13 @@ bool SkWBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap,
int width = head.fWidth; int width = head.fWidth;
int height = head.fHeight; int height = head.fHeight;
if (SkImageDecoder::kDecodeBounds_Mode == mode) {
decodedBitmap->setConfig(SkBitmap::kIndex8_Config, width, height);
decodedBitmap->setIsOpaque(true);
return true;
}
// No Bitmap reuse supported for this format
if (!decodedBitmap->isNull()) {
return false;
}
decodedBitmap->setConfig(SkBitmap::kIndex8_Config, width, height); decodedBitmap->setConfig(SkBitmap::kIndex8_Config, width, height);
decodedBitmap->setIsOpaque(true); decodedBitmap->setIsOpaque(true);
if (SkImageDecoder::kDecodeBounds_Mode == mode) {
return true;
}
const SkPMColor colors[] = { SK_ColorBLACK, SK_ColorWHITE }; const SkPMColor colors[] = { SK_ColorBLACK, SK_ColorWHITE };
SkColorTable* ct = SkNEW_ARGS(SkColorTable, (colors, 2)); SkColorTable* ct = SkNEW_ARGS(SkColorTable, (colors, 2));
SkAutoUnref aur(ct); SkAutoUnref aur(ct);

View File

@ -27,7 +27,7 @@ bool SkImageDecoder::DecodeFile(const char[], SkBitmap*, SkBitmap::Config,
return false; return false;
} }
bool SkImageDecoder::decode(SkStream*, SkBitmap*, SkBitmap::Config, Mode, bool) { bool SkImageDecoder::decode(SkStream*, SkBitmap*, SkBitmap::Config, Mode) {
return false; return false;
} }