Share code to compute timing functions. (Bug 651801, patch 2) r=bzbarsky
authorL. David Baron <dbaron@dbaron.org>
Thu, 21 Apr 2011 20:17:30 -0700
changeset 68408 8bec19370c0e573a32e844ace1cc12060422adf8
parent 68407 04d855576596fb6b973aa43fe755bfa72fb4c234
child 68409 1cd6b2cce8a84d7abdbb13223da27a87dd3449a0
push id19630
push userdbaron@mozilla.com
push dateFri, 22 Apr 2011 03:18:36 +0000
treeherdermozilla-central@e00435bb54b5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs651801
milestone6.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
Share code to compute timing functions. (Bug 651801, patch 2) r=bzbarsky
layout/style/nsRuleNode.cpp
layout/style/nsStyleStruct.h
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -3704,16 +3704,59 @@ CountTransitionProps(const TransitionPro
     }
     if (data.num > numTransitions)
       numTransitions = data.num;
   }
 
   return numTransitions;
 }
 
+static void
+ComputeTimingFunction(const nsCSSValue& aValue, nsTimingFunction& aResult)
+{
+  switch (aValue.GetUnit()) {
+    case eCSSUnit_Enumerated:
+      aResult = nsTimingFunction(aValue.GetIntValue());
+      break;
+    case eCSSUnit_Cubic_Bezier:
+      {
+        nsCSSValue::Array* array = aValue.GetArrayValue();
+        NS_ASSERTION(array && array->Count() == 4,
+                     "Need 4 control points");
+        aResult = nsTimingFunction(array->Item(0).GetFloatValue(),
+                                   array->Item(1).GetFloatValue(),
+                                   array->Item(2).GetFloatValue(),
+                                   array->Item(3).GetFloatValue());
+      }
+      break;
+    case eCSSUnit_Steps:
+      {
+        nsCSSValue::Array* array = aValue.GetArrayValue();
+        NS_ASSERTION(array && array->Count() == 2,
+                     "Need 2 items");
+        NS_ASSERTION(array->Item(0).GetUnit() == eCSSUnit_Integer,
+                     "unexpected first value");
+        NS_ASSERTION(array->Item(1).GetUnit() == eCSSUnit_Enumerated &&
+                     (array->Item(1).GetIntValue() ==
+                       NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START ||
+                      array->Item(1).GetIntValue() ==
+                       NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END),
+                     "unexpected second value");
+        nsTimingFunction::Type type =
+          (array->Item(1).GetIntValue() ==
+            NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END)
+            ? nsTimingFunction::StepEnd : nsTimingFunction::StepStart;
+        aResult = nsTimingFunction(type, array->Item(0).GetIntValue());
+      }
+      break;
+    default:
+      NS_NOTREACHED("Invalid transition property unit");
+  }
+}
+
 const void*
 nsRuleNode::ComputeDisplayData(void* aStartStruct,
                                const nsRuleData* aRuleData,
                                nsStyleContext* aContext,
                                nsRuleNode* aHighestNode,
                                const RuleDetail aRuleDetail,
                                const PRBool aCanStoreInRuleTree)
 {
@@ -3851,59 +3894,18 @@ nsRuleNode::ComputeDisplayData(void* aSt
       NS_ABORT_IF_FALSE(!canStoreInRuleTree,
                         "should have made canStoreInRuleTree false above");
       transition->SetTimingFunction(
         parentDisplay->mTransitions[i].GetTimingFunction());
     } else if (timingFunction.unit == eCSSUnit_Initial) {
       transition->SetTimingFunction(
         nsTimingFunction(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE));
     } else if (timingFunction.list) {
-      switch (timingFunction.list->mValue.GetUnit()) {
-        case eCSSUnit_Enumerated:
-          transition->SetTimingFunction(
-            nsTimingFunction(timingFunction.list->mValue.GetIntValue()));
-          break;
-        case eCSSUnit_Cubic_Bezier:
-          {
-            nsCSSValue::Array* array =
-              timingFunction.list->mValue.GetArrayValue();
-            NS_ASSERTION(array && array->Count() == 4,
-                         "Need 4 control points");
-            transition->SetTimingFunction(
-              nsTimingFunction(array->Item(0).GetFloatValue(),
-                               array->Item(1).GetFloatValue(),
-                               array->Item(2).GetFloatValue(),
-                               array->Item(3).GetFloatValue()));
-          }
-          break;
-        case eCSSUnit_Steps:
-          {
-            nsCSSValue::Array* array =
-              timingFunction.list->mValue.GetArrayValue();
-            NS_ASSERTION(array && array->Count() == 2,
-                         "Need 2 items");
-            NS_ASSERTION(array->Item(0).GetUnit() == eCSSUnit_Integer,
-                         "unexpected first value");
-            NS_ASSERTION(array->Item(1).GetUnit() == eCSSUnit_Enumerated &&
-                         (array->Item(1).GetIntValue() ==
-                           NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START ||
-                          array->Item(1).GetIntValue() ==
-                           NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END),
-                         "unexpected second value");
-            transition->SetTimingFunction(
-              nsTimingFunction((
-                array->Item(1).GetIntValue() ==
-                  NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END)
-                  ? nsTimingFunction::StepEnd : nsTimingFunction::StepStart,
-                array->Item(0).GetIntValue()));
-          }
-          break;
-        default:
-          NS_NOTREACHED("Invalid transition property unit");
-      }
+      ComputeTimingFunction(timingFunction.list->mValue,
+                            transition->TimingFunctionSlot());
     }
 
     FOR_ALL_TRANSITION_PROPS(p) {
       const TransitionPropInfo& info = transitionPropInfo[p];
       TransitionPropData& d = transitionPropData[p];
 
       // if we're at the end of the list, start at the beginning and repeat
       // until we're out of transitions to populate
@@ -4052,59 +4054,18 @@ nsRuleNode::ComputeDisplayData(void* aSt
       NS_ABORT_IF_FALSE(!canStoreInRuleTree,
                         "should have made canStoreInRuleTree false above");
       animation->SetTimingFunction(
         parentDisplay->mAnimations[i].GetTimingFunction());
     } else if (animTimingFunction.unit == eCSSUnit_Initial) {
       animation->SetTimingFunction(
         nsTimingFunction(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE));
     } else if (animTimingFunction.list) {
-      switch (animTimingFunction.list->mValue.GetUnit()) {
-        case eCSSUnit_Enumerated:
-          animation->SetTimingFunction(
-            nsTimingFunction(animTimingFunction.list->mValue.GetIntValue()));
-          break;
-        case eCSSUnit_Cubic_Bezier:
-          {
-            nsCSSValue::Array* array =
-              animTimingFunction.list->mValue.GetArrayValue();
-            NS_ASSERTION(array && array->Count() == 4,
-                         "Need 4 control points");
-            animation->SetTimingFunction(
-              nsTimingFunction(array->Item(0).GetFloatValue(),
-                               array->Item(1).GetFloatValue(),
-                               array->Item(2).GetFloatValue(),
-                               array->Item(3).GetFloatValue()));
-          }
-          break;
-        case eCSSUnit_Steps:
-          {
-            nsCSSValue::Array* array =
-              animTimingFunction.list->mValue.GetArrayValue();
-            NS_ASSERTION(array && array->Count() == 2,
-                         "Need 2 items");
-            NS_ASSERTION(array->Item(0).GetUnit() == eCSSUnit_Integer,
-                         "unexpected first value");
-            NS_ASSERTION(array->Item(1).GetUnit() == eCSSUnit_Enumerated &&
-                         (array->Item(1).GetIntValue() ==
-                           NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START ||
-                          array->Item(1).GetIntValue() ==
-                           NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END),
-                         "unexpected second value");
-            animation->SetTimingFunction(
-              nsTimingFunction((
-                array->Item(1).GetIntValue() ==
-                  NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END)
-                  ? nsTimingFunction::StepEnd : nsTimingFunction::StepStart,
-                array->Item(0).GetIntValue()));
-          }
-          break;
-        default:
-          NS_NOTREACHED("Invalid animation property unit");
-      }
+      ComputeTimingFunction(animTimingFunction.list->mValue,
+                            animation->TimingFunctionSlot());
     }
 
     if (i >= animDirection.num) {
       animation->SetDirection(display->mAnimations[i % animDirection.num].GetDirection());
     } else if (animDirection.unit == eCSSUnit_Inherit) {
       NS_ABORT_IF_FALSE(i < parentDisplay->mAnimationDirectionCount,
                         "animDirection.num computed incorrectly");
       NS_ABORT_IF_FALSE(!canStoreInRuleTree,
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -1329,39 +1329,51 @@ struct nsTimingFunction {
   nsTimingFunction(Type aType, PRUint32 aSteps)
     : mType(aType)
   {
     NS_ABORT_IF_FALSE(mType == StepStart || mType == StepEnd, "wrong type");
     mSteps = aSteps;
   }
 
   nsTimingFunction(const nsTimingFunction& aOther)
-    : mType(aOther.mType)
   {
-    if (mType == Function) {
-      mFunc.mX1 = aOther.mFunc.mX1;
-      mFunc.mY1 = aOther.mFunc.mY1;
-      mFunc.mX2 = aOther.mFunc.mX2;
-      mFunc.mY2 = aOther.mFunc.mY2;
-    } else {
-      mSteps = aOther.mSteps;
-    }
+    *this = aOther;
   }
 
   Type mType;
   union {
     struct {
       float mX1;
       float mY1;
       float mX2;
       float mY2;
     } mFunc;
     PRUint32 mSteps;
   };
 
+  nsTimingFunction&
+  operator=(const nsTimingFunction& aOther)
+  {
+    if (&aOther == this)
+      return *this;
+
+    mType = aOther.mType;
+
+    if (mType == Function) {
+      mFunc.mX1 = aOther.mFunc.mX1;
+      mFunc.mY1 = aOther.mFunc.mY1;
+      mFunc.mX2 = aOther.mFunc.mX2;
+      mFunc.mY2 = aOther.mFunc.mY2;
+    } else {
+      mSteps = aOther.mSteps;
+    }
+
+    return *this;
+  }
+
   bool operator==(const nsTimingFunction& aOther) const
   {
     if (mType != aOther.mType) {
       return false;
     }
     if (mType == Function) {
       return mFunc.mX1 == aOther.mFunc.mX1 && mFunc.mY1 == aOther.mFunc.mY1 &&
              mFunc.mX2 == aOther.mFunc.mX2 && mFunc.mY2 == aOther.mFunc.mY2;
@@ -1403,16 +1415,18 @@ struct nsTransition {
     }
   void SetUnknownProperty(const nsAString& aUnknownProperty);
   void CopyPropertyFrom(const nsTransition& aOther)
     {
       mProperty = aOther.mProperty;
       mUnknownProperty = aOther.mUnknownProperty;
     }
 
+  nsTimingFunction& TimingFunctionSlot() { return mTimingFunction; }
+
 private:
   nsTimingFunction mTimingFunction;
   float mDuration;
   float mDelay;
   nsCSSProperty mProperty;
   nsCOMPtr<nsIAtom> mUnknownProperty; // used when mProperty is
                                       // eCSSProperty_UNKNOWN
 };
@@ -1441,16 +1455,18 @@ struct nsAnimation {
   void SetDuration(float aDuration) { mDuration = aDuration; }
   void SetName(const nsSubstring& aName) { mName = aName; }
   void SetDirection(PRUint8 aDirection) { mDirection = aDirection; }
   void SetFillMode(PRUint8 aFillMode) { mFillMode = aFillMode; }
   void SetPlayState(PRUint8 aPlayState) { mPlayState = aPlayState; }
   void SetIterationCount(float aIterationCount)
     { mIterationCount = aIterationCount; }
 
+  nsTimingFunction& TimingFunctionSlot() { return mTimingFunction; }
+
 private:
   nsTimingFunction mTimingFunction;
   float mDuration;
   float mDelay;
   nsString mName; // empty string for 'none'
   PRUint8 mDirection;
   PRUint8 mFillMode;
   PRUint8 mPlayState;