Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 368a7a51 authored by Leon Scroggins III's avatar Leon Scroggins III Committed by Leon Scroggins
Browse files

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
parent 99abec3d
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -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)) {
+2 −2
Original line number Diff line number Diff line
@@ -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;
+2 −1
Original line number Diff line number Diff line
@@ -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);