Bug 1288040 (Part 2) - Don't reset the last composited frame index when we reset animation. r=edwin
authorSeth Fowler <mark.seth.fowler@gmail.com>
Tue, 19 Jul 2016 13:31:44 -0700
changeset 305956 34faad78d6f099f4d1a25a1c7935db5656fdf627
parent 305955 8383c2cc99393e21a7b7f2f8129e94b0f9a77593
child 305957 1f2c834df0db955921199939b3977829f976ad1f
push id30474
push usercbook@mozilla.com
push dateThu, 21 Jul 2016 14:25:10 +0000
treeherdermozilla-central@6b180266ac16 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersedwin
bugs1288040
milestone50.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 1288040 (Part 2) - Don't reset the last composited frame index when we reset animation. r=edwin
image/FrameAnimator.cpp
image/FrameAnimator.h
image/RasterImage.cpp
--- a/image/FrameAnimator.cpp
+++ b/image/FrameAnimator.cpp
@@ -29,17 +29,16 @@ AnimationState::SetDoneDecoding(bool aDo
 {
   mDoneDecoding = aDone;
 }
 
 void
 AnimationState::ResetAnimation()
 {
   mCurrentAnimationFrameIndex = 0;
-  mLastCompositedFrameIndex = -1;
 }
 
 void
 AnimationState::SetAnimationMode(uint16_t aAnimationMode)
 {
   mAnimationMode = aAnimationMode;
 }
 
@@ -218,17 +217,17 @@ FrameAnimator::AdvanceFrame(AnimationSta
   }
 
   if (nextFrameIndex == 0) {
     ret.dirtyRect = aState.mFirstFrameRefreshArea;
   } else {
     MOZ_ASSERT(nextFrameIndex == currentFrameIndex + 1);
 
     // Change frame
-    if (!DoBlend(aState, &ret.dirtyRect, currentFrameIndex, nextFrameIndex)) {
+    if (!DoBlend(&ret.dirtyRect, currentFrameIndex, nextFrameIndex)) {
       // something went wrong, move on to next
       NS_WARNING("FrameAnimator::AdvanceFrame(): Compositing of frame failed");
       nextFrame->SetCompositingFailed(true);
       aState.mCurrentAnimationFrameTime = GetCurrentImgFrameEndTime(aState);
       aState.mCurrentAnimationFrameIndex = nextFrameIndex;
 
       ret.error = true;
       return ret;
@@ -294,22 +293,22 @@ FrameAnimator::RequestRefresh(AnimationS
       break;
     }
   }
 
   return ret;
 }
 
 LookupResult
-FrameAnimator::GetCompositedFrame(AnimationState& aState, uint32_t aFrameNum)
+FrameAnimator::GetCompositedFrame(uint32_t aFrameNum)
 {
   MOZ_ASSERT(aFrameNum != 0, "First frame is never composited");
 
   // If we have a composited version of this frame, return that.
-  if (aState.mLastCompositedFrameIndex == int32_t(aFrameNum)) {
+  if (mLastCompositedFrameIndex == int32_t(aFrameNum)) {
     return LookupResult(mCompositingFrame->DrawableRef(), MatchType::EXACT);
   }
 
   // Otherwise return the raw frame. DoBlend is required to ensure that we only
   // hit this case if the frame is not paletted and doesn't require compositing.
   LookupResult result =
     SurfaceCache::Lookup(ImageKey(mImage),
                          RasterSurfaceKey(mSize,
@@ -411,18 +410,17 @@ FrameAnimator::GetRawFrame(uint32_t aFra
   return result ? result.DrawableRef()->RawAccessRef()
                 : RawAccessFrameRef();
 }
 
 //******************************************************************************
 // DoBlend gets called when the timer for animation get fired and we have to
 // update the composited frame of the animation.
 bool
-FrameAnimator::DoBlend(AnimationState& aState,
-                       nsIntRect* aDirtyRect,
+FrameAnimator::DoBlend(nsIntRect* aDirtyRect,
                        uint32_t aPrevFrameIndex,
                        uint32_t aNextFrameIndex)
 {
   RawAccessFrameRef prevFrame = GetRawFrame(aPrevFrameIndex);
   RawAccessFrameRef nextFrame = GetRawFrame(aNextFrameIndex);
 
   MOZ_ASSERT(prevFrame && nextFrame, "Should have frames here");
 
@@ -499,34 +497,34 @@ FrameAnimator::DoBlend(AnimationState& a
   }
 
   // Optimization:
   //   Skip compositing if the last composited frame is this frame
   //   (Only one composited frame was made for this animation.  Example:
   //    Only Frame 3 of a 10 frame image required us to build a composite frame
   //    On the second loop, we do not need to rebuild the frame
   //    since it's still sitting in compositingFrame)
-  if (aState.mLastCompositedFrameIndex == int32_t(aNextFrameIndex)) {
+  if (mLastCompositedFrameIndex == int32_t(aNextFrameIndex)) {
     return true;
   }
 
   bool needToBlankComposite = false;
 
   // Create the Compositing Frame
   if (!mCompositingFrame) {
     RefPtr<imgFrame> newFrame = new imgFrame;
     nsresult rv = newFrame->InitForDecoder(mSize,
                                            SurfaceFormat::B8G8R8A8);
     if (NS_FAILED(rv)) {
       mCompositingFrame.reset();
       return false;
     }
     mCompositingFrame = newFrame->RawAccessRef();
     needToBlankComposite = true;
-  } else if (int32_t(aNextFrameIndex) != aState.mLastCompositedFrameIndex+1) {
+  } else if (int32_t(aNextFrameIndex) != mLastCompositedFrameIndex+1) {
 
     // If we are not drawing on top of last composited frame,
     // then we are building a new composite frame, so let's clear it first.
     needToBlankComposite = true;
   }
 
   AnimationData compositingFrameData = mCompositingFrame->GetAnimationData();
 
@@ -610,17 +608,17 @@ FrameAnimator::DoBlend(AnimationState& a
       case DisposalMethod::KEEP:
         // Copy previous frame into compositingFrame before we put the new
         // frame on top
         // Assumes that the previous frame represents a full frame (it could be
         // smaller in size than the container, as long as the frame before it
         // erased itself)
         // Note: Frame 1 never gets into DoBlend(), so (aNextFrameIndex - 1)
         // will always be a valid frame number.
-        if (aState.mLastCompositedFrameIndex != int32_t(aNextFrameIndex - 1)) {
+        if (mLastCompositedFrameIndex != int32_t(aNextFrameIndex - 1)) {
           if (isFullPrevFrame && !prevFrame->GetIsPaletted()) {
             // Just copy the bits
             CopyFrameImage(prevFrameData.mRawData,
                            prevFrameData.mRect,
                            compositingFrameData.mRawData,
                            compositingFrameData.mRect);
           } else {
             if (needToBlankComposite) {
@@ -685,17 +683,17 @@ FrameAnimator::DoBlend(AnimationState& a
               compositingFrameData.mRawData,
               compositingFrameData.mRect,
               nextFrameData.mBlendMethod,
               nextFrameData.mBlendRect);
 
   // Tell the image that it is fully 'downloaded'.
   mCompositingFrame->Finish();
 
-  aState.mLastCompositedFrameIndex = int32_t(aNextFrameIndex);
+  mLastCompositedFrameIndex = int32_t(aNextFrameIndex);
 
   return true;
 }
 
 //******************************************************************************
 // Fill aFrame with black. Does also clears the mask.
 void
 FrameAnimator::ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect)
--- a/image/FrameAnimator.h
+++ b/image/FrameAnimator.h
@@ -22,17 +22,16 @@ namespace image {
 
 class RasterImage;
 
 class AnimationState
 {
 public:
   explicit AnimationState(uint16_t aAnimationMode)
     : mCurrentAnimationFrameIndex(0)
-    , mLastCompositedFrameIndex(-1)
     , mLoopRemainingCount(-1)
     , mLoopCount(-1)
     , mFirstFrameTimeout(0)
     , mAnimationMode(aAnimationMode)
     , mDoneDecoding(false)
   { }
 
   /**
@@ -101,19 +100,16 @@ private:
   nsIntRect mFirstFrameRefreshArea;
 
   //! the time that the animation advanced to the current frame
   TimeStamp mCurrentAnimationFrameTime;
 
   //! The current frame index we're on. 0 to (numFrames - 1).
   uint32_t mCurrentAnimationFrameIndex;
 
-  //! Track the last composited frame for Optimizations (See DoComposite code)
-  int32_t mLastCompositedFrameIndex;
-
   //! number of loops remaining before animation stops (-1 no stop)
   int32_t mLoopRemainingCount;
 
   //! The total number of loops for the image.
   int32_t mLoopCount;
 
   //! The timeout for the first frame of this image.
   int32_t mFirstFrameTimeout;
@@ -126,16 +122,17 @@ private:
 };
 
 class FrameAnimator
 {
 public:
   FrameAnimator(RasterImage* aImage, gfx::IntSize aSize)
     : mImage(aImage)
     , mSize(aSize)
+    , mLastCompositedFrameIndex(-1)
   {
      MOZ_COUNT_CTOR(FrameAnimator);
   }
 
   ~FrameAnimator()
   {
     MOZ_COUNT_DTOR(FrameAnimator);
   }
@@ -183,17 +180,17 @@ public:
    */
   RefreshResult RequestRefresh(AnimationState& aState, const TimeStamp& aTime);
 
   /**
    * If we have a composited frame for @aFrameNum, returns it. Otherwise,
    * returns an empty LookupResult. It is an error to call this method with
    * aFrameNum == 0, because the first frame is never composited.
    */
-  LookupResult GetCompositedFrame(AnimationState& aState, uint32_t aFrameNum);
+  LookupResult GetCompositedFrame(uint32_t aFrameNum);
 
   /*
    * Returns the frame's adjusted timeout. If the animation loops and the
    * timeout falls in between a certain range then the timeout is adjusted so
    * that it's never 0. If the animation does not loop then no adjustments are
    * made.
    */
   int32_t GetTimeoutForFrame(AnimationState& aState, uint32_t aFrameNum) const;
@@ -237,18 +234,17 @@ private: // methods
 
   /**
    * Get the time the frame we're currently displaying is supposed to end.
    *
    * In the error case, returns an "infinity" timestamp.
    */
   TimeStamp GetCurrentImgFrameEndTime(AnimationState& aState) const;
 
-  bool DoBlend(AnimationState& aState,
-               nsIntRect* aDirtyRect,
+  bool DoBlend(nsIntRect* aDirtyRect,
                uint32_t aPrevFrameIndex,
                uint32_t aNextFrameIndex);
 
   /** Clears an area of <aFrame> with transparent black.
    *
    * @param aFrameData Target Frame data
    * @param aFrameRect The rectangle of the data pointed ot by aFrameData
    *
@@ -306,14 +302,17 @@ private: // data
 
   /** the previous composited frame, for DISPOSE_RESTORE_PREVIOUS
    *
    * The Previous Frame (all frames composited up to the current) needs to be
    * stored in cases where the image specifies it wants the last frame back
    * when it's done with the current frame.
    */
   RawAccessFrameRef mCompositingPrevFrame;
+
+  //! Track the last composited frame for Optimizations (See DoComposite code)
+  int32_t mLastCompositedFrameIndex;
 };
 
 } // namespace image
 } // namespace mozilla
 
 #endif // mozilla_image_FrameAnimator_h
--- a/image/RasterImage.cpp
+++ b/image/RasterImage.cpp
@@ -280,17 +280,17 @@ RasterImage::LookupFrameInternal(uint32_
                  "Don't ask for a frame > 0 if we're not animated!");
     aFrameNum = 0;
   }
 
   if (mAnimationState && aFrameNum > 0) {
     MOZ_ASSERT(mFrameAnimator);
     MOZ_ASSERT(ToSurfaceFlags(aFlags) == DefaultSurfaceFlags(),
                "Can't composite frames with non-default surface flags");
-    return mFrameAnimator->GetCompositedFrame(*mAnimationState, aFrameNum);
+    return mFrameAnimator->GetCompositedFrame(aFrameNum);
   }
 
   SurfaceFlags surfaceFlags = ToSurfaceFlags(aFlags);
 
   // We don't want any substitution for sync decodes, and substitution would be
   // illegal when high quality downscaling is disabled, so we use
   // SurfaceCache::Lookup in this case.
   if ((aFlags & FLAG_SYNC_DECODE) || !(aFlags & FLAG_HIGH_QUALITY_SCALING)) {