Loading core/jni/android/graphics/AnimatedImageDrawable.cpp +36 −5 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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()); Loading @@ -63,6 +91,7 @@ static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/, return 0; } picture = recorder.finishRecordingAsPicture(); bytesUsed += picture->approximateBytesUsed(); } Loading @@ -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()); } Loading Loading @@ -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) { Loading graphics/java/android/graphics/drawable/AnimatedImageDrawable.java +1 −2 Original line number Diff line number Diff line Loading @@ -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); Loading libs/hwui/hwui/AnimatedImageDrawable.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -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(); } Loading libs/hwui/hwui/AnimatedImageDrawable.h +9 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading Loading
core/jni/android/graphics/AnimatedImageDrawable.cpp +36 −5 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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()); Loading @@ -63,6 +91,7 @@ static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/, return 0; } picture = recorder.finishRecordingAsPicture(); bytesUsed += picture->approximateBytesUsed(); } Loading @@ -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()); } Loading Loading @@ -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) { Loading
graphics/java/android/graphics/drawable/AnimatedImageDrawable.java +1 −2 Original line number Diff line number Diff line Loading @@ -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); Loading
libs/hwui/hwui/AnimatedImageDrawable.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -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(); } Loading
libs/hwui/hwui/AnimatedImageDrawable.h +9 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading