Bug 1036287 part 2 - Make GetComputedTimingAt take a nullable local time; r=dholbert
authorBrian Birtles <birtles@gmail.com>
Wed, 16 Jul 2014 09:02:32 +0900
changeset 216197 8ac5d63123ae209c527698fca0cadc71613c0f2f
parent 216196 c52984dbf1beeb2880508600162513e1bea7470c
child 216198 4a342071fd1aa777626a3b17b22ed4d06228976b
push id515
push userraliiev@mozilla.com
push dateMon, 06 Oct 2014 12:51:51 +0000
treeherdermozilla-release@267c7a481bef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1036287
milestone33.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 1036287 part 2 - Make GetComputedTimingAt take a nullable local time; r=dholbert As part of supporting arbitrary timelines, we'd like to pass null times to the function that calculates computed timing. Incidentally, this also provides a means for evaluating calculating timing parameters that are independent of the current time (currently only the active duration) without requiring a valid time. This patch updates the signature of ElementAnimation::GetComputedTimingAt to take a nullable time duration. We use the Nullable wrapper to represent null TimeDurations since, unlike, TimeStamp, TimeDuration does not include a null state.
layout/style/AnimationCommon.cpp
layout/style/AnimationCommon.h
--- a/layout/style/AnimationCommon.cpp
+++ b/layout/style/AnimationCommon.cpp
@@ -481,67 +481,74 @@ ElementAnimation::HasAnimationOfProperty
     if (aProperty == mProperties[propIdx].mProperty) {
       return true;
     }
   }
   return false;
 }
 
 ComputedTiming
-ElementAnimation::GetComputedTimingAt(TimeDuration aLocalTime,
+ElementAnimation::GetComputedTimingAt(const Nullable<TimeDuration>& aLocalTime,
                                       const AnimationTiming& aTiming)
 {
   const TimeDuration zeroDuration;
 
   // Currently we expect negative durations to be picked up during CSS
   // parsing but when we start receiving timing parameters from other sources
   // we will need to clamp negative durations here.
-  // For now, if we're hitting this it probably means we've overflowing
+  // For now, if we're hitting this it probably means we're overflowing
   // integer arithmetic in mozilla::TimeStamp.
   MOZ_ASSERT(aTiming.mIterationDuration >= zeroDuration,
              "Expecting iteration duration >= 0");
 
   // Always return the same object to benefit from return-value optimization.
   ComputedTiming result;
 
   result.mActiveDuration = ActiveDuration(aTiming);
 
+  // The default constructor for ComputedTiming sets all other members to
+  // values consistent with an animation that has not been sampled.
+  if (aLocalTime.IsNull()) {
+    return result;
+  }
+  const TimeDuration& localTime = aLocalTime.Value();
+
   // When we finish exactly at the end of an iteration we need to report
   // the end of the final iteration and not the start of the next iteration
   // so we set up a flag for that case.
   bool isEndOfFinalIteration = false;
 
   // Get the normalized time within the active interval.
   TimeDuration activeTime;
-  if (aLocalTime >= aTiming.mDelay + result.mActiveDuration) {
+  if (localTime >= aTiming.mDelay + result.mActiveDuration) {
     result.mPhase = ComputedTiming::AnimationPhase_After;
     if (!aTiming.FillsForwards()) {
       // The animation isn't active or filling at this time.
       result.mTimeFraction = ComputedTiming::kNullTimeFraction;
       return result;
     }
     activeTime = result.mActiveDuration;
     // Note that infinity == floor(infinity) so this will also be true when we
     // have finished an infinitely repeating animation of zero duration.
     isEndOfFinalIteration =
       aTiming.mIterationCount != 0.0 &&
       aTiming.mIterationCount == floor(aTiming.mIterationCount);
-  } else if (aLocalTime < aTiming.mDelay) {
+  } else if (localTime < aTiming.mDelay) {
     result.mPhase = ComputedTiming::AnimationPhase_Before;
     if (!aTiming.FillsBackwards()) {
       // The animation isn't active or filling at this time.
       result.mTimeFraction = ComputedTiming::kNullTimeFraction;
       return result;
     }
     // activeTime is zero
   } else {
     MOZ_ASSERT(result.mActiveDuration != zeroDuration,
                "How can we be in the middle of a zero-duration interval?");
     result.mPhase = ComputedTiming::AnimationPhase_Active;
-    activeTime = aLocalTime - aTiming.mDelay;
+    activeTime = localTime - aTiming.mDelay;
   }
 
   // Get the position within the current iteration.
   TimeDuration iterationTime;
   if (aTiming.mIterationDuration != zeroDuration) {
     iterationTime = isEndOfFinalIteration
                     ? aTiming.mIterationDuration
                     : activeTime % aTiming.mIterationDuration;
--- a/layout/style/AnimationCommon.h
+++ b/layout/style/AnimationCommon.h
@@ -10,16 +10,17 @@
 #include "nsIStyleRule.h"
 #include "nsRefreshDriver.h"
 #include "prclist.h"
 #include "nsCSSProperty.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/StyleAnimationValue.h"
 #include "mozilla/dom/AnimationTimeline.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/dom/Nullable.h"
 #include "nsSMILKeySpline.h"
 #include "nsStyleStruct.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/FloatingPoint.h"
 #include "nsCSSPseudoElements.h"
 #include "nsCycleCollectionParticipant.h"
 
 class nsIFrame;
@@ -374,23 +375,37 @@ public:
   // the animation begins playback. This is zero unless the animation has
   // a negative delay in which case it is the absolute value of the delay.
   // This is used for setting the elapsedTime member of AnimationEvents.
   mozilla::TimeDuration InitialAdvance() const {
     return std::max(TimeDuration(), mTiming.mDelay * -1);
   }
 
   // This function takes as input the timing parameters of an animation and
-  // returns the computed timing at the specified moment.
+  // returns the computed timing at the specified local time.
+  //
+  // The local time may be null in which case only static parameters such as the
+  // active duration are calculated. All other members of the returned object
+  // are given a null/initial value.
   //
   // This function returns ComputedTiming::kNullTimeFraction for the
   // mTimeFraction member of the return value if the animation should not be
   // run (because it is not currently active and is not filling at this time).
-  static ComputedTiming GetComputedTimingAt(TimeDuration aLocalTime,
-                                            const AnimationTiming& aTiming);
+  static ComputedTiming
+  GetComputedTimingAt(const Nullable<mozilla::TimeDuration>& aLocalTime,
+                      const AnimationTiming& aTiming);
+
+  // Convenience wrapper method to save changing all call sites. Removed in
+  // a subsequent patch.
+  static ComputedTiming
+  GetComputedTimingAt(mozilla::TimeDuration aLocalTime,
+                      const AnimationTiming& aTiming) {
+    return GetComputedTimingAt(Nullable<mozilla::TimeDuration>(aLocalTime),
+                               aTiming);
+  }
 
   // Return the duration of the active interval for the given timing parameters.
   static mozilla::TimeDuration ActiveDuration(const AnimationTiming& aTiming);
 
   nsString mName;
   AnimationTiming mTiming;
   // The beginning of the delay period.
   mozilla::TimeStamp mStartTime;