Bug 1502275 - Skip recreating the decoder after redecode errors if an animated image is reset. r=tnikkel

Redecode errors break the state machine of FrameAnimator, since the
decoder and the animation state are now out of sync. Going forward this
tight coupling should be eliminated, as the decoder will produce full
frames and the animator can just take the current frame without worrying
about its relative position. For the moment, we should just not reset an
animation if it hit a redecode error (likely due to OOM) just like how
we already stop advancing the animation before the reset.

Differential Revision: https://phabricator.services.mozilla.com/D11046
This commit is contained in:
Andrew Osmond 2018-11-06 10:15:07 -05:00
parent 22dd697280
commit 90300fb153

View File

@ -76,7 +76,7 @@ AnimationSurfaceProvider::Reset()
{
// We want to go back to the beginning.
bool mayDiscard;
bool restartDecoder;
bool restartDecoder = false;
{
MutexAutoLock lock(mFramesMutex);
@ -100,12 +100,23 @@ AnimationSurfaceProvider::Reset()
// this should not take too long to acquire.
MutexAutoLock lock(mDecodingMutex);
// Recreate the decoder so we can regenerate the frames again.
mDecoder = DecoderFactory::CloneAnimationDecoder(mDecoder);
MOZ_ASSERT(mDecoder);
// We may have hit an error while redecoding. Because FrameAnimator is
// tightly coupled to our own state, that means we would need to go through
// some heroics to resume animating in those cases. The typical reason for
// a redecode to fail is out of memory, and recycling should prevent most of
// those errors. When image.animated.generate-full-frames has shipped
// enabled on a release or two, we can simply remove the old FrameAnimator
// blending code and simplify this quite a bit -- just always pop the next
// full frame and timeout off the stack.
if (mDecoder) {
mDecoder = DecoderFactory::CloneAnimationDecoder(mDecoder);
MOZ_ASSERT(mDecoder);
MutexAutoLock lock2(mFramesMutex);
restartDecoder = mFrames->Reset();
MutexAutoLock lock2(mFramesMutex);
restartDecoder = mFrames->Reset();
} else {
MOZ_ASSERT(mFrames->HasRedecodeError());
}
}
if (restartDecoder) {