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

Commit 6413aebc authored by Leon Scroggins's avatar Leon Scroggins Committed by android-build-merger
Browse files

Merge "Report native allocation size of AnimatedImageDrawable" into pi-dev

am: d848f75f

Change-Id: Ifc765e6ba33dcd7152e850ddbe88fc6b458f75af
parents c1fc34b1 d848f75f
Loading
Loading
Loading
Loading
+36 −5
Original line number Diff line number Diff line
@@ -42,7 +42,6 @@ static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/,
    }

    auto* imageDecoder = reinterpret_cast<ImageDecoder*>(nativeImageDecoder);
    auto info = imageDecoder->mCodec->getInfo();
    const SkISize scaledSize = SkISize::Make(width, height);
    SkIRect subset;
    if (jsubset) {
@@ -51,6 +50,35 @@ static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/,
        subset = SkIRect::MakeWH(width, height);
    }

    auto info = imageDecoder->mCodec->getInfo();
    bool hasRestoreFrame = false;
    if (imageDecoder->mCodec->getEncodedFormat() == SkEncodedImageFormat::kWEBP) {
        if (width < info.width() && height < info.height()) {
            // WebP will scale its SkBitmap to the scaled size.
            // FIXME: b/73529447 GIF should do the same.
            info = info.makeWH(width, height);
        }
    } else {
        const int frameCount = imageDecoder->mCodec->codec()->getFrameCount();
        for (int i = 0; i < frameCount; ++i) {
            SkCodec::FrameInfo frameInfo;
            if (!imageDecoder->mCodec->codec()->getFrameInfo(i, &frameInfo)) {
                doThrowIOE(env, "Failed to read frame info!");
                return 0;
            }
            if (frameInfo.fDisposalMethod == SkCodecAnimation::DisposalMethod::kRestorePrevious) {
                hasRestoreFrame = true;
                break;
            }
        }
    }

    size_t bytesUsed = info.computeMinByteSize();
    // SkAnimatedImage has one SkBitmap for decoding, plus an extra one if there is a
    // kRestorePrevious frame. AnimatedImageDrawable has two SkPictures storing the current
    // frame and the next frame. (The former assumes that the image is animated, and the
    // latter assumes that it is drawn to a hardware canvas.)
    bytesUsed *= hasRestoreFrame ? 4 : 3;
    sk_sp<SkPicture> picture;
    if (jpostProcess) {
        SkRect bounds = SkRect::MakeWH(subset.width(), subset.height());
@@ -63,6 +91,7 @@ static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/,
            return 0;
        }
        picture = recorder.finishRecordingAsPicture();
        bytesUsed += picture->approximateBytesUsed();
    }


@@ -74,7 +103,10 @@ static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/,
        return 0;
    }

    sk_sp<AnimatedImageDrawable> drawable(new AnimatedImageDrawable(animatedImg));
    bytesUsed += sizeof(animatedImg.get());

    sk_sp<AnimatedImageDrawable> drawable(new AnimatedImageDrawable(std::move(animatedImg),
                                                                    bytesUsed));
    return reinterpret_cast<jlong>(drawable.release());
}

@@ -202,10 +234,9 @@ static void AnimatedImageDrawable_nSetOnAnimationEndListener(JNIEnv* env, jobjec
    }
}

static long AnimatedImageDrawable_nNativeByteSize(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
static jlong AnimatedImageDrawable_nNativeByteSize(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
    auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
    // FIXME: Report the size of the internal SkBitmap etc.
    return sizeof(drawable);
    return drawable->byteSize();
}

static void AnimatedImageDrawable_nMarkInvisible(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
+1 −2
Original line number Diff line number Diff line
@@ -292,8 +292,7 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 {
        mState = new State(nCreate(nativeImageDecoder, decoder, width, height, cropRect),
                inputStream, afd);

        // FIXME: Use the right size for the native allocation.
        long nativeSize = 200;
        final long nativeSize = nNativeByteSize(mState.mNativePtr);
        NativeAllocationRegistry registry = new NativeAllocationRegistry(
                AnimatedImageDrawable.class.getClassLoader(), nGetNativeFinalizer(), nativeSize);
        registry.registerNativeAllocation(mState, mState.mNativePtr);
+2 −2
Original line number Diff line number Diff line
@@ -26,8 +26,8 @@

namespace android {

AnimatedImageDrawable::AnimatedImageDrawable(sk_sp<SkAnimatedImage> animatedImage)
        : mSkAnimatedImage(std::move(animatedImage)) {
AnimatedImageDrawable::AnimatedImageDrawable(sk_sp<SkAnimatedImage> animatedImage, size_t bytesUsed)
        : mSkAnimatedImage(std::move(animatedImage)), mBytesUsed(bytesUsed) {
    mTimeToShowNextSnapshot = mSkAnimatedImage->currentFrameDuration();
}

+9 −1
Original line number Diff line number Diff line
@@ -45,7 +45,9 @@ public:
 */
class ANDROID_API AnimatedImageDrawable : public SkDrawable {
public:
    AnimatedImageDrawable(sk_sp<SkAnimatedImage> animatedImage);
    // bytesUsed includes the approximate sizes of the SkAnimatedImage and the SkPictures in the
    // Snapshots.
    AnimatedImageDrawable(sk_sp<SkAnimatedImage> animatedImage, size_t bytesUsed);

    /**
     * This updates the internal time and returns true if the animation needs
@@ -100,11 +102,17 @@ public:
    Snapshot decodeNextFrame();
    Snapshot reset();

    size_t byteSize() const {
        return sizeof(this) + mBytesUsed;
    }

protected:
    virtual void onDraw(SkCanvas* canvas) override;

private:
    sk_sp<SkAnimatedImage> mSkAnimatedImage;
    const size_t mBytesUsed;

    bool mRunning = false;
    bool mStarting = false;