ImageDecoder: use kYes_ZeroInitialized memory
Bug: 183115528 Test: (A)ImageDecoderTest(s) (verify correctness) Test: monitor showmap_pss_bytes dashboards (verify memory impact) This lets the decoder leave zero initialized memory untouched. An Android feature makes untouched zero initialized memory cheaper, and BitmapFactory takes advantage of it. Do the same for ImageDecoder. This feature was originally brought up in b/10016979. ImageDecoder saved memory in other ways, and as I understand it, Android has shifted towards using (Animated)VectorDrawables. Both of these may have contributed to us not noticing when we switched from BitmapFactory to ImageDecoder. Change-Id: Iecfd1bbfdcc38e1f0bf380b4f4ea5b861cfcf08a
This commit is contained in:
committed by
Leon Scroggins
parent
99abec3d81
commit
368a7a51c6
@@ -45,7 +45,8 @@ sk_sp<SkColorSpace> ImageDecoder::getDefaultColorSpace() const {
|
||||
return SkColorSpace::MakeSRGB();
|
||||
}
|
||||
|
||||
ImageDecoder::ImageDecoder(std::unique_ptr<SkAndroidCodec> codec, sk_sp<SkPngChunkReader> peeker)
|
||||
ImageDecoder::ImageDecoder(std::unique_ptr<SkAndroidCodec> codec, sk_sp<SkPngChunkReader> peeker,
|
||||
SkCodec::ZeroInitialized zeroInit)
|
||||
: mCodec(std::move(codec))
|
||||
, mPeeker(std::move(peeker))
|
||||
, mDecodeSize(mCodec->codec()->dimensions())
|
||||
@@ -57,6 +58,7 @@ ImageDecoder::ImageDecoder(std::unique_ptr<SkAndroidCodec> codec, sk_sp<SkPngChu
|
||||
mTargetSize = swapWidthHeight() ? SkISize { mDecodeSize.height(), mDecodeSize.width() }
|
||||
: mDecodeSize;
|
||||
this->rewind();
|
||||
mOptions.fZeroInitialized = zeroInit;
|
||||
}
|
||||
|
||||
ImageDecoder::~ImageDecoder() = default;
|
||||
@@ -446,10 +448,17 @@ SkCodec::Result ImageDecoder::decode(void* pixels, size_t rowBytes) {
|
||||
ALOGE("Failed to invert matrix!");
|
||||
}
|
||||
}
|
||||
|
||||
// Even if the client did not provide zero initialized memory, the
|
||||
// memory we decode into is.
|
||||
mOptions.fZeroInitialized = SkCodec::kYes_ZeroInitialized;
|
||||
}
|
||||
|
||||
auto result = mCodec->getAndroidPixels(decodeInfo, decodePixels, decodeRowBytes, &mOptions);
|
||||
|
||||
// The next call to decode() may not provide zero initialized memory.
|
||||
mOptions.fZeroInitialized = SkCodec::kNo_ZeroInitialized;
|
||||
|
||||
if (scale || handleOrigin || mCropRect) {
|
||||
SkBitmap scaledBm;
|
||||
if (!scaledBm.installPixels(outputInfo, pixels, rowBytes)) {
|
||||
|
||||
@@ -34,8 +34,8 @@ public:
|
||||
std::unique_ptr<SkAndroidCodec> mCodec;
|
||||
sk_sp<SkPngChunkReader> mPeeker;
|
||||
|
||||
ImageDecoder(std::unique_ptr<SkAndroidCodec> codec,
|
||||
sk_sp<SkPngChunkReader> peeker = nullptr);
|
||||
ImageDecoder(std::unique_ptr<SkAndroidCodec> codec, sk_sp<SkPngChunkReader> peeker = nullptr,
|
||||
SkCodec::ZeroInitialized zeroInit = SkCodec::kNo_ZeroInitialized);
|
||||
~ImageDecoder();
|
||||
|
||||
SkISize getSampledDimensions(int sampleSize) const;
|
||||
|
||||
@@ -141,7 +141,8 @@ static jobject native_create(JNIEnv* env, std::unique_ptr<SkStream> stream,
|
||||
}
|
||||
|
||||
const bool isNinePatch = peeker->mPatch != nullptr;
|
||||
ImageDecoder* decoder = new ImageDecoder(std::move(androidCodec), std::move(peeker));
|
||||
ImageDecoder* decoder = new ImageDecoder(std::move(androidCodec), std::move(peeker),
|
||||
SkCodec::kYes_ZeroInitialized);
|
||||
return env->NewObject(gImageDecoder_class, gImageDecoder_constructorMethodID,
|
||||
reinterpret_cast<jlong>(decoder), decoder->width(), decoder->height(),
|
||||
animated, isNinePatch);
|
||||
|
||||
Reference in New Issue
Block a user