Merge "Follow Firefox & Chrome GIF behavior" into udc-dev
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user