Bug 523950 - Part 5. Pass the currently displayed frame of an animation to its decoder. r=tnikkel

When we need to recreate an animated image decoder because it was
discarded, the animation may have progressed beyond the first frame.
Given that later in the patch series we need FrameAnimator to be driving
the decoding more actively, it simplifies its role by making it assume
the initial state of the decoder matches its initial state. Passing in
the currently displayed frame allows the decoder to advance its frame
buffer (and potentially discard unnecessary frames), such that when the
animation actually wants to advance as it normally would, the decoder
state matches what it would have been if it had never been discarded.
This commit is contained in:
Andrew Osmond 2018-02-28 13:34:52 -05:00
parent 646219b1e7
commit 54898d5d6c
4 changed files with 8 additions and 3 deletions

View File

@ -17,7 +17,8 @@ namespace image {
AnimationSurfaceProvider::AnimationSurfaceProvider(NotNull<RasterImage*> aImage,
const SurfaceKey& aSurfaceKey,
NotNull<Decoder*> aDecoder)
NotNull<Decoder*> aDecoder,
size_t aCurrentFrame)
: ISurfaceProvider(ImageKey(aImage.get()), aSurfaceKey,
AvailabilityState::StartAsPlaceholder())
, mImage(aImage.get())

View File

@ -31,7 +31,8 @@ public:
AnimationSurfaceProvider(NotNull<RasterImage*> aImage,
const SurfaceKey& aSurfaceKey,
NotNull<Decoder*> aDecoder);
NotNull<Decoder*> aDecoder,
size_t aCurrentFrame);
//////////////////////////////////////////////////////////////////////////////

View File

@ -175,6 +175,7 @@ DecoderFactory::CreateAnimationDecoder(DecoderType aType,
const IntSize& aIntrinsicSize,
DecoderFlags aDecoderFlags,
SurfaceFlags aSurfaceFlags,
size_t aCurrentFrame,
IDecodingTask** aOutTask)
{
if (aType == DecoderType::UNKNOWN) {
@ -205,7 +206,7 @@ DecoderFactory::CreateAnimationDecoder(DecoderType aType,
SurfaceKey surfaceKey =
RasterSurfaceKey(aIntrinsicSize, aSurfaceFlags, PlaybackType::eAnimated);
auto provider = MakeNotNull<RefPtr<AnimationSurfaceProvider>>(
aImage, surfaceKey, WrapNotNull(decoder));
aImage, surfaceKey, WrapNotNull(decoder), aCurrentFrame);
// Attempt to insert the surface provider into the surface cache right away so
// we won't trigger any more decoders with the same parameters.

View File

@ -1249,9 +1249,11 @@ RasterImage::Decode(const IntSize& aSize,
nsresult rv;
bool animated = mAnimationState && aPlaybackType == PlaybackType::eAnimated;
if (animated) {
size_t currentFrame = mAnimationState->GetCurrentAnimationFrameIndex();
rv = DecoderFactory::CreateAnimationDecoder(mDecoderType, WrapNotNull(this),
mSourceBuffer, mSize,
decoderFlags, surfaceFlags,
currentFrame,
getter_AddRefs(task));
} else {
rv = DecoderFactory::CreateDecoder(mDecoderType, WrapNotNull(this),