Bug 1272549 - Part 4: Compute distance for none and a valid transform list. r=birtles
authorBoris Chiou <boris.chiou@gmail.com>
Mon, 03 Oct 2016 17:43:20 +0800
changeset 319296 da8910563fadcdc9fea32734afa07491c758fa7a
parent 319295 191bd8c2c0ff56cde7fd285e6121d322005d261d
child 319297 92a5d32ed2da14b0b00826139827f3c605f44b66
push id30869
push userphilringnalda@gmail.com
push dateWed, 26 Oct 2016 04:57:48 +0000
treeherdermozilla-central@9471b3c49b2c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbirtles
bugs1272549
milestone52.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 1272549 - Part 4: Compute distance for none and a valid transform list. r=birtles Reuse AddTransformLists to get the identity transform functions to replace none, and then treat them with another transform list as two matched ones. MozReview-Commit-ID: HwdBPCiUivg
layout/style/StyleAnimationValue.cpp
layout/style/nsStyleTransformMatrix.cpp
layout/style/nsStyleTransformMatrix.h
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -696,16 +696,20 @@ StyleAnimationValue::ComputeColorDistanc
 
   double diffA = startA - endA;
   double diffR = startR - endR;
   double diffG = startG - endG;
   double diffB = startB - endB;
   return sqrt(diffA * diffA + diffR * diffR + diffG * diffG + diffB * diffB);
 }
 
+static nsCSSValueList*
+AddTransformLists(double aCoeff1, const nsCSSValueList* aList1,
+                  double aCoeff2, const nsCSSValueList* aList2);
+
 static double
 ComputeTransformDistance(nsCSSValue::Array* aArray1,
                          nsCSSValue::Array* aArray2)
 {
   MOZ_ASSERT(aArray1, "aArray1 should be non-null.");
   MOZ_ASSERT(aArray2, "aArray2 should be non-null.");
 
   // Normalize translate and scale functions to equivalent "translate3d" and
@@ -1234,23 +1238,21 @@ StyleAnimationValue::ComputeDistance(nsC
       MOZ_ASSERT(list1);
       MOZ_ASSERT(list2);
 
       if (list1->mValue.GetUnit() == eCSSUnit_None &&
           list2->mValue.GetUnit() == eCSSUnit_None) {
         // Both none, nothing happens.
         aDistance = 0.0;
       } else if (list1->mValue.GetUnit() == eCSSUnit_None) {
-        // TODO: Implement none transform list in the later patch.
-        aDistance = 0.0;
-        return false;
+        nsAutoPtr<nsCSSValueList> none(AddTransformLists(0, list2, 0, list2));
+        aDistance = ComputeTransformListDistance(none, list2);
       } else if (list2->mValue.GetUnit() == eCSSUnit_None) {
-        // TODO: Implement none transform list in the later patch.
-        aDistance = 0.0;
-        return false;
+        nsAutoPtr<nsCSSValueList> none(AddTransformLists(0, list1, 0, list1));
+        aDistance = ComputeTransformListDistance(list1, none);
       } else {
         const nsCSSValueList *item1 = list1, *item2 = list2;
         do {
           nsCSSKeyword func1 = nsStyleTransformMatrix::TransformFunctionOf(
             item1->mValue.GetArrayValue());
           nsCSSKeyword func2 = nsStyleTransformMatrix::TransformFunctionOf(
             item2->mValue.GetArrayValue());
           if (!TransformFunctionsMatch(func1, func2)) {
@@ -2492,18 +2494,39 @@ AddTransformLists(double aCoeff1, const 
           AddCSSValueAngle(aCoeff1, a1->Item(4), aCoeff2, a2->Item(4),
                            arr->Item(4));
           break;
         }
         MOZ_FALLTHROUGH;
       }
       case eCSSKeyword_matrix:
       case eCSSKeyword_matrix3d:
-      case eCSSKeyword_interpolatematrix:
-      case eCSSKeyword_perspective: {
+      case eCSSKeyword_perspective:
+        if (aCoeff1 == 0.0 && aCoeff2 == 0.0) {
+          // Special case. If both coefficients are 0.0, we should apply an
+          // identity transform function.
+          arr = StyleAnimationValue::AppendTransformFunction(tfunc, resultTail);
+
+          if (tfunc == eCSSKeyword_rotate3d) {
+            arr->Item(1).SetFloatValue(0.0, eCSSUnit_Number);
+            arr->Item(2).SetFloatValue(0.0, eCSSUnit_Number);
+            arr->Item(3).SetFloatValue(1.0, eCSSUnit_Number);
+            arr->Item(4).SetFloatValue(0.0, eCSSUnit_Radian);
+          } else if (tfunc == eCSSKeyword_perspective) {
+            // The parameter of the identity perspective function is
+            // positive infinite.
+            arr->Item(1).SetFloatValue(std::numeric_limits<float>::infinity(),
+                                       eCSSUnit_Pixel);
+          } else {
+            nsStyleTransformMatrix::SetIdentityMatrix(arr);
+          }
+          break;
+        }
+        MOZ_FALLTHROUGH;
+      case eCSSKeyword_interpolatematrix: {
         // FIXME: If the matrix contains only numbers then we could decompose
         // here.
 
         // Construct temporary lists with only this item in them.
         nsCSSValueList tempList1, tempList2;
         tempList1.mValue = aList1->mValue;
         tempList2.mValue = aList2->mValue;
 
--- a/layout/style/nsStyleTransformMatrix.cpp
+++ b/layout/style/nsStyleTransformMatrix.cpp
@@ -680,16 +680,42 @@ MatrixForTransformFunction(Matrix4x4& aM
  */
 nsCSSKeyword
 TransformFunctionOf(const nsCSSValue::Array* aData)
 {
   MOZ_ASSERT(aData->Item(0).GetUnit() == eCSSUnit_Enumerated);
   return aData->Item(0).GetKeywordValue();
 }
 
+void
+SetIdentityMatrix(nsCSSValue::Array* aMatrix)
+{
+  MOZ_ASSERT(aMatrix, "aMatrix should be non-null");
+
+  nsCSSKeyword tfunc = TransformFunctionOf(aMatrix);
+  MOZ_ASSERT(tfunc == eCSSKeyword_matrix ||
+             tfunc == eCSSKeyword_matrix3d,
+             "Only accept matrix and matrix3d");
+
+  if (tfunc == eCSSKeyword_matrix) {
+    MOZ_ASSERT(aMatrix->Count() == 7, "Invalid matrix");
+    Matrix m;
+    for (size_t i = 0; i < 6; ++i) {
+      aMatrix->Item(i + 1).SetFloatValue(m.components[i], eCSSUnit_Number);
+    }
+    return;
+  }
+
+  MOZ_ASSERT(aMatrix->Count() == 17, "Invalid matrix3d");
+  Matrix4x4 m;
+  for (size_t i = 0; i < 16; ++i) {
+    aMatrix->Item(i + 1).SetFloatValue(m.components[i], eCSSUnit_Number);
+  }
+}
+
 Matrix4x4
 ReadTransforms(const nsCSSValueList* aList,
                nsStyleContext* aContext,
                nsPresContext* aPresContext,
                RuleNodeCacheConditions& aConditions,
                TransformReferenceBox& aRefBox,
                float aAppUnitsPerMatrixUnit,
                bool* aContains3dTransform)
--- a/layout/style/nsStyleTransformMatrix.h
+++ b/layout/style/nsStyleTransformMatrix.h
@@ -122,16 +122,18 @@ namespace nsStyleTransformMatrix {
   };
 
   /**
    * Return the transform function, as an nsCSSKeyword, for the given
    * nsCSSValue::Array from a transform list.
    */
   nsCSSKeyword TransformFunctionOf(const nsCSSValue::Array* aData);
 
+  void SetIdentityMatrix(nsCSSValue::Array* aMatrix);
+
   float ProcessTranslatePart(const nsCSSValue& aValue,
                              nsStyleContext* aContext,
                              nsPresContext* aPresContext,
                              mozilla::RuleNodeCacheConditions& aConditions,
                              TransformReferenceBox* aRefBox,
                              TransformReferenceBox::DimensionGetter aDimensionGetter = nullptr);
 
   void