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

am: d848f75f99

Change-Id: Ifc765e6ba33dcd7152e850ddbe88fc6b458f75af
This commit is contained in:
Leon Scroggins
2018-03-21 17:20:16 +00:00
committed by android-build-merger
4 changed files with 48 additions and 10 deletions

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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;