Bug 926048. Part 3. Correctly check if we are at the end of an animated image. r=edwin
authorTimothy Nikkel <tnikkel@gmail.com>
Tue, 01 Mar 2016 22:34:40 -0600
changeset 322733 68dd453ec527500a44e25164d4f433526610c8ab
parent 322732 2b3a42aa606a417915f4eac3690b6add47a582b1
child 322734 bddda82562e9007b8f76f887628a4a02d4b225f8
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersedwin
bugs926048
milestone47.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 926048. Part 3. Correctly check if we are at the end of an animated image. r=edwin mImage->GetNumFrames() is the current number of decoded frames (that the RasterImage knows about), so it only represents the last frame of the animation if we are done decoding. If we are not fully decoded, and we are on the last decoded frame, just stay on the last decoded frame. When more frames get decoded (or we determine that we are the last frame of the animation) we will advance. One might expect that if |nextFrameIndex == mImage->GetNumFrames()| then |GetRawFrame(nextFrameIndex)| would return a null surface. But that is not the case because the decoding thread can insert frames into the surface cache that the RasterImage hasn't acknowledged yet (because it has to do so on the main thread, which we are currently running on). This is why moving animated images to the surface cache is likely the cause of this bug. This introduces an issue that is explained in, and fixed by the next patch.
image/FrameAnimator.cpp
--- a/image/FrameAnimator.cpp
+++ b/image/FrameAnimator.cpp
@@ -97,16 +97,23 @@ FrameAnimator::AdvanceFrame(TimeStamp aT
     // 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 we're done decoding the next frame, go ahead and display it now and
   // reinit with the next frame's delay time.
   if (mImage->GetNumFrames() == nextFrameIndex) {
+    // We can only accurately determine if we are at the end of the loop if we are
+    // done decoding, otherwise we don't know how many frames there will be.
+    if (!mDoneDecoding) {
+      // We've already advanced to the last decoded frame, nothing more we can do.
+      return ret;
+    }
+
     // End of an animation loop...
 
     // If we are not looping forever, initialize the loop counter
     if (mLoopRemainingCount < 0 && LoopCount() >= 0) {
       mLoopRemainingCount = LoopCount();
     }
 
     // If animation mode is "loop once", or we're at end of loop counter,