Bug 1168263 - Simplify GetResultingTransformMatrix calculations to avoid unnecessary origin changes. r=roc
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 26 Nov 2015 22:32:35 +1300
changeset 308452 885889d182fdb6baab2a51d75b3ab4e6abf82576
parent 308451 7a4447e71d7a63b6e77601fd4b374b83bf4f9cbb
child 308453 7e18014be68d9e13760b2814862745911caf49a5
push id5513
push userraliiev@mozilla.com
push dateMon, 25 Jan 2016 13:55:34 +0000
treeherdermozilla-beta@5ee97dd05b5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1168263
milestone45.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 1168263 - Simplify GetResultingTransformMatrix calculations to avoid unnecessary origin changes. r=roc
gfx/layers/composite/AsyncCompositionManager.cpp
gfx/layers/ipc/LayerTransactionParent.cpp
layout/base/nsDisplayList.cpp
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -528,23 +528,18 @@ SampleValue(float aPortion, Animation& a
   Point3D perspectiveOrigin = data.perspectiveOrigin();
   nsDisplayTransform::FrameTransformProperties props(interpolatedList,
                                                      transformOrigin,
                                                      perspectiveOrigin,
                                                      data.perspective());
   Matrix4x4 transform =
     nsDisplayTransform::GetResultingTransformMatrix(props, origin,
                                                     data.appUnitsPerDevPixel(),
-                                                    0, &data.bounds());
-  Point3D scaledOrigin =
-    Point3D(NS_round(NSAppUnitsToFloatPixels(origin.x, data.appUnitsPerDevPixel())),
-            NS_round(NSAppUnitsToFloatPixels(origin.y, data.appUnitsPerDevPixel())),
-            0.0f);
-
-  transform.PreTranslate(scaledOrigin);
+                                                    nsDisplayTransform::OFFSET_BY_ORIGIN,
+                                                    &data.bounds());
 
   InfallibleTArray<TransformFunction> functions;
   functions.AppendElement(TransformMatrix(transform));
   *aValue = functions;
 }
 
 static bool
 SampleAnimations(Layer* aLayer, TimeStamp aPoint)
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -739,24 +739,21 @@ LayerTransactionParent::RecvGetAnimation
         Point3D(NS_round(NSAppUnitsToFloatPixels(data.origin().x, scale)),
                 NS_round(NSAppUnitsToFloatPixels(data.origin().y, scale)),
                 0.0f);
       transformOrigin = data.transformOrigin();
       break;
     }
   }
 
-  // Undo the translation to the origin of the reference frame applied by
-  // AsyncCompositionManager::SampleValue
-  transform.PreTranslate(-scaledOrigin.x, -scaledOrigin.y, -scaledOrigin.z);
+  transform.PostTranslate(-scaledOrigin.x, -scaledOrigin.y, -scaledOrigin.z);
 
   // Undo the rebasing applied by
   // nsDisplayTransform::GetResultingTransformMatrixInternal
-  Point3D basis = -scaledOrigin - transformOrigin;
-  transform.ChangeBasis(basis.x, basis.y, basis.z);
+  transform.ChangeBasis(-transformOrigin);
 
   // Convert to CSS pixels (this undoes the operations performed by
   // nsStyleTransformMatrix::ProcessTranslatePart which is called from
   // nsDisplayTransform::GetResultingTransformMatrix)
   double devPerCss =
     double(scale) / double(nsDeviceContext::AppUnitsPerCSSPixel());
   transform._41 *= devPerCss;
   transform._42 *= devPerCss;
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -5129,23 +5129,27 @@ nsDisplayTransform::GetDeltaToPerspectiv
         coord.GetPercentValue();
     } else {
       MOZ_ASSERT(coord.GetUnit() == eStyleUnit_Coord, "unexpected unit");
       *coords[index] =
         NSAppUnitsToFloatPixels(coord.GetCoordValue(), aAppUnitsPerPixel);
     }
   }
 
-  nsPoint parentOffset = aFrame->GetOffsetTo(cbFrame);
-  Point3D gfxOffset(
-            NSAppUnitsToFloatPixels(parentOffset.x, aAppUnitsPerPixel),
-            NSAppUnitsToFloatPixels(parentOffset.y, aAppUnitsPerPixel),
+  /* GetOffsetTo computes the offset required to move from 0,0 in cbFrame to 0,0
+   * in aFrame. Although we actually want the inverse of this, it's faster to
+   * compute this way.
+   */
+  nsPoint frameToCbOffset = -aFrame->GetOffsetTo(cbFrame);
+  Point3D frameToCbGfxOffset(
+            NSAppUnitsToFloatPixels(frameToCbOffset.x, aAppUnitsPerPixel),
+            NSAppUnitsToFloatPixels(frameToCbOffset.y, aAppUnitsPerPixel),
             0.0f);
 
-  return result - gfxOffset;
+  return result + frameToCbGfxOffset;
 }
 
 nsDisplayTransform::FrameTransformProperties::FrameTransformProperties(const nsIFrame* aFrame,
                                                                        float aAppUnitsPerPixel,
                                                                        const nsRect* aBoundsOverride)
   : mFrame(aFrame)
   , mTransformList(aFrame->StyleDisplay()->mSpecifiedTransform)
   , mToTransformOrigin(GetDeltaToTransformOrigin(aFrame, aAppUnitsPerPixel, aBoundsOverride))
@@ -5261,27 +5265,26 @@ nsDisplayTransform::GetResultingTransfor
                         0);
 
   bool hasPerspective = aProperties.mChildPerspective > 0.0;
 
   if (!hasSVGTransforms || !hasTransformFromSVGParent) {
     // This is a simplification of the following |else| block, the
     // simplification being possible because we don't need to apply
     // mToTransformOrigin between two transforms.
-    Point3D offsets = roundedOrigin + aProperties.mToTransformOrigin;
     if ((aFlags & OFFSET_BY_ORIGIN) &&
         !hasPerspective) {
       // We can fold the final translation by roundedOrigin into the first matrix
       // basis change translation. This is more stable against variation due to
       // insufficient floating point precision than reversing the translation
       // afterwards.
       result.PreTranslate(-aProperties.mToTransformOrigin);
-      result.PostTranslate(offsets);
+      result.PostTranslate(roundedOrigin + aProperties.mToTransformOrigin);
     } else {
-      result.ChangeBasis(offsets);
+      result.ChangeBasis(aProperties.mToTransformOrigin);
     }
   } else {
     Point3D refBoxOffset(NSAppUnitsToFloatPixels(refBox.X(), aAppUnitsPerPixel),
                          NSAppUnitsToFloatPixels(refBox.Y(), aAppUnitsPerPixel),
                          0);
     // We have both a transform and children-only transform. The
     // 'transform-origin' must apply between the two, so we need to apply it
     // now before we apply transformFromSVGParent. Since mToTransformOrigin is
@@ -5296,36 +5299,35 @@ nsDisplayTransform::GetResultingTransfor
       frame->PresContext()->AppUnitsPerCSSPixel() / aAppUnitsPerPixel;
     transformFromSVGParent._31 *= pixelsPerCSSPx;
     transformFromSVGParent._32 *= pixelsPerCSSPx;
     result = result * Matrix4x4::From2D(transformFromSVGParent);
 
     // Similar to the code in the |if| block above, but since we've accounted
     // for mToTransformOrigin so we don't include that. We also need to reapply
     // refBoxOffset.
-    Point3D offsets = roundedOrigin + refBoxOffset;
     if ((aFlags & OFFSET_BY_ORIGIN) &&
         !hasPerspective) {
       result.PreTranslate(-refBoxOffset);
-      result.PostTranslate(offsets);
+      result.PostTranslate(roundedOrigin + refBoxOffset);
     } else {
-      result.ChangeBasis(offsets);
+      result.ChangeBasis(refBoxOffset);
     }
   }
 
   if (hasPerspective) {
     Matrix4x4 perspective;
     perspective._34 =
       -1.0 / NSAppUnitsToFloatPixels(aProperties.mChildPerspective, aAppUnitsPerPixel);
 
-    perspective.ChangeBasis(aProperties.GetToPerspectiveOrigin() + roundedOrigin);
+    perspective.ChangeBasis(aProperties.GetToPerspectiveOrigin());
     result = result * perspective;
 
     if (aFlags & OFFSET_BY_ORIGIN) {
-      result.PreTranslate(roundedOrigin);
+      result.PostTranslate(roundedOrigin);
     }
   }
 
   if ((aFlags & INCLUDE_PRESERVE3D_ANCESTORS) &&
       frame && frame->Combines3DTransformWithAncestors()) {
     // Include the transform set on our parent
     NS_ASSERTION(frame->GetParent() &&
                  frame->GetParent()->IsTransformed() &&