diff options
author | Martok <martok@martoks-place.de> | 2022-12-31 22:55:46 +0100 |
---|---|---|
committer | Martok <martok@martoks-place.de> | 2023-01-04 00:49:04 +0100 |
commit | b618b3fb767e61f73732a0385f733357571314b0 (patch) | |
tree | c7e53031c59f85d10ee167dc999696edc46eaa79 /image/FrameAnimator.cpp | |
parent | e7fd4ba61bec3736df2f50eb0e7b215a805dde06 (diff) | |
download | uxp-b618b3fb767e61f73732a0385f733357571314b0.tar.gz |
Issue #2073 - m-c 523950: Discard decoded frames of very large GIF animations (squashed)
Controlled by image.animated.decode-on-demand.threshold-kb, default 256MB
Includes squashed bugfixes/regressions:
- m-c 1444537: Shutting down the decode pool should make animated decoders bail early
- m-c 1628606: Make sure to mark the surface cache entry available before sending the frame complete notification
- m-c 1502275: Skip recreating the decoder after redecode errors if an animated image is reset
- m-c 1443232: Don't insert frames into our AnimationFrameBuffer that we consider in error and unusable
Diffstat (limited to 'image/FrameAnimator.cpp')
-rw-r--r-- | image/FrameAnimator.cpp | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/image/FrameAnimator.cpp b/image/FrameAnimator.cpp index 066da94f40..b9a4aec4a8 100644 --- a/image/FrameAnimator.cpp +++ b/image/FrameAnimator.cpp @@ -64,12 +64,7 @@ AnimationState::UpdateStateInternal(LookupResult& aResult, if (mHasBeenDecoded) { Maybe<uint32_t> frameCount = FrameCount(); MOZ_ASSERT(frameCount.isSome()); - aResult.Surface().Seek(*frameCount - 1); - if (aResult.Surface() && aResult.Surface()->IsFinished()) { - mIsCurrentlyDecoded = true; - } else { - mIsCurrentlyDecoded = false; - } + mIsCurrentlyDecoded = aResult.Surface().IsFullyDecoded(); } } @@ -286,8 +281,12 @@ FrameAnimator::AdvanceFrame(AnimationState& aState, // failure) we would have discarded all the old frames and may not yet have // the new ones. if (!nextFrame || !nextFrame->IsFinished()) { - // Uh oh, the frame we want to show is currently being decoded (partial) - // Wait until the next refresh driver tick and try again + // Uh oh, the frame we want to show is currently being decoded (partial). + // Similar to the above case, we could be blocked by network or decoding, + // and so we should advance our current time rather than risk jumping + // through the animation. We will wait until the next refresh driver tick + // and try again. + aState.mCurrentAnimationFrameTime = aTime; return ret; } @@ -313,6 +312,7 @@ FrameAnimator::AdvanceFrame(AnimationState& aState, MOZ_ASSERT(currentFrameEndTime.isSome()); aState.mCurrentAnimationFrameTime = *currentFrameEndTime; aState.mCurrentAnimationFrameIndex = nextFrameIndex; + aFrames.Advance(nextFrameIndex); return ret; } @@ -343,6 +343,7 @@ FrameAnimator::AdvanceFrame(AnimationState& aState, // Set currentAnimationFrameIndex at the last possible moment aState.mCurrentAnimationFrameIndex = nextFrameIndex; + aFrames.Advance(nextFrameIndex); // If we're here, we successfully advanced the frame. ret.mFrameAdvanced = true; @@ -350,6 +351,25 @@ FrameAnimator::AdvanceFrame(AnimationState& aState, return ret; } +void +FrameAnimator::ResetAnimation(AnimationState& aState) +{ + aState.ResetAnimation(); + + // Our surface provider is synchronized to our state, so we need to reset its + // state as well, if we still have one. + LookupResult result = + SurfaceCache::Lookup(ImageKey(mImage), + RasterSurfaceKey(mSize, + DefaultSurfaceFlags(), + PlaybackType::eAnimated)); + if (!result) { + return; + } + + result.Surface().Reset(); +} + RefreshResult FrameAnimator::RequestRefresh(AnimationState& aState, const TimeStamp& aTime, |