Bug 1304886 - Part 5: Make InterpolateTransformMatrix template to calculate accumulation. r?boris draft
 author Hiroyuki Ikezoe Wed, 16 Nov 2016 20:32:32 +0900 changeset 439610 4c62d1637175ea29ca0093a1f08daf4f772ff349 parent 439609 b2a605588e13c3e165cf3617aae72ac236ce2bcb child 439611 01bfa6e4ecc7c2e6edfee510a31618f4103b8bdd push id 36059 push user hiikezoe@mozilla-japan.org push date Wed, 16 Nov 2016 11:32:59 +0000 reviewers boris bugs 1304886 milestone 53.0a1
Bug 1304886 - Part 5: Make InterpolateTransformMatrix template to calculate accumulation. r?boris InterpolateTransformMatrix renamed to OperateTransformMatrix. MozReview-Commit-ID: 3IpkAIa3cBN
```--- a/layout/style/nsStyleTransformMatrix.cpp
+++ b/layout/style/nsStyleTransformMatrix.cpp
@@ -259,33 +259,57 @@ ProcessMatrix3D(Matrix4x4& aMatrix,
&aRefBox, &TransformReferenceBox::Height);
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;
-}
+class Interpolate {
+public:
+  template<typename T>
+  static T operate(const T& aOne, const T& aTwo, double aCoeff)
+  {
+    MOZ_ASSERT(aCoeff >= 0.0 && aCoeff <= 1.0,
+               "Coefficient should be in the range [0.0, 1.0]");
+    return aOne + (aTwo - aOne) * aCoeff;
+  }
+
+  static Point3D operateForScale(const Point3D& aOne,
+                                 const Point3D& aTwo,
+                                 double aCoeff)
+  {
+    MOZ_ASSERT(aCoeff >= 0.0 && aCoeff <= 1.0,
+               "Coefficient should be in the range [0.0, 1.0]");
+    return aOne + (aTwo - aOne) * aCoeff;
+  }
+
+  static Matrix4x4 operateForRotate(const gfxQuaternion& aOne,
+                                    const gfxQuaternion& aTwo,
+                                    double aCoeff)
+  {
+    MOZ_ASSERT(aCoeff >= 0.0 && aCoeff <= 1.0,
+               "Coefficient should be in the range [0.0, 1.0]");
+    return aOne.Slerp(aTwo, aCoeff).ToMatrix();
+  }
+};

/**
- * Interpolates between 2 matrices by decomposing them.
+ * Calculate 2 matrices by decomposing them with Operator.
*
* @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]
+ * @param aProgress  Coefficient for the Operator.
*/
+template <typename Operator>
static Matrix4x4
-InterpolateTransformMatrix(const Matrix4x4 &aMatrix1,
-                           const Matrix4x4 &aMatrix2,
-                           double aProgress)
+OperateTransformMatrix(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};
@@ -305,57 +329,56 @@ InterpolateTransformMatrix(const Matrix4
Decompose3DMatrix(aMatrix2, scale2, shear2,
rotate2, translate2, perspective2);
}

// Interpolate each of the pieces
Matrix4x4 result;

Point4D perspective =
-    InterpolateNumerically(perspective1, perspective2, aProgress);
+    Operator::operate(perspective1, perspective2, aProgress);
result.SetTransposedVector(3, perspective);

Point3D translate =
-    InterpolateNumerically(translate1, translate2, aProgress);
+    Operator::operate(translate1, translate2, aProgress);
result.PreTranslate(translate.x, translate.y, translate.z);

-  gfxQuaternion q3 = rotate1.Slerp(rotate2, aProgress);
-  Matrix4x4 rotate = q3.ToMatrix();
+  Matrix4x4 rotate = Operator::operateForRotate(rotate1, rotate2, aProgress);
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);
+    Operator::operate(shear1[ShearType::YZSHEAR],
+                      shear2[ShearType::YZSHEAR],
+                      aProgress);
if (yzshear != 0.0) {
result.SkewYZ(yzshear);
}

float xzshear =
-    InterpolateNumerically(shear1[ShearType::XZSHEAR],
-                           shear2[ShearType::XZSHEAR],
-                           aProgress);
+    Operator::operate(shear1[ShearType::XZSHEAR],
+                      shear2[ShearType::XZSHEAR],
+                      aProgress);
if (xzshear != 0.0) {
result.SkewXZ(xzshear);
}

float xyshear =
-    InterpolateNumerically(shear1[ShearType::XYSHEAR],
-                           shear2[ShearType::XYSHEAR],
-                           aProgress);
+    Operator::operate(shear1[ShearType::XYSHEAR],
+                      shear2[ShearType::XYSHEAR],
+                      aProgress);
if (xyshear != 0.0) {
result.SkewXY(xyshear);
}

Point3D scale =
-    InterpolateNumerically(scale1, scale2, aProgress);
+    Operator::operateForScale(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 */
@@ -382,17 +405,18 @@ ProcessInterpolateMatrix(Matrix4x4& aMat
aContext, aPresContext,
aConditions,
aRefBox, nsPresContext::AppUnitsPerCSSPixel(),
aContains3dTransform);
}