Merge "Follow Firefox & Chrome GIF behavior" into udc-dev

This commit is contained in:
John Reck
2023-04-07 14:16:35 +00:00
committed by Android (Google) Code Review
3 changed files with 39 additions and 17 deletions

View File

@@ -29,9 +29,10 @@
namespace android {
AnimatedImageDrawable::AnimatedImageDrawable(sk_sp<SkAnimatedImage> animatedImage, size_t bytesUsed)
: mSkAnimatedImage(std::move(animatedImage)), mBytesUsed(bytesUsed) {
mTimeToShowNextSnapshot = ms2ns(mSkAnimatedImage->currentFrameDuration());
AnimatedImageDrawable::AnimatedImageDrawable(sk_sp<SkAnimatedImage> animatedImage, size_t bytesUsed,
SkEncodedImageFormat format)
: mSkAnimatedImage(std::move(animatedImage)), mBytesUsed(bytesUsed), mFormat(format) {
mTimeToShowNextSnapshot = ms2ns(currentFrameDuration());
setStagingBounds(mSkAnimatedImage->getBounds());
}
@@ -92,7 +93,7 @@ bool AnimatedImageDrawable::isDirty(nsecs_t* outDelay) {
// directly from mSkAnimatedImage.
lock.unlock();
std::unique_lock imageLock{mImageLock};
*outDelay = ms2ns(mSkAnimatedImage->currentFrameDuration());
*outDelay = ms2ns(currentFrameDuration());
return true;
} else {
// The next snapshot has not yet been decoded, but we've already passed
@@ -109,7 +110,7 @@ AnimatedImageDrawable::Snapshot AnimatedImageDrawable::decodeNextFrame() {
Snapshot snap;
{
std::unique_lock lock{mImageLock};
snap.mDurationMS = mSkAnimatedImage->decodeNextFrame();
snap.mDurationMS = adjustFrameDuration(mSkAnimatedImage->decodeNextFrame());
snap.mPic.reset(mSkAnimatedImage->newPictureSnapshot());
}
@@ -123,7 +124,7 @@ AnimatedImageDrawable::Snapshot AnimatedImageDrawable::reset() {
std::unique_lock lock{mImageLock};
mSkAnimatedImage->reset();
snap.mPic.reset(mSkAnimatedImage->newPictureSnapshot());
snap.mDurationMS = mSkAnimatedImage->currentFrameDuration();
snap.mDurationMS = currentFrameDuration();
}
return snap;
@@ -274,7 +275,7 @@ int AnimatedImageDrawable::drawStaging(SkCanvas* canvas) {
{
std::unique_lock lock{mImageLock};
mSkAnimatedImage->reset();
durationMS = mSkAnimatedImage->currentFrameDuration();
durationMS = currentFrameDuration();
}
{
std::unique_lock lock{mSwapLock};
@@ -306,7 +307,7 @@ int AnimatedImageDrawable::drawStaging(SkCanvas* canvas) {
{
std::unique_lock lock{mImageLock};
if (update) {
durationMS = mSkAnimatedImage->decodeNextFrame();
durationMS = adjustFrameDuration(mSkAnimatedImage->decodeNextFrame());
}
canvas->drawDrawable(mSkAnimatedImage.get());
@@ -336,4 +337,20 @@ SkRect AnimatedImageDrawable::onGetBounds() {
return SkRectMakeLargest();
}
int AnimatedImageDrawable::adjustFrameDuration(int durationMs) {
if (durationMs == SkAnimatedImage::kFinished) {
return SkAnimatedImage::kFinished;
}
if (mFormat == SkEncodedImageFormat::kGIF) {
// Match Chrome & Firefox behavior that gifs with a duration <= 10ms is bumped to 100ms
return durationMs <= 10 ? 100 : durationMs;
}
return durationMs;
}
int AnimatedImageDrawable::currentFrameDuration() {
return adjustFrameDuration(mSkAnimatedImage->currentFrameDuration());
}
} // namespace android

View File

@@ -16,16 +16,16 @@
#pragma once
#include <cutils/compiler.h>
#include <utils/Macros.h>
#include <utils/RefBase.h>
#include <utils/Timers.h>
#include <SkAnimatedImage.h>
#include <SkCanvas.h>
#include <SkColorFilter.h>
#include <SkDrawable.h>
#include <SkEncodedImageFormat.h>
#include <SkPicture.h>
#include <cutils/compiler.h>
#include <utils/Macros.h>
#include <utils/RefBase.h>
#include <utils/Timers.h>
#include <future>
#include <mutex>
@@ -48,7 +48,8 @@ class AnimatedImageDrawable : public SkDrawable {
public:
// bytesUsed includes the approximate sizes of the SkAnimatedImage and the SkPictures in the
// Snapshots.
AnimatedImageDrawable(sk_sp<SkAnimatedImage> animatedImage, size_t bytesUsed);
AnimatedImageDrawable(sk_sp<SkAnimatedImage> animatedImage, size_t bytesUsed,
SkEncodedImageFormat format);
/**
* This updates the internal time and returns true if the image needs
@@ -115,6 +116,7 @@ protected:
private:
sk_sp<SkAnimatedImage> mSkAnimatedImage;
const size_t mBytesUsed;
const SkEncodedImageFormat mFormat;
bool mRunning = false;
bool mStarting = false;
@@ -157,6 +159,9 @@ private:
Properties mProperties;
std::unique_ptr<OnAnimationEndListener> mEndListener;
int adjustFrameDuration(int);
int currentFrameDuration();
};
} // namespace android

View File

@@ -97,7 +97,7 @@ static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/,
bytesUsed += picture->approximateBytesUsed();
}
SkEncodedImageFormat format = imageDecoder->mCodec->getEncodedFormat();
sk_sp<SkAnimatedImage> animatedImg = SkAnimatedImage::Make(std::move(imageDecoder->mCodec),
info, subset,
std::move(picture));
@@ -108,8 +108,8 @@ static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/,
bytesUsed += sizeof(animatedImg.get());
sk_sp<AnimatedImageDrawable> drawable(new AnimatedImageDrawable(std::move(animatedImg),
bytesUsed));
sk_sp<AnimatedImageDrawable> drawable(
new AnimatedImageDrawable(std::move(animatedImg), bytesUsed, format));
return reinterpret_cast<jlong>(drawable.release());
}