Bug 781701 - Interpolate rotate3d rotation angles numerically when we can instead of using matrix decompositon. r=dbaron, a=sledru
authorMatt Woodrow <mwoodrow@mozilla.com>
Tue, 19 Aug 2014 15:58:17 +1200
changeset 217571 2e4f0cb37da14d73675a8d0d9a88c6498de77991
parent 217570 16c381733bedc6edd52604656e615badfb97c649
child 217572 5a9669ba5940eb47b39316e0ec383dbbaf521a91
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)
reviewersdbaron, sledru
bugs781701
milestone33.0a2
Bug 781701 - Interpolate rotate3d rotation angles numerically when we can instead of using matrix decompositon. r=dbaron, a=sledru
layout/style/StyleAnimationValue.cpp
layout/style/nsStyleTransformMatrix.cpp
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -1808,20 +1808,46 @@ AddTransformLists(double aCoeff1, const 
         NS_ABORT_IF_FALSE(a1->Count() == 2, "unexpected count");
         NS_ABORT_IF_FALSE(a2->Count() == 2, "unexpected count");
 
         AddCSSValueAngle(aCoeff1, a1->Item(1), aCoeff2, a2->Item(1),
                          arr->Item(1));
 
         break;
       }
+      case eCSSKeyword_rotate3d: {
+        gfxPoint3D vector1(a1->Item(1).GetFloatValue(),
+                           a1->Item(2).GetFloatValue(),
+                           a1->Item(3).GetFloatValue());
+        vector1.Normalize();
+        gfxPoint3D vector2(a2->Item(1).GetFloatValue(),
+                           a2->Item(2).GetFloatValue(),
+                           a2->Item(3).GetFloatValue());
+        vector2.Normalize();
+
+        // Handle rotate3d with matched (normalized) vectors,
+        // otherwise fallthrough to the next switch statement
+        // and do matrix decomposition.
+        if (vector1 == vector2) {
+          // We skipped appending a transform function above for rotate3d,
+          // so do it now.
+          arr = StyleAnimationValue::AppendTransformFunction(tfunc, resultTail);
+          arr->Item(1).SetFloatValue(vector1.x, eCSSUnit_Number);
+          arr->Item(2).SetFloatValue(vector1.y, eCSSUnit_Number);
+          arr->Item(3).SetFloatValue(vector1.z, eCSSUnit_Number);
+
+          AddCSSValueAngle(aCoeff1, a1->Item(4), aCoeff2, a2->Item(4),
+                           arr->Item(4));
+          break;
+        }
+        // FALL THROUGH
+      }
       case eCSSKeyword_matrix:
       case eCSSKeyword_matrix3d:
       case eCSSKeyword_interpolatematrix:
-      case eCSSKeyword_rotate3d:
       case eCSSKeyword_perspective: {
         // 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
@@ -432,43 +432,39 @@ ProcessRotate3D(gfx3DMatrix& aMatrix, co
   /* The current spec specifies a matrix that rotates in the wrong direction. For now we just negate
    * the angle provided to get the correct rotation direction until the spec is updated.
    * See bug 704468.
    */
   double theta = -aData->Item(4).GetAngleValueInRadians();
   float cosTheta = FlushToZero(cos(theta));
   float sinTheta = FlushToZero(sin(theta));
 
-  float x = aData->Item(1).GetFloatValue();
-  float y = aData->Item(2).GetFloatValue();
-  float z = aData->Item(3).GetFloatValue();
+  gfxPoint3D vector(aData->Item(1).GetFloatValue(),
+                    aData->Item(2).GetFloatValue(),
+                    aData->Item(3).GetFloatValue());
 
-  /* Normalize [x,y,z] */
-  float length = sqrt(x*x + y*y + z*z);
-  if (length == 0.0) {
+  if (!vector.Length()) {
     return;
   }
-  x /= length;
-  y /= length;
-  z /= length;
+  vector.Normalize();
 
   gfx3DMatrix temp;
 
   /* Create our matrix */
-  temp._11 = 1 + (1 - cosTheta) * (x * x - 1);
-  temp._12 = -z * sinTheta + (1 - cosTheta) * x * y;
-  temp._13 = y * sinTheta + (1 - cosTheta) * x * z;
+  temp._11 = 1 + (1 - cosTheta) * (vector.x * vector.x - 1);
+  temp._12 = -vector.z * sinTheta + (1 - cosTheta) * vector.x * vector.y;
+  temp._13 = vector.y * sinTheta + (1 - cosTheta) * vector.x * vector.z;
   temp._14 = 0.0f;
-  temp._21 = z * sinTheta + (1 - cosTheta) * x * y;
-  temp._22 = 1 + (1 - cosTheta) * (y * y - 1);
-  temp._23 = -x * sinTheta + (1 - cosTheta) * y * z;
+  temp._21 = vector.z * sinTheta + (1 - cosTheta) * vector.x * vector.y;
+  temp._22 = 1 + (1 - cosTheta) * (vector.y * vector.y - 1);
+  temp._23 = -vector.x * sinTheta + (1 - cosTheta) * vector.y * vector.z;
   temp._24 = 0.0f;
-  temp._31 = -y * sinTheta + (1 - cosTheta) * x * z;
-  temp._32 = x * sinTheta + (1 - cosTheta) * y * z;
-  temp._33 = 1 + (1 - cosTheta) * (z * z - 1);
+  temp._31 = -vector.y * sinTheta + (1 - cosTheta) * vector.x * vector.z;
+  temp._32 = vector.x * sinTheta + (1 - cosTheta) * vector.y * vector.z;
+  temp._33 = 1 + (1 - cosTheta) * (vector.z * vector.z - 1);
   temp._34 = 0.0f;
   temp._41 = 0.0f;
   temp._42 = 0.0f;
   temp._43 = 0.0f;
   temp._44 = 1.0f;
 
   aMatrix = temp * aMatrix;
 }