Bug 1304886 - Part 3: Move InterpolateTransformMatrix into nsStyleTransformMatrix. r?boris draft
authorHiroyuki Ikezoe <hiikezoe@mozilla-japan.org>
Wed, 16 Nov 2016 20:32:32 +0900
changeset 439608 c5cf349e36f1f14db4e0244e5519c66013e16050
parent 439607 19dd1af1cbbcc95c046885ce3531219ef93002c3
child 439609 b2a605588e13c3e165cf3617aae72ac236ce2bcb
push id36059
push userhiikezoe@mozilla-japan.org
push dateWed, 16 Nov 2016 11:32:59 +0000
reviewersboris
bugs1304886
milestone53.0a1
Bug 1304886 - Part 3: Move InterpolateTransformMatrix into nsStyleTransformMatrix. r?boris MozReview-Commit-ID: 7GV6B7AwNcg
layout/style/StyleAnimationValue.cpp
layout/style/StyleAnimationValue.h
layout/style/nsStyleTransformMatrix.cpp
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -1831,104 +1831,16 @@ StyleAnimationValue::AppendTransformFunc
   item->mValue.SetArrayValue(arr, eCSSUnit_Function);
 
   *aListTail = item;
   aListTail = &item->mNext;
 
   return arr.forget();
 }
 
-template<typename T>
-T InterpolateNumerically(const T& aOne, const T& aTwo, double aCoeff)
-{
-  return aOne + (aTwo - aOne) * aCoeff;
-}
-
-
-/* static */ Matrix4x4
-StyleAnimationValue::InterpolateTransformMatrix(const Matrix4x4 &aMatrix1,
-                                                const Matrix4x4 &aMatrix2,
-                                                double aProgress)
-{
-  // Decompose both matrices
-
-  // TODO: What do we do if one of these returns false (singular matrix)
-  Point3D scale1(1, 1, 1), translate1;
-  Point4D perspective1(0, 0, 0, 1);
-  gfxQuaternion rotate1;
-  nsStyleTransformMatrix::ShearArray shear1{0.0f, 0.0f, 0.0f};
-
-  Point3D scale2(1, 1, 1), translate2;
-  Point4D perspective2(0, 0, 0, 1);
-  gfxQuaternion rotate2;
-  nsStyleTransformMatrix::ShearArray shear2{0.0f, 0.0f, 0.0f};
-
-  Matrix matrix2d1, matrix2d2;
-  if (aMatrix1.Is2D(&matrix2d1) && aMatrix2.Is2D(&matrix2d2)) {
-    Decompose2DMatrix(matrix2d1, scale1, shear1, rotate1, translate1);
-    Decompose2DMatrix(matrix2d2, scale2, shear2, rotate2, translate2);
-  } else {
-    Decompose3DMatrix(aMatrix1, scale1, shear1,
-                      rotate1, translate1, perspective1);
-    Decompose3DMatrix(aMatrix2, scale2, shear2,
-                      rotate2, translate2, perspective2);
-  }
-
-  // Interpolate each of the pieces
-  Matrix4x4 result;
-
-  Point4D perspective =
-    InterpolateNumerically(perspective1, perspective2, aProgress);
-  result.SetTransposedVector(3, perspective);
-
-  Point3D translate =
-    InterpolateNumerically(translate1, translate2, aProgress);
-  result.PreTranslate(translate.x, translate.y, translate.z);
-
-  gfxQuaternion q3 = rotate1.Slerp(rotate2, aProgress);
-  Matrix4x4 rotate = q3.ToMatrix();
-  if (!rotate.IsIdentity()) {
-      result = rotate * result;
-  }
-
-  // TODO: Would it be better to interpolate these as angles?
-  //       How do we convert back to angles?
-  float yzshear =
-    InterpolateNumerically(shear1[ShearType::YZSHEAR],
-                           shear2[ShearType::YZSHEAR],
-                           aProgress);
-  if (yzshear != 0.0) {
-    result.SkewYZ(yzshear);
-  }
-
-  float xzshear =
-    InterpolateNumerically(shear1[ShearType::XZSHEAR],
-                           shear2[ShearType::XZSHEAR],
-                           aProgress);
-  if (xzshear != 0.0) {
-    result.SkewXZ(xzshear);
-  }
-
-  float xyshear =
-    InterpolateNumerically(shear1[ShearType::XYSHEAR],
-                           shear2[ShearType::XYSHEAR],
-                           aProgress);
-  if (xyshear != 0.0) {
-    result.SkewXY(xyshear);
-  }
-
-  Point3D scale =
-    InterpolateNumerically(scale1, scale2, aProgress);
-  if (scale != Point3D(1.0, 1.0, 1.0)) {
-    result.PreScale(scale.x, scale.y, scale.z);
-  }
-
-  return result;
-}
-
 static nsCSSValueList*
 AddDifferentTransformLists(double aCoeff1, const nsCSSValueList* aList1,
                            double aCoeff2, const nsCSSValueList* aList2)
 {
   nsAutoPtr<nsCSSValueList> result;
   nsCSSValueList **resultTail = getter_Transfers(result);
 
   RefPtr<nsCSSValue::Array> arr;
--- a/layout/style/StyleAnimationValue.h
+++ b/layout/style/StyleAnimationValue.h
@@ -289,27 +289,16 @@ public:
    * @param [out] aComputedValue The resulting computed value.
    * @return true on success, false on failure.
    */
   static MOZ_MUST_USE bool ExtractComputedValue(
     nsCSSPropertyID aProperty,
     nsStyleContext* aStyleContext,
     StyleAnimationValue& aComputedValue);
 
-  /**
-   * Interpolates between 2 matrices by decomposing them.
-   *
-   * @param aMatrix1   First matrix, using CSS pixel units.
-   * @param aMatrix2   Second matrix, using CSS pixel units.
-   * @param aProgress  Interpolation value in the range [0.0, 1.0]
-   */
-  static gfx::Matrix4x4 InterpolateTransformMatrix(const gfx::Matrix4x4 &aMatrix1,
-                                                   const gfx::Matrix4x4 &aMatrix2,
-                                                   double aProgress);
-
   static already_AddRefed<nsCSSValue::Array>
     AppendTransformFunction(nsCSSKeyword aTransformFunction,
                             nsCSSValueList**& aListTail);
 
   /**
    * The types and values for the values that we extract and animate.
    */
   enum Unit {
--- a/layout/style/nsStyleTransformMatrix.cpp
+++ b/layout/style/nsStyleTransformMatrix.cpp
@@ -259,16 +259,110 @@ ProcessMatrix3D(Matrix4x4& aMatrix,
                                   &aRefBox, &TransformReferenceBox::Height);
   temp._43 = ProcessTranslatePart(aData->Item(15),
                                   aContext, aPresContext, aConditions,
                                   nullptr);
 
   aMatrix = temp * aMatrix;
 }
 
+template<typename T>
+T InterpolateNumerically(const T& aOne, const T& aTwo, double aCoeff)
+{
+  return aOne + (aTwo - aOne) * aCoeff;
+}
+
+/**
+ * Interpolates between 2 matrices by decomposing them.
+ *
+ * @param aMatrix1   First matrix, using CSS pixel units.
+ * @param aMatrix2   Second matrix, using CSS pixel units.
+ * @param aProgress  Interpolation value in the range [0.0, 1.0]
+ */
+static Matrix4x4
+InterpolateTransformMatrix(const Matrix4x4 &aMatrix1,
+                           const Matrix4x4 &aMatrix2,
+                           double aProgress)
+{
+  // Decompose both matrices
+
+  // TODO: What do we do if one of these returns false (singular matrix)
+  Point3D scale1(1, 1, 1), translate1;
+  Point4D perspective1(0, 0, 0, 1);
+  gfxQuaternion rotate1;
+  nsStyleTransformMatrix::ShearArray shear1{0.0f, 0.0f, 0.0f};
+
+  Point3D scale2(1, 1, 1), translate2;
+  Point4D perspective2(0, 0, 0, 1);
+  gfxQuaternion rotate2;
+  nsStyleTransformMatrix::ShearArray shear2{0.0f, 0.0f, 0.0f};
+
+  Matrix matrix2d1, matrix2d2;
+  if (aMatrix1.Is2D(&matrix2d1) && aMatrix2.Is2D(&matrix2d2)) {
+    Decompose2DMatrix(matrix2d1, scale1, shear1, rotate1, translate1);
+    Decompose2DMatrix(matrix2d2, scale2, shear2, rotate2, translate2);
+  } else {
+    Decompose3DMatrix(aMatrix1, scale1, shear1,
+                      rotate1, translate1, perspective1);
+    Decompose3DMatrix(aMatrix2, scale2, shear2,
+                      rotate2, translate2, perspective2);
+  }
+
+  // Interpolate each of the pieces
+  Matrix4x4 result;
+
+  Point4D perspective =
+    InterpolateNumerically(perspective1, perspective2, aProgress);
+  result.SetTransposedVector(3, perspective);
+
+  Point3D translate =
+    InterpolateNumerically(translate1, translate2, aProgress);
+  result.PreTranslate(translate.x, translate.y, translate.z);
+
+  gfxQuaternion q3 = rotate1.Slerp(rotate2, aProgress);
+  Matrix4x4 rotate = q3.ToMatrix();
+  if (!rotate.IsIdentity()) {
+    result = rotate * result;
+  }
+
+  // TODO: Would it be better to interpolate these as angles?
+  //       How do we convert back to angles?
+  float yzshear =
+    InterpolateNumerically(shear1[ShearType::YZSHEAR],
+                           shear2[ShearType::YZSHEAR],
+                           aProgress);
+  if (yzshear != 0.0) {
+    result.SkewYZ(yzshear);
+  }
+
+  float xzshear =
+    InterpolateNumerically(shear1[ShearType::XZSHEAR],
+                           shear2[ShearType::XZSHEAR],
+                           aProgress);
+  if (xzshear != 0.0) {
+    result.SkewXZ(xzshear);
+  }
+
+  float xyshear =
+    InterpolateNumerically(shear1[ShearType::XYSHEAR],
+                           shear2[ShearType::XYSHEAR],
+                           aProgress);
+  if (xyshear != 0.0) {
+    result.SkewXY(xyshear);
+  }
+
+  Point3D scale =
+    InterpolateNumerically(scale1, scale2, aProgress);
+  if (scale != Point3D(1.0, 1.0, 1.0)) {
+    result.PreScale(scale.x, scale.y, scale.z);
+  }
+
+  return result;
+}
+
 /* Helper function to process two matrices that we need to interpolate between */
 void
 ProcessInterpolateMatrix(Matrix4x4& aMatrix,
                          const nsCSSValue::Array* aData,
                          nsStyleContext* aContext,
                          nsPresContext* aPresContext,
                          RuleNodeCacheConditions& aConditions,
                          TransformReferenceBox& aRefBox,
@@ -288,19 +382,17 @@ ProcessInterpolateMatrix(Matrix4x4& aMat
     matrix2 = ReadTransforms(aData->Item(2).GetListValue(),
                              aContext, aPresContext,
                              aConditions,
                              aRefBox, nsPresContext::AppUnitsPerCSSPixel(),
                              aContains3dTransform);
   }
   double progress = aData->Item(3).GetPercentValue();
 
-  aMatrix =
-    StyleAnimationValue::InterpolateTransformMatrix(matrix1, matrix2, progress)
-    * aMatrix;
+  aMatrix = InterpolateTransformMatrix(matrix1, matrix2, progress) * aMatrix;
 }
 
 /* Helper function to process a translatex function. */
 static void
 ProcessTranslateX(Matrix4x4& aMatrix,
                   const nsCSSValue::Array* aData,
                   nsStyleContext* aContext,
                   nsPresContext* aPresContext,