summaryrefslogtreecommitdiff
path: root/image/FrameAnimator.cpp
diff options
context:
space:
mode:
authorMartok <martok@martoks-place.de>2022-12-31 22:55:46 +0100
committerMartok <martok@martoks-place.de>2023-01-04 00:49:04 +0100
commitb618b3fb767e61f73732a0385f733357571314b0 (patch)
treec7e53031c59f85d10ee167dc999696edc46eaa79 /image/FrameAnimator.cpp
parente7fd4ba61bec3736df2f50eb0e7b215a805dde06 (diff)
downloaduxp-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.cpp36
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,