Bug 1120279 - Always check if the next frame is available before advancing an animation.
authorAndrew Osmond <aosmond@mozilla.com>
Wed, 21 Sep 2016 12:55:26 -0400
changeset 314742 6a41bd18fe6c1417cb7683bd6dbdf474b15b97b0
parent 314741 52fc6a1fb0a7564e8d9f8bfbb1111e763a18476f
child 314743 5a71ed072a2b148c9dc657a6a2a5e1bbdb5fb39f
push id81962
push useraosmond@gmail.com
push dateWed, 21 Sep 2016 16:55:53 +0000
treeherdermozilla-inbound@6a41bd18fe6c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1120279
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1120279 - Always check if the next frame is available before advancing an animation.
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;
   }