Bug 1120279 - Always check if the next frame is available before advancing an animation. r=edwin, a=gchang
authorAndrew Osmond <aosmond@mozilla.com>
Wed, 21 Sep 2016 12:55:26 -0400
changeset 356015 f568370288565ecf264f26a50debf926de5209fe
parent 356014 a5c745d9064e4b8d9cbc504442773d78801de316
child 356016 bc7ada3c7f1ba563665ce9d218a5b2a837a8f671
push id6570
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:26:13 +0000
treeherdermozilla-beta@f455459b2ae5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersedwin, gchang
bugs1120279
milestone51.0a2
Bug 1120279 - Always check if the next frame is available before advancing an animation. r=edwin, a=gchang
image/FrameAnimator.cpp
--- a/image/FrameAnimator.cpp
+++ b/image/FrameAnimator.cpp
@@ -195,23 +195,21 @@ FrameAnimator::AdvanceFrame(AnimationSta
   // There can be frames in the surface cache with index >= KnownFrameCount()
   // which GetRawFrame() can access because an async decoder has decoded them,
   // but which AnimationState doesn't know about yet because we haven't received
   // the appropriate notification on the main thread. Make sure we stay in sync
   // with AnimationState.
   MOZ_ASSERT(nextFrameIndex < aState.KnownFrameCount());
   RawAccessFrameRef nextFrame = GetRawFrame(nextFrameIndex);
 
-  // If we're done decoding, we know we've got everything we're going to get.
-  // If we aren't, we only display fully-downloaded frames; everything else
-  // gets delayed.
-  bool canDisplay = aState.mDoneDecoding ||
-                    (nextFrame && nextFrame->IsFinished());
-
-  if (!canDisplay) {
+  // We should always check to see if we have the next frame even if we have
+  // previously finished decoding. If we needed to redecode (e.g. due to a draw
+  // 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
     return ret;
   }
 
   if (GetTimeoutForFrame(nextFrameIndex) == FrameTimeout::Forever()) {
     ret.mAnimationFinished = true;
   }