Bug 1374882 - Precompute active duration and end time. r?birtles draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Thu, 22 Jun 2017 12:12:43 +0900
changeset 598708 fce2b43641c426231431f3a7f4ea2c37eb9c2610
parent 598707 a0a63ce1a4e63d452bb503436444eede97a9c2ab
child 598709 bc7e44757321912cae533192527bd01d488440a7
push id65289
push userhikezoe@mozilla.com
push dateThu, 22 Jun 2017 03:12:57 +0000
reviewersbirtles
bugs1374882
milestone56.0a1
Bug 1374882 - Precompute active duration and end time. r?birtles MozReview-Commit-ID: ClFHaXkpGXX
dom/animation/TimingParams.cpp
dom/animation/TimingParams.h
--- a/dom/animation/TimingParams.cpp
+++ b/dom/animation/TimingParams.cpp
@@ -82,16 +82,18 @@ TimingParams::FromOptionsType(const Opti
     result.mDelay = TimeDuration::FromMilliseconds(timing.mDelay);
     result.mEndDelay = TimeDuration::FromMilliseconds(timing.mEndDelay);
     result.mIterations = timing.mIterations;
     result.mIterationStart = timing.mIterationStart;
     result.mDirection = timing.mDirection;
     result.mFill = timing.mFill;
     result.mFunction = easing;
   }
+  result.Update();
+
   return result;
 }
 
 /* static */ TimingParams
 TimingParams::FromOptionsUnion(
   const dom::UnrestrictedDoubleOrKeyframeEffectOptions& aOptions,
   nsIDocument* aDocument,
   ErrorResult& aRv)
@@ -184,16 +186,18 @@ TimingParams::ParseEasing(const nsAStrin
 
   aRv.ThrowTypeError<dom::MSG_INVALID_EASING_ERROR>(aEasing);
   return Nothing();
 }
 
 bool
 TimingParams::operator==(const TimingParams& aOther) const
 {
+  // We don't compare mActiveDuration and mEndTime because they are calculated
+  // from other timing parameters.
   return mDuration == aOther.mDuration &&
          mDelay == aOther.mDelay &&
          mIterations == aOther.mIterations &&
          mIterationStart == aOther.mIterationStart &&
          mDirection == aOther.mDirection &&
          mFill == aOther.mFill &&
          mFunction == aOther.mFunction;
 }
--- a/dom/animation/TimingParams.h
+++ b/dom/animation/TimingParams.h
@@ -40,16 +40,17 @@ struct TimingParams
                dom::PlaybackDirection aDirection,
                dom::FillMode aFillMode)
     : mIterations(aIterationCount)
     , mDirection(aDirection)
     , mFill(aFillMode)
   {
     mDuration.emplace(StickyTimeDuration::FromMilliseconds(aDuration));
     mDelay = TimeDuration::FromMilliseconds(aDelay);
+    Update();
   }
 
   TimingParams(const TimeDuration& aDuration,
                const TimeDuration& aDelay,
                const TimeDuration& aEndDelay,
                float aIterations,
                float aIterationStart,
                dom::PlaybackDirection aDirection,
@@ -59,16 +60,17 @@ struct TimingParams
     , mEndDelay(aEndDelay)
     , mIterations(aIterations)
     , mIterationStart(aIterationStart)
     , mDirection(aDirection)
     , mFill(aFillMode)
     , mFunction(aFunction)
   {
     mDuration.emplace(aDuration);
+    Update();
   }
 
   template <class OptionsType>
   static TimingParams FromOptionsType(
     const OptionsType& aOptions,
     nsIDocument* aDocument,
     ErrorResult& aRv);
   static TimingParams FromOptionsUnion(
@@ -118,64 +120,78 @@ struct TimingParams
         NS_LITERAL_STRING("iterations"));
     }
   }
 
   static Maybe<ComputedTimingFunction> ParseEasing(const nsAString& aEasing,
                                                    nsIDocument* aDocument,
                                                    ErrorResult& aRv);
 
-  // Return the duration of the active interval calculated by duration and
-  // iteration count.
-  StickyTimeDuration ActiveDuration() const
+  static StickyTimeDuration CalcActiveDuration(
+    const Maybe<StickyTimeDuration>& aDuration,
+    double aIterations)
   {
     // If either the iteration duration or iteration count is zero,
     // Web Animations says that the active duration is zero. This is to
     // ensure that the result is defined when the other argument is Infinity.
     static const StickyTimeDuration zeroDuration;
-    if (!mDuration || *mDuration == zeroDuration || mIterations == 0.0) {
+    if (!aDuration || *aDuration == zeroDuration || aIterations == 0.0) {
       return zeroDuration;
     }
 
-    return mDuration->MultDouble(mIterations);
+    return aDuration->MultDouble(aIterations);
+  }
+  // Return the duration of the active interval calculated by duration and
+  // iteration count.
+  StickyTimeDuration ActiveDuration() const
+  {
+    MOZ_ASSERT(CalcActiveDuration(mDuration, mIterations) == mActiveDuration,
+               "Cached value of active duration should be up to date");
+    return mActiveDuration;
   }
 
   StickyTimeDuration EndTime() const
   {
-    return std::max(mDelay + ActiveDuration() + mEndDelay,
-                    StickyTimeDuration());
+    MOZ_ASSERT(mEndTime == std::max(mDelay + ActiveDuration() + mEndDelay,
+                                    StickyTimeDuration()),
+               "Cached value of end time should be up to date");
+    return mEndTime;
   }
 
   bool operator==(const TimingParams& aOther) const;
   bool operator!=(const TimingParams& aOther) const
   {
     return !(*this == aOther);
   }
 
   void SetDuration(Maybe<StickyTimeDuration>&& aDuration)
   {
     mDuration = Move(aDuration);
+    Update();
   }
   const Maybe<StickyTimeDuration>& Duration() const { return mDuration; }
 
   void SetDelay(const TimeDuration& aDelay)
   {
     mDelay = aDelay;
+    Update();
   }
   const TimeDuration& Delay() const { return mDelay; }
 
   void SetEndDelay(const TimeDuration& aEndDelay)
   {
     mEndDelay = aEndDelay;
+    Update();
   }
   const TimeDuration& EndDelay() const { return mEndDelay; }
 
   void SetIterations(double aIterations)
   {
     mIterations = aIterations;
+    Update();
   }
   double Iterations() const { return mIterations; }
 
   void SetIterationStart(double aIterationStart)
   {
     mIterationStart = aIterationStart;
   }
   double IterationStart() const { return mIterationStart; }
@@ -194,22 +210,32 @@ struct TimingParams
 
   void SetFunction(Maybe<ComputedTimingFunction>&& aFunction)
   {
     mFunction = Move(aFunction);
   }
   const Maybe<ComputedTimingFunction>& Function() const { return mFunction; }
 
 private:
+  void Update()
+  {
+    mActiveDuration = CalcActiveDuration(mDuration, mIterations);
+
+    mEndTime = std::max(mDelay + mActiveDuration + mEndDelay,
+                        StickyTimeDuration());
+  }
+
   // mDuration.isNothing() represents the "auto" value
   Maybe<StickyTimeDuration> mDuration;
   TimeDuration mDelay;      // Initializes to zero
   TimeDuration mEndDelay;
   double mIterations = 1.0; // Can be NaN, negative, +/-Infinity
   double mIterationStart = 0.0;
   dom::PlaybackDirection mDirection = dom::PlaybackDirection::Normal;
   dom::FillMode mFill = dom::FillMode::Auto;
   Maybe<ComputedTimingFunction> mFunction;
+  StickyTimeDuration mActiveDuration = StickyTimeDuration();
+  StickyTimeDuration mEndTime = StickyTimeDuration();
 };
 
 } // namespace mozilla
 
 #endif // mozilla_TimingParams_h