Bug 1069417 - Modify TransformTo() and related functions to use typed matrices. r=kats
authorBotond Ballo <botond@mozilla.com>
Mon, 30 Nov 2015 20:14:31 -0500
changeset 309548 bad076546d10d21693dccd01b748950016f302f2
parent 309547 a8d8fc095ebcb3b35e82be25cfa3b7e1a1924c08
child 309549 1995fa8bbf43e1458f0fff9310cb0e8d919097c5
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)
reviewerskats
bugs1069417
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 1069417 - Modify TransformTo() and related functions to use typed matrices. r=kats Call sites (all in APZ and related code) were modified accordingly. Some of these modifications involved changing some matrices stored in APZ to be typed.
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/src/APZCTreeManager.h
gfx/layers/apz/src/AsyncPanZoomController.cpp
gfx/layers/apz/src/AsyncPanZoomController.h
gfx/layers/apz/src/HitTestingTreeNode.cpp
gfx/layers/apz/src/InputBlockState.cpp
gfx/layers/apz/src/InputBlockState.h
gfx/layers/apz/test/gtest/TestAsyncPanZoomController.cpp
gfx/layers/client/ClientTiledPaintedLayer.cpp
gfx/layers/client/TiledContentClient.cpp
gfx/layers/client/TiledContentClient.h
gfx/layers/composite/AsyncCompositionManager.cpp
gfx/layers/composite/LayerManagerComposite.cpp
layout/base/UnitTransforms.h
layout/base/nsDisplayList.cpp
widget/InputData.cpp
widget/InputData.h
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -746,18 +746,18 @@ APZCTreeManager::ReceiveInputEvent(Input
 
         // For wheel events, the call to ReceiveInputEvent below may result in
         // scrolling, which changes the async transform. However, the event we
         // want to pass to gecko should be the pre-scroll event coordinates,
         // transformed into the gecko space. (pre-scroll because the mouse
         // cursor is stationary during wheel scrolling, unlike touchmove
         // events). Since we just flushed the pending repaints the transform to
         // gecko space should only consist of overscroll-cancelling transforms.
-        Matrix4x4 transformToGecko = GetScreenToApzcTransform(apzc)
-                                   * GetApzcToGeckoTransform(apzc);
+        ScreenToScreenMatrix4x4 transformToGecko = GetScreenToApzcTransform(apzc)
+                                                 * GetApzcToGeckoTransform(apzc);
         Maybe<ScreenPoint> untransformedOrigin = UntransformTo<ScreenPixel>(
           transformToGecko, wheelInput.mOrigin);
 
         if (!untransformedOrigin) {
           return result;
         }
 
         result = mInputQueue->ReceiveInputEvent(
@@ -786,18 +786,18 @@ APZCTreeManager::ReceiveInputEvent(Input
 
         // For pan gesture events, the call to ReceiveInputEvent below may result in
         // scrolling, which changes the async transform. However, the event we
         // want to pass to gecko should be the pre-scroll event coordinates,
         // transformed into the gecko space. (pre-scroll because the mouse
         // cursor is stationary during pan gesture scrolling, unlike touchmove
         // events). Since we just flushed the pending repaints the transform to
         // gecko space should only consist of overscroll-cancelling transforms.
-        Matrix4x4 transformToGecko = GetScreenToApzcTransform(apzc)
-                                   * GetApzcToGeckoTransform(apzc);
+        ScreenToScreenMatrix4x4 transformToGecko = GetScreenToApzcTransform(apzc)
+                                                 * GetApzcToGeckoTransform(apzc);
         Maybe<ScreenPoint> untransformedStartPoint = UntransformTo<ScreenPixel>(
           transformToGecko, panInput.mPanStartPoint);
         Maybe<ScreenPoint> untransformedDisplacement = UntransformVector<ScreenPixel>(
             transformToGecko, panInput.mPanDisplacement, panInput.mPanStartPoint);
 
         if (!untransformedStartPoint || !untransformedDisplacement) {
           return result;
         }
@@ -815,18 +815,18 @@ APZCTreeManager::ReceiveInputEvent(Input
       break;
     } case PINCHGESTURE_INPUT: {  // note: no one currently sends these
       PinchGestureInput& pinchInput = aEvent.AsPinchGestureInput();
       RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(pinchInput.mFocusPoint,
                                                             &hitResult);
       if (apzc) {
         MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion);
 
-        Matrix4x4 outTransform = GetScreenToApzcTransform(apzc)
-                               * GetApzcToGeckoTransform(apzc);
+        ScreenToScreenMatrix4x4 outTransform = GetScreenToApzcTransform(apzc)
+                                             * GetApzcToGeckoTransform(apzc);
         Maybe<ScreenPoint> untransformedFocusPoint = UntransformTo<ScreenPixel>(
           outTransform, pinchInput.mFocusPoint);
 
         if (!untransformedFocusPoint) {
           return result;
         }
 
         result = mInputQueue->ReceiveInputEvent(
@@ -841,18 +841,18 @@ APZCTreeManager::ReceiveInputEvent(Input
       break;
     } case TAPGESTURE_INPUT: {  // note: no one currently sends these
       TapGestureInput& tapInput = aEvent.AsTapGestureInput();
       RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(tapInput.mPoint,
                                                             &hitResult);
       if (apzc) {
         MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion);
 
-        Matrix4x4 outTransform = GetScreenToApzcTransform(apzc)
-                               * GetApzcToGeckoTransform(apzc);
+        ScreenToScreenMatrix4x4 outTransform = GetScreenToApzcTransform(apzc)
+                                             * GetApzcToGeckoTransform(apzc);
         Maybe<ScreenIntPoint> untransformedPoint =
           UntransformTo<ScreenPixel>(outTransform, tapInput.mPoint);
 
         if (!untransformedPoint) {
           return result;
         }
 
         result = mInputQueue->ReceiveInputEvent(
@@ -946,19 +946,19 @@ APZCTreeManager::ProcessTouchInput(Multi
     mApzcForInputBlock->GetGuid(aOutTargetGuid);
     result = mInputQueue->ReceiveInputEvent(mApzcForInputBlock,
         /* aTargetConfirmed = */ mHitResultForInputBlock == HitLayer,
         aInput, aOutInputBlockId);
 
     // For computing the event to pass back to Gecko, use up-to-date transforms
     // (i.e. not anything cached in an input block).
     // This ensures that transformToApzc and transformToGecko are in sync.
-    Matrix4x4 transformToApzc = GetScreenToApzcTransform(mApzcForInputBlock);
-    Matrix4x4 transformToGecko = GetApzcToGeckoTransform(mApzcForInputBlock);
-    Matrix4x4 outTransform = transformToApzc * transformToGecko;
+    ScreenToParentLayerMatrix4x4 transformToApzc = GetScreenToApzcTransform(mApzcForInputBlock);
+    ParentLayerToScreenMatrix4x4 transformToGecko = GetApzcToGeckoTransform(mApzcForInputBlock);
+    ScreenToScreenMatrix4x4 outTransform = transformToApzc * transformToGecko;
     
     for (size_t i = 0; i < aInput.mTouches.Length(); i++) {
       SingleTouchData& touchData = aInput.mTouches[i];
       Maybe<ScreenIntPoint> untransformedScreenPoint = UntransformTo<ScreenPixel>(
           outTransform, touchData.mScreenPoint);
       if (!untransformedScreenPoint) {
         return nsEventStatus_eIgnore;
       }
@@ -1031,28 +1031,29 @@ APZCTreeManager::ProcessEvent(WidgetInpu
   nsEventStatus result = nsEventStatus_eIgnore;
 
   // Note, we call this before having transformed the reference point.
   UpdateWheelTransaction(aEvent);
 
   // Transform the refPoint.
   // If the event hits an overscrolled APZC, instruct the caller to ignore it.
   HitTestResult hitResult = HitNothing;
-  RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(ScreenPoint(aEvent.refPoint.x, aEvent.refPoint.y),
-                                                        &hitResult);
+  PixelCastJustification LDIsScreen = PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent;
+  ScreenIntPoint refPointAsScreen = ViewAs<ScreenPixel>(aEvent.refPoint, LDIsScreen);
+  RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(refPointAsScreen, &hitResult);
   if (apzc) {
     MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion);
     apzc->GetGuid(aOutTargetGuid);
-    Matrix4x4 transformToApzc = GetScreenToApzcTransform(apzc);
-    Matrix4x4 transformToGecko = GetApzcToGeckoTransform(apzc);
-    Matrix4x4 outTransform = transformToApzc * transformToGecko;
-    Maybe<LayoutDeviceIntPoint> untransformedRefPoint =
-      UntransformTo<LayoutDevicePixel>(outTransform, aEvent.refPoint);
+    ScreenToParentLayerMatrix4x4 transformToApzc = GetScreenToApzcTransform(apzc);
+    ParentLayerToScreenMatrix4x4 transformToGecko = GetApzcToGeckoTransform(apzc);
+    ScreenToScreenMatrix4x4 outTransform = transformToApzc * transformToGecko;
+    Maybe<ScreenIntPoint> untransformedRefPoint =
+      UntransformTo<ScreenPixel>(outTransform, refPointAsScreen);
     if (untransformedRefPoint) {
-      aEvent.refPoint = *untransformedRefPoint;
+      aEvent.refPoint = ViewAs<LayoutDevicePixel>(*untransformedRefPoint, LDIsScreen);
     }
   }
   return result;
 }
 
 nsEventStatus
 APZCTreeManager::ProcessMouseEvent(WidgetMouseEventBase& aEvent,
                                    ScrollableLayerGuid* aOutTargetGuid,
@@ -1347,23 +1348,23 @@ TransformDisplacement(APZCTreeManager* a
                       AsyncPanZoomController* aTarget,
                       ParentLayerPoint& aStartPoint,
                       ParentLayerPoint& aEndPoint) {
   if (aSource == aTarget) {
     return true;
   }
 
   // Convert start and end points to Screen coordinates.
-  Matrix4x4 untransformToApzc = aTreeManager->GetScreenToApzcTransform(aSource).Inverse();
+  ParentLayerToScreenMatrix4x4 untransformToApzc = aTreeManager->GetScreenToApzcTransform(aSource).Inverse();
   ScreenPoint screenStart = TransformTo<ScreenPixel>(untransformToApzc, aStartPoint);
   ScreenPoint screenEnd = TransformTo<ScreenPixel>(untransformToApzc, aEndPoint);
 
 
   // Convert start and end points to aTarget's ParentLayer coordinates.
-  Matrix4x4 transformToApzc = aTreeManager->GetScreenToApzcTransform(aTarget);
+  ScreenToParentLayerMatrix4x4 transformToApzc = aTreeManager->GetScreenToApzcTransform(aTarget);
   Maybe<ParentLayerPoint> startPoint = UntransformTo<ParentLayerPixel>(transformToApzc, screenStart);
   Maybe<ParentLayerPoint> endPoint = UntransformTo<ParentLayerPixel>(transformToApzc, screenEnd);
   if (!startPoint || !endPoint) {
     return false;
   }
   aEndPoint = *endPoint;
   aStartPoint = *startPoint;
 
@@ -1844,17 +1845,17 @@ APZCTreeManager::FindRootContentApzcForL
    PD using those internally stored values.
    The APZCs also obviously have LT, LN, PT, and PN, so all of the above transformation combinations
    required can be generated.
  */
 
 /*
  * See the long comment above for a detailed explanation of this function.
  */
-Matrix4x4
+ScreenToParentLayerMatrix4x4
 APZCTreeManager::GetScreenToApzcTransform(const AsyncPanZoomController *aApzc) const
 {
   Matrix4x4 result;
   MonitorAutoLock lock(mTreeLock);
 
   // The comments below assume there is a chain of layers L..R with L and P having APZC instances as
   // explained in the comment above. This function is called with aApzc at L, and the loop
   // below performs one iteration, where parent is at P. The comments explain what values are stored
@@ -1878,24 +1879,24 @@ APZCTreeManager::GetScreenToApzcTransfor
     // result is RC.Inverse() * QC.Inverse() * PA.Inverse() * PC.Inverse() * OC.Inverse() * NC.Inverse() * MC.Inverse()
     result = untransformSinceLastApzc * result;
 
     // The above value for result when parent == P matches the required output
     // as explained in the comment above this method. Note that any missing
     // terms are guaranteed to be identity transforms.
   }
 
-  return result;
+  return ViewAs<ScreenToParentLayerMatrix4x4>(result);
 }
 
 /*
  * See the long comment above GetScreenToApzcTransform() for a detailed
  * explanation of this function.
  */
-Matrix4x4
+ParentLayerToScreenMatrix4x4
 APZCTreeManager::GetApzcToGeckoTransform(const AsyncPanZoomController *aApzc) const
 {
   Matrix4x4 result;
   MonitorAutoLock lock(mTreeLock);
 
   // The comments below assume there is a chain of layers L..R with L and P having APZC instances as
   // explained in the comment above. This function is called with aApzc at L, and the loop
   // below performs one iteration, where parent is at P. The comments explain what values are stored
@@ -1912,17 +1913,17 @@ APZCTreeManager::GetApzcToGeckoTransform
     // aTransformToGeckoOut is LA.Inverse() * LD * MC * NC * OC * PC * PD * QC * RC
     result = result * parent->GetTransformToLastDispatchedPaint() * parent->GetAncestorTransform();
 
     // The above value for result when parent == P matches the required output
     // as explained in the comment above this method. Note that any missing
     // terms are guaranteed to be identity transforms.
   }
 
-  return result;
+  return ViewAs<ParentLayerToScreenMatrix4x4>(result);
 }
 
 already_AddRefed<AsyncPanZoomController>
 APZCTreeManager::GetMultitouchTarget(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const
 {
   MonitorAutoLock lock(mTreeLock);
   RefPtr<AsyncPanZoomController> apzc;
   // For now, we only ever want to do pinching on the root-content APZC for
--- a/gfx/layers/apz/src/APZCTreeManager.h
+++ b/gfx/layers/apz/src/APZCTreeManager.h
@@ -429,18 +429,18 @@ public:
      lock the tree of APZCs while they find the right one, and then return an addref'd
      pointer to it. This allows caller code to just use the target APZC without worrying
      about it going away. These are public for testing code and generally should not be
      used by other production code.
   */
   RefPtr<HitTestingTreeNode> GetRootNode() const;
   already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const ScreenPoint& aPoint,
                                                          HitTestResult* aOutHitResult);
-  gfx::Matrix4x4 GetScreenToApzcTransform(const AsyncPanZoomController *aApzc) const;
-  gfx::Matrix4x4 GetApzcToGeckoTransform(const AsyncPanZoomController *aApzc) const;
+  ScreenToParentLayerMatrix4x4 GetScreenToApzcTransform(const AsyncPanZoomController *aApzc) const;
+  ParentLayerToScreenMatrix4x4 GetApzcToGeckoTransform(const AsyncPanZoomController *aApzc) const;
 private:
   typedef bool (*GuidComparator)(const ScrollableLayerGuid&, const ScrollableLayerGuid&);
 
   /* Helpers */
   void AttachNodeToTree(HitTestingTreeNode* aNode,
                         HitTestingTreeNode* aParent,
                         HitTestingTreeNode* aNextSibling);
   already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const ScrollableLayerGuid& aGuid);
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -1062,17 +1062,17 @@ nsEventStatus AsyncPanZoomController::Ha
   mFrameMetrics.SetScrollOffset(scrollOffset);
   ScheduleCompositeAndMaybeRepaint();
   UpdateSharedCompositorFrameMetrics();
 
   return nsEventStatus_eConsumeNoDefault;
 }
 
 nsEventStatus AsyncPanZoomController::HandleInputEvent(const InputData& aEvent,
-                                                       const Matrix4x4& aTransformToApzc) {
+                                                       const ScreenToParentLayerMatrix4x4& aTransformToApzc) {
   APZThreadUtils::AssertOnControllerThread();
 
   nsEventStatus rv = nsEventStatus_eIgnore;
 
   switch (aEvent.mInputType) {
   case MULTITOUCH_INPUT: {
     MultiTouchInput multiTouchInput = aEvent.AsMultiTouchInput();
     if (!multiTouchInput.TransformToLocal(aTransformToApzc)) {
@@ -1545,30 +1545,33 @@ nsEventStatus AsyncPanZoomController::On
 
   return nsEventStatus_eConsumeNoDefault;
 }
 
 bool
 AsyncPanZoomController::ConvertToGecko(const ScreenIntPoint& aPoint, CSSPoint* aOut)
 {
   if (APZCTreeManager* treeManagerLocal = GetApzcTreeManager()) {
-    Matrix4x4 transformScreenToGecko = treeManagerLocal->GetScreenToApzcTransform(this) 
-                                     * treeManagerLocal->GetApzcToGeckoTransform(this);
+    ScreenToScreenMatrix4x4 transformScreenToGecko =
+        treeManagerLocal->GetScreenToApzcTransform(this)
+      * treeManagerLocal->GetApzcToGeckoTransform(this);
     
-    // NOTE: This isn't *quite* LayoutDevicePoint, we just don't have a name
-    // for this coordinate space and it maps the closest to LayoutDevicePoint.
-    Maybe<LayoutDeviceIntPoint> layoutPoint = UntransformTo<LayoutDevicePixel>(
+    Maybe<ScreenIntPoint> layoutPoint = UntransformTo<ScreenPixel>(
         transformScreenToGecko, aPoint);
     if (!layoutPoint) {
       return false;
     }
 
     { // scoped lock to access mFrameMetrics
       ReentrantMonitorAutoEnter lock(mMonitor);
-      *aOut = LayoutDevicePoint(*layoutPoint) / mFrameMetrics.GetDevPixelsPerCSSPixel();
+      // NOTE: This isn't *quite* LayoutDevicePoint, we just don't have a name
+      // for this coordinate space and it maps the closest to LayoutDevicePoint.
+      *aOut = LayoutDevicePoint(ViewAs<LayoutDevicePixel>(*layoutPoint,
+                  PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent))
+            / mFrameMetrics.GetDevPixelsPerCSSPixel();
     }
     return true;
   }
   return false;
 }
 
 ParentLayerPoint
 AsyncPanZoomController::GetScrollWheelDelta(const ScrollWheelInput& aEvent) const
@@ -2042,37 +2045,37 @@ nsEventStatus AsyncPanZoomController::On
 
 nsEventStatus AsyncPanZoomController::OnCancelTap(const TapGestureInput& aEvent) {
   APZC_LOG("%p got a cancel-tap in state %d\n", this, mState);
   // XXX: Implement this.
   return nsEventStatus_eIgnore;
 }
 
 
-Matrix4x4 AsyncPanZoomController::GetTransformToThis() const {
+ScreenToParentLayerMatrix4x4 AsyncPanZoomController::GetTransformToThis() const {
   if (APZCTreeManager* treeManagerLocal = GetApzcTreeManager()) {
     return treeManagerLocal->GetScreenToApzcTransform(this);
   }
-  return Matrix4x4();
+  return ScreenToParentLayerMatrix4x4();
 }
 
 ScreenPoint AsyncPanZoomController::ToScreenCoordinates(const ParentLayerPoint& aVector,
                                                         const ParentLayerPoint& aAnchor) const {
   return TransformVector<ScreenPixel>(GetTransformToThis().Inverse(), aVector, aAnchor);
 }
 
 // TODO: figure out a good way to check the w-coordinate is positive and return the result
 ParentLayerPoint AsyncPanZoomController::ToParentLayerCoordinates(const ScreenPoint& aVector,
                                                                   const ScreenPoint& aAnchor) const {
   return TransformVector<ParentLayerPixel>(GetTransformToThis(), aVector, aAnchor);
 }
 
 bool AsyncPanZoomController::Contains(const ScreenIntPoint& aPoint) const
 {
-  Matrix4x4 transformToThis = GetTransformToThis();
+  ScreenToParentLayerMatrix4x4 transformToThis = GetTransformToThis();
   Maybe<ParentLayerIntPoint> point = UntransformTo<ParentLayerPixel>(transformToThis, aPoint);
   if (!point) {
     return false;
   }
 
   ParentLayerIntRect cb;
   {
     ReentrantMonitorAutoEnter lock(mMonitor);
--- a/gfx/layers/apz/src/AsyncPanZoomController.h
+++ b/gfx/layers/apz/src/AsyncPanZoomController.h
@@ -274,17 +274,17 @@ public:
 
   nsEventStatus HandleDragEvent(const MouseInput& aEvent,
                                 const AsyncDragMetrics& aDragMetrics);
 
   /**
    * Handler for events which should not be intercepted by the touch listener.
    */
   nsEventStatus HandleInputEvent(const InputData& aEvent,
-                                 const Matrix4x4& aTransformToApzc);
+                                 const ScreenToParentLayerMatrix4x4& aTransformToApzc);
 
   /**
    * Handler for gesture events.
    * Currently some gestures are detected in GestureEventListener that calls
    * APZC back through this handler in order to avoid recursive calls to
    * APZC::HandleInputEvent() which is supposed to do the work for
    * ReceiveInputEvent().
    */
@@ -350,17 +350,17 @@ public:
   int32_t GetLastTouchIdentifier() const;
 
   /**
    * Returns the matrix that transforms points from global screen space into
    * this APZC's ParentLayer space.
    * To respect the lock ordering, mMonitor must NOT be held when calling
    * this function (since this function acquires the tree lock).
    */
-  Matrix4x4 GetTransformToThis() const;
+  ScreenToParentLayerMatrix4x4 GetTransformToThis() const;
 
   /**
    * Convert the vector |aVector|, rooted at the point |aAnchor|, from
    * this APZC's ParentLayer coordinates into screen coordinates.
    * The anchor is necessary because with 3D tranforms, the location of the
    * vector can affect the result of the transform.
    * To respect the lock ordering, mMonitor must NOT be held when calling
    * this function (since this function acquires the tree lock).
--- a/gfx/layers/apz/src/HitTestingTreeNode.cpp
+++ b/gfx/layers/apz/src/HitTestingTreeNode.cpp
@@ -226,17 +226,18 @@ HitTestingTreeNode::IsOutsideClip(const 
 Maybe<LayerPoint>
 HitTestingTreeNode::Untransform(const ParentLayerPoint& aPoint) const
 {
   // convert into Layer coordinate space
   gfx::Matrix4x4 localTransform = mTransform;
   if (mApzc) {
     localTransform = localTransform * mApzc->GetCurrentAsyncTransformWithOverscroll();
   }
-  return UntransformTo<LayerPixel>(localTransform.Inverse(), aPoint);
+  return UntransformTo<LayerPixel>(
+      ViewAs<LayerToParentLayerMatrix4x4>(localTransform).Inverse(), aPoint);
 }
 
 HitTestResult
 HitTestingTreeNode::HitTest(const ParentLayerPoint& aPoint) const
 {
   // This should only ever get called if the point is inside the clip region
   // for this node.
   MOZ_ASSERT(!IsOutsideClip(aPoint));
--- a/gfx/layers/apz/src/InputBlockState.cpp
+++ b/gfx/layers/apz/src/InputBlockState.cpp
@@ -54,17 +54,17 @@ InputBlockState::SetConfirmedTargetApzc(
   return true;
 }
 
 void
 InputBlockState::UpdateTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc)
 {
   // note that aTargetApzc MAY be null here.
   mTargetApzc = aTargetApzc;
-  mTransformToApzc = aTargetApzc ? aTargetApzc->GetTransformToThis() : gfx::Matrix4x4();
+  mTransformToApzc = aTargetApzc ? aTargetApzc->GetTransformToThis() : ScreenToParentLayerMatrix4x4();
   mOverscrollHandoffChain = (mTargetApzc ? mTargetApzc->BuildOverscrollHandoffChain() : nullptr);
 }
 
 const RefPtr<AsyncPanZoomController>&
 InputBlockState::GetTargetApzc() const
 {
   return mTargetApzc;
 }
--- a/gfx/layers/apz/src/InputBlockState.h
+++ b/gfx/layers/apz/src/InputBlockState.h
@@ -56,17 +56,17 @@ private:
   bool mTargetConfirmed;
   const uint64_t mBlockId;
 protected:
   RefPtr<const OverscrollHandoffChain> mOverscrollHandoffChain;
 
   // Used to transform events from global screen space to |mTargetApzc|'s
   // screen space. It's cached at the beginning of the input block so that
   // all events in the block are in the same coordinate space.
-  gfx::Matrix4x4 mTransformToApzc;
+  ScreenToParentLayerMatrix4x4 mTransformToApzc;
 };
 
 /**
  * This class represents a set of events that can be cancelled by web content
  * via event listeners.
  *
  * Each cancelable input block can be cancelled by web content, and
  * this information is stored in the mPreventDefault flag. Because web
--- a/gfx/layers/apz/test/gtest/TestAsyncPanZoomController.cpp
+++ b/gfx/layers/apz/test/gtest/TestAsyncPanZoomController.cpp
@@ -2178,18 +2178,18 @@ protected:
     regions.mDispatchToContentHitRegion = regions.mHitRegion;
     layers[0]->SetEventRegions(regions);
     layers[1]->SetEventRegions(regions);
   }
 };
 
 class APZHitTestingTester : public APZCTreeManagerTester {
 protected:
-  Matrix4x4 transformToApzc;
-  Matrix4x4 transformToGecko;
+  ScreenToParentLayerMatrix4x4 transformToApzc;
+  ParentLayerToScreenMatrix4x4 transformToGecko;
 
   already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const ScreenPoint& aPoint) {
     RefPtr<AsyncPanZoomController> hit = manager->GetTargetAPZC(aPoint, nullptr);
     if (hit) {
       transformToApzc = manager->GetScreenToApzcTransform(hit.get());
       transformToGecko = manager->GetApzcToGeckoTransform(hit.get());
     }
     return hit.forget();
@@ -2272,70 +2272,70 @@ protected:
 TEST_F(APZHitTestingTester, HitTesting1) {
   CreateHitTesting1LayerTree();
   ScopedLayerTreeRegistration registration(manager, 0, root, mcc);
 
   // No APZC attached so hit testing will return no APZC at (20,20)
   RefPtr<AsyncPanZoomController> hit = GetTargetAPZC(ScreenPoint(20, 20));
   TestAsyncPanZoomController* nullAPZC = nullptr;
   EXPECT_EQ(nullAPZC, hit.get());
-  EXPECT_EQ(Matrix4x4(), transformToApzc);
-  EXPECT_EQ(Matrix4x4(), transformToGecko);
+  EXPECT_EQ(ScreenToParentLayerMatrix4x4(), transformToApzc);
+  EXPECT_EQ(ParentLayerToScreenMatrix4x4(), transformToGecko);
 
   uint32_t paintSequenceNumber = 0;
 
   // Now we have a root APZC that will match the page
   SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID);
   manager->UpdateHitTestingTree(nullptr, root, false, 0, paintSequenceNumber++);
   hit = GetTargetAPZC(ScreenPoint(15, 15));
   EXPECT_EQ(ApzcOf(root), hit.get());
   // expect hit point at LayerIntPoint(15, 15)
-  EXPECT_EQ(Point(15, 15), transformToApzc * Point(15, 15));
-  EXPECT_EQ(Point(15, 15), transformToGecko * Point(15, 15));
+  EXPECT_EQ(ParentLayerPoint(15, 15), transformToApzc * ScreenPoint(15, 15));
+  EXPECT_EQ(ScreenPoint(15, 15), transformToGecko * ParentLayerPoint(15, 15));
 
   // Now we have a sub APZC with a better fit
   SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 1);
   manager->UpdateHitTestingTree(nullptr, root, false, 0, paintSequenceNumber++);
   EXPECT_NE(ApzcOf(root), ApzcOf(layers[3]));
   hit = GetTargetAPZC(ScreenPoint(25, 25));
   EXPECT_EQ(ApzcOf(layers[3]), hit.get());
   // expect hit point at LayerIntPoint(25, 25)
-  EXPECT_EQ(Point(25, 25), transformToApzc * Point(25, 25));
-  EXPECT_EQ(Point(25, 25), transformToGecko * Point(25, 25));
+  EXPECT_EQ(ParentLayerPoint(25, 25), transformToApzc * ScreenPoint(25, 25));
+  EXPECT_EQ(ScreenPoint(25, 25), transformToGecko * ParentLayerPoint(25, 25));
 
   // At this point, layers[4] obscures layers[3] at the point (15, 15) so
   // hitting there should hit the root APZC
   hit = GetTargetAPZC(ScreenPoint(15, 15));
   EXPECT_EQ(ApzcOf(root), hit.get());
 
   // Now test hit testing when we have two scrollable layers
   SetScrollableFrameMetrics(layers[4], FrameMetrics::START_SCROLL_ID + 2);
   manager->UpdateHitTestingTree(nullptr, root, false, 0, paintSequenceNumber++);
   hit = GetTargetAPZC(ScreenPoint(15, 15));
   EXPECT_EQ(ApzcOf(layers[4]), hit.get());
   // expect hit point at LayerIntPoint(15, 15)
-  EXPECT_EQ(Point(15, 15), transformToApzc * Point(15, 15));
-  EXPECT_EQ(Point(15, 15), transformToGecko * Point(15, 15));
+  EXPECT_EQ(ParentLayerPoint(15, 15), transformToApzc * ScreenPoint(15, 15));
+  EXPECT_EQ(ScreenPoint(15, 15), transformToGecko * ParentLayerPoint(15, 15));
 
   // Hit test ouside the reach of layer[3,4] but inside root
   hit = GetTargetAPZC(ScreenPoint(90, 90));
   EXPECT_EQ(ApzcOf(root), hit.get());
   // expect hit point at LayerIntPoint(90, 90)
-  EXPECT_EQ(Point(90, 90), transformToApzc * Point(90, 90));
-  EXPECT_EQ(Point(90, 90), transformToGecko * Point(90, 90));
+  EXPECT_EQ(ParentLayerPoint(90, 90), transformToApzc * ScreenPoint(90, 90));
+  EXPECT_EQ(ScreenPoint(90, 90), transformToGecko * ParentLayerPoint(90, 90));
 
   // Hit test ouside the reach of any layer
   hit = GetTargetAPZC(ScreenPoint(1000, 10));
   EXPECT_EQ(nullAPZC, hit.get());
-  EXPECT_EQ(Matrix4x4(), transformToApzc);
-  EXPECT_EQ(Matrix4x4(), transformToGecko);
+  EXPECT_EQ(ScreenToParentLayerMatrix4x4(), transformToApzc);
+  EXPECT_EQ(ParentLayerToScreenMatrix4x4(), transformToGecko);
   hit = GetTargetAPZC(ScreenPoint(-1000, 10));
   EXPECT_EQ(nullAPZC, hit.get());
-  EXPECT_EQ(Matrix4x4(), transformToApzc);
-  EXPECT_EQ(Matrix4x4(), transformToGecko);
+  EXPECT_EQ(ScreenToParentLayerMatrix4x4(), transformToApzc);
+  EXPECT_EQ(ParentLayerToScreenMatrix4x4(), transformToGecko);
 }
 
 // A more involved hit testing test that involves css and async transforms.
 TEST_F(APZHitTestingTester, HitTesting2) {
   CreateHitTesting2LayerTree();
   ScopedLayerTreeRegistration registration(manager, 0, root, mcc);
 
   manager->UpdateHitTestingTree(nullptr, root, false, 0, 0);
@@ -2348,107 +2348,107 @@ TEST_F(APZHitTestingTester, HitTesting2)
 
   TestAsyncPanZoomController* apzcroot = ApzcOf(root);
   TestAsyncPanZoomController* apzc1 = ApzcOf(layers[1]);
   TestAsyncPanZoomController* apzc3 = ApzcOf(layers[3]);
 
   // Hit an area that's clearly on the root layer but not any of the child layers.
   RefPtr<AsyncPanZoomController> hit = GetTargetAPZC(ScreenPoint(75, 25));
   EXPECT_EQ(apzcroot, hit.get());
-  EXPECT_EQ(Point(75, 25), transformToApzc * Point(75, 25));
-  EXPECT_EQ(Point(75, 25), transformToGecko * Point(75, 25));
+  EXPECT_EQ(ParentLayerPoint(75, 25), transformToApzc * ScreenPoint(75, 25));
+  EXPECT_EQ(ScreenPoint(75, 25), transformToGecko * ParentLayerPoint(75, 25));
 
   // Hit an area on the root that would be on layers[3] if layers[2]
   // weren't transformed.
   // Note that if layers[2] were scrollable, then this would hit layers[2]
   // because its composition bounds would be at (10,60)-(50,100) (and the
   // scale-only transform that we set on layers[2] would be invalid because
   // it would place the layer into overscroll, as its composition bounds
   // start at x=10 but its content at x=20).
   hit = GetTargetAPZC(ScreenPoint(15, 75));
   EXPECT_EQ(apzcroot, hit.get());
-  EXPECT_EQ(Point(15, 75), transformToApzc * Point(15, 75));
-  EXPECT_EQ(Point(15, 75), transformToGecko * Point(15, 75));
+  EXPECT_EQ(ParentLayerPoint(15, 75), transformToApzc * ScreenPoint(15, 75));
+  EXPECT_EQ(ScreenPoint(15, 75), transformToGecko * ParentLayerPoint(15, 75));
 
   // Hit an area on layers[1].
   hit = GetTargetAPZC(ScreenPoint(25, 25));
   EXPECT_EQ(apzc1, hit.get());
-  EXPECT_EQ(Point(25, 25), transformToApzc * Point(25, 25));
-  EXPECT_EQ(Point(25, 25), transformToGecko * Point(25, 25));
+  EXPECT_EQ(ParentLayerPoint(25, 25), transformToApzc * ScreenPoint(25, 25));
+  EXPECT_EQ(ScreenPoint(25, 25), transformToGecko * ParentLayerPoint(25, 25));
 
   // Hit an area on layers[3].
   hit = GetTargetAPZC(ScreenPoint(25, 75));
   EXPECT_EQ(apzc3, hit.get());
   // transformToApzc should unapply layers[2]'s transform
-  EXPECT_EQ(Point(12.5, 75), transformToApzc * Point(25, 75));
+  EXPECT_EQ(ParentLayerPoint(12.5, 75), transformToApzc * ScreenPoint(25, 75));
   // and transformToGecko should reapply it
-  EXPECT_EQ(Point(25, 75), transformToGecko * Point(12.5, 75));
+  EXPECT_EQ(ScreenPoint(25, 75), transformToGecko * ParentLayerPoint(12.5, 75));
 
   // Hit an area on layers[3] that would be on the root if layers[2]
   // weren't transformed.
   hit = GetTargetAPZC(ScreenPoint(75, 75));
   EXPECT_EQ(apzc3, hit.get());
   // transformToApzc should unapply layers[2]'s transform
-  EXPECT_EQ(Point(37.5, 75), transformToApzc * Point(75, 75));
+  EXPECT_EQ(ParentLayerPoint(37.5, 75), transformToApzc * ScreenPoint(75, 75));
   // and transformToGecko should reapply it
-  EXPECT_EQ(Point(75, 75), transformToGecko * Point(37.5, 75));
+  EXPECT_EQ(ScreenPoint(75, 75), transformToGecko * ParentLayerPoint(37.5, 75));
 
   // Pan the root layer upward by 50 pixels.
   // This causes layers[1] to scroll out of view, and an async transform
   // of -50 to be set on the root layer.
   EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(1);
 
   // This first pan will move the APZC by 50 pixels, and dispatch a paint request.
   // Since this paint request is in the queue to Gecko, transformToGecko will
   // take it into account.
   ApzcPanNoFling(apzcroot, mcc, 100, 50);
 
   // Hit where layers[3] used to be. It should now hit the root.
   hit = GetTargetAPZC(ScreenPoint(75, 75));
   EXPECT_EQ(apzcroot, hit.get());
   // transformToApzc doesn't unapply the root's own async transform
-  EXPECT_EQ(Point(75, 75), transformToApzc * Point(75, 75));
+  EXPECT_EQ(ParentLayerPoint(75, 75), transformToApzc * ScreenPoint(75, 75));
   // and transformToGecko unapplies it and then reapplies it, because by the
   // time the event being transformed reaches Gecko the new paint request will
   // have been handled.
-  EXPECT_EQ(Point(75, 75), transformToGecko * Point(75, 75));
+  EXPECT_EQ(ScreenPoint(75, 75), transformToGecko * ParentLayerPoint(75, 75));
 
   // Hit where layers[1] used to be and where layers[3] should now be.
   hit = GetTargetAPZC(ScreenPoint(25, 25));
   EXPECT_EQ(apzc3, hit.get());
   // transformToApzc unapplies both layers[2]'s css transform and the root's
   // async transform
-  EXPECT_EQ(Point(12.5, 75), transformToApzc * Point(25, 25));
+  EXPECT_EQ(ParentLayerPoint(12.5, 75), transformToApzc * ScreenPoint(25, 25));
   // transformToGecko reapplies both the css transform and the async transform
   // because we have already issued a paint request with it.
-  EXPECT_EQ(Point(25, 25), transformToGecko * Point(12.5, 75));
+  EXPECT_EQ(ScreenPoint(25, 25), transformToGecko * ParentLayerPoint(12.5, 75));
 
   // This second pan will move the APZC by another 50 pixels but since the paint
   // request dispatched above has not "completed", we will not dispatch another
   // one yet. Now we have an async transform on top of the pending paint request
   // transform.
   ApzcPanNoFling(apzcroot, mcc, 100, 50);
 
   // Hit where layers[3] used to be. It should now hit the root.
   hit = GetTargetAPZC(ScreenPoint(75, 75));
   EXPECT_EQ(apzcroot, hit.get());
   // transformToApzc doesn't unapply the root's own async transform
-  EXPECT_EQ(Point(75, 75), transformToApzc * Point(75, 75));
+  EXPECT_EQ(ParentLayerPoint(75, 75), transformToApzc * ScreenPoint(75, 75));
   // transformToGecko unapplies the full async transform of -100 pixels, and then
   // reapplies the "D" transform of -50 leading to an overall adjustment of +50
-  EXPECT_EQ(Point(75, 125), transformToGecko * Point(75, 75));
+  EXPECT_EQ(ScreenPoint(75, 125), transformToGecko * ParentLayerPoint(75, 75));
 
   // Hit where layers[1] used to be. It should now hit the root.
   hit = GetTargetAPZC(ScreenPoint(25, 25));
   EXPECT_EQ(apzcroot, hit.get());
   // transformToApzc doesn't unapply the root's own async transform
-  EXPECT_EQ(Point(25, 25), transformToApzc * Point(25, 25));
+  EXPECT_EQ(ParentLayerPoint(25, 25), transformToApzc * ScreenPoint(25, 25));
   // transformToGecko unapplies the full async transform of -100 pixels, and then
   // reapplies the "D" transform of -50 leading to an overall adjustment of +50
-  EXPECT_EQ(Point(25, 75), transformToGecko * Point(25, 25));
+  EXPECT_EQ(ScreenPoint(25, 75), transformToGecko * ParentLayerPoint(25, 25));
 }
 
 TEST_F(APZCTreeManagerTester, ScrollablePaintedLayers) {
   CreateSimpleMultiLayerTree();
   ScopedLayerTreeRegistration registration(manager, 0, root, mcc);
 
   // both layers have the same scrollId
   SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID);
--- a/gfx/layers/client/ClientTiledPaintedLayer.cpp
+++ b/gfx/layers/client/ClientTiledPaintedLayer.cpp
@@ -51,22 +51,24 @@ ClientTiledPaintedLayer::ClearCachedReso
 
 void
 ClientTiledPaintedLayer::FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
 {
   aAttrs = PaintedLayerAttributes(GetValidRegion());
 }
 
 static Maybe<LayerRect>
-ApplyParentLayerToLayerTransform(const gfx::Matrix4x4& aTransform, const ParentLayerRect& aParentLayerRect, const LayerRect& aClip)
+ApplyParentLayerToLayerTransform(const ParentLayerToLayerMatrix4x4& aTransform,
+                                 const ParentLayerRect& aParentLayerRect,
+                                 const LayerRect& aClip)
 {
   return UntransformTo<LayerPixel>(aTransform, aParentLayerRect, aClip);
 }
 
-static gfx::Matrix4x4
+static LayerToParentLayerMatrix4x4
 GetTransformToAncestorsParentLayer(Layer* aStart, const LayerMetricsWrapper& aAncestor)
 {
   gfx::Matrix4x4 transform;
   const LayerMetricsWrapper& ancestorParent = aAncestor.GetParent();
   for (LayerMetricsWrapper iter(aStart, LayerMetricsWrapper::StartAt::BOTTOM);
        ancestorParent ? iter != ancestorParent : iter.IsValid();
        iter = iter.GetParent()) {
     transform = transform * iter.GetTransform();
@@ -81,17 +83,17 @@ GetTransformToAncestorsParentLayer(Layer
       //
       // With containerless scrolling, the offending post-scale is on the
       // parent layer of the displayport-ancestor, which we don't reach in this
       // loop, so we don't need to worry about it.
       const FrameMetrics& metrics = iter.Metrics();
       transform.PostScale(metrics.GetPresShellResolution(), metrics.GetPresShellResolution(), 1.f);
     }
   }
-  return transform;
+  return ViewAs<LayerToParentLayerMatrix4x4>(transform);
 }
 
 void
 ClientTiledPaintedLayer::GetAncestorLayers(LayerMetricsWrapper* aOutScrollAncestor,
                                            LayerMetricsWrapper* aOutDisplayPortAncestor,
                                            bool* aOutHasTransformAnimation)
 {
   LayerMetricsWrapper scrollAncestor;
@@ -153,19 +155,18 @@ ClientTiledPaintedLayer::BeginPaint()
   TILING_LOG("TILING %p: Found scrollAncestor %p, displayPortAncestor %p, transform %d\n", this,
     scrollAncestor.GetLayer(), displayPortAncestor.GetLayer(), hasTransformAnimation);
 
   const FrameMetrics& scrollMetrics = scrollAncestor.Metrics();
   const FrameMetrics& displayportMetrics = displayPortAncestor.Metrics();
 
   // Calculate the transform required to convert ParentLayer space of our
   // display port ancestor to the Layer space of this layer.
-  gfx::Matrix4x4 transformDisplayPortToLayer =
-    GetTransformToAncestorsParentLayer(this, displayPortAncestor);
-  transformDisplayPortToLayer.Invert();
+  ParentLayerToLayerMatrix4x4 transformDisplayPortToLayer =
+    GetTransformToAncestorsParentLayer(this, displayPortAncestor).Inverse();
 
   LayerRect layerBounds = ViewAs<LayerPixel>(Rect(GetLayerBounds()));
 
   // Compute the critical display port that applies to this layer in the
   // LayoutDevice space of this layer, but only if there is no OMT animation
   // on this layer. If there is an OMT animation then we need to draw the whole
   // visible region of this layer as determined by layout, because we don't know
   // what parts of it might move into view in the compositor.
@@ -187,18 +188,17 @@ ClientTiledPaintedLayer::BeginPaint()
   // Store the resolution from the displayport ancestor layer. Because this is Gecko-side,
   // before any async transforms have occurred, we can use the zoom for this.
   mPaintData.mResolution = displayportMetrics.GetZoom();
   TILING_LOG("TILING %p: Resolution %s\n", this, Stringify(mPaintData.mResolution).c_str());
 
   // Store the applicable composition bounds in this layer's Layer units.
   mPaintData.mTransformToCompBounds =
     GetTransformToAncestorsParentLayer(this, scrollAncestor);
-  gfx::Matrix4x4 transformToBounds = mPaintData.mTransformToCompBounds;
-  transformToBounds.Invert();
+  ParentLayerToLayerMatrix4x4 transformToBounds = mPaintData.mTransformToCompBounds.Inverse();
   Maybe<LayerRect> compositionBoundsTransformed = ApplyParentLayerToLayerTransform(
     transformToBounds, scrollMetrics.GetCompositionBounds(), layerBounds);
   if (!compositionBoundsTransformed) {
     mPaintData.ResetPaintData();
     return;
   }
   mPaintData.mCompositionBounds = *compositionBoundsTransformed;
   TILING_LOG("TILING %p: Composition bounds %s\n", this, Stringify(mPaintData.mCompositionBounds).c_str());
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -1395,21 +1395,22 @@ ClientMultiTiledLayerBuffer::ValidateTil
  * it reflects what the compositor is actually rendering. This operation
  * basically adds in the layer's async transform.
  * This function then returns the scroll ancestor's composition bounds,
  * transformed into the painted layer's LayerPixel coordinates, accounting
  * for the compositor state.
  */
 static Maybe<LayerRect>
 GetCompositorSideCompositionBounds(const LayerMetricsWrapper& aScrollAncestor,
-                                   const Matrix4x4& aTransformToCompBounds,
+                                   const LayerToParentLayerMatrix4x4& aTransformToCompBounds,
                                    const ViewTransform& aAPZTransform,
                                    const LayerRect& aClip)
 {
-  Matrix4x4 transform = aTransformToCompBounds * Matrix4x4(aAPZTransform);
+  LayerToParentLayerMatrix4x4 transform = aTransformToCompBounds *
+      ViewAs<ParentLayerToParentLayerMatrix4x4>(aAPZTransform);
 
   return UntransformTo<LayerPixel>(transform.Inverse(),
     aScrollAncestor.Metrics().GetCompositionBounds(), aClip);
 }
 
 bool
 ClientMultiTiledLayerBuffer::ComputeProgressiveUpdateRegion(const nsIntRegion& aInvalidRegion,
                                                             const nsIntRegion& aOldValidRegion,
--- a/gfx/layers/client/TiledContentClient.h
+++ b/gfx/layers/client/TiledContentClient.h
@@ -308,17 +308,17 @@ struct BasicTiledLayerPaintData {
   ParentLayerPoint mLastScrollOffset;
 
   /*
    * The transform matrix to go from this layer's Layer units to
    * the scroll ancestor's ParentLayer units. The "scroll ancestor" is
    * the closest ancestor layer which scrolls, and is used to obtain
    * the composition bounds that are relevant for this layer.
    */
-  gfx::Matrix4x4 mTransformToCompBounds;
+  LayerToParentLayerMatrix4x4 mTransformToCompBounds;
 
   /*
    * The critical displayport of the content from the nearest ancestor layer
    * that represents scrollable content with a display port set. Empty if a
    * critical displayport is not set.
    */
   LayerIntRect mCriticalDisplayPort;
 
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -197,17 +197,17 @@ GetBaseTransform(Layer* aLayer, Matrix4x
   *aTransform =
     (aLayer->AsLayerComposite()->GetShadowTransformSetByAnimation()
         ? aLayer->GetLocalTransform()
         : aLayer->GetTransform());
 }
 
 static void
 TransformClipRect(Layer* aLayer,
-                  const Matrix4x4& aTransform)
+                  const ParentLayerToParentLayerMatrix4x4& aTransform)
 {
   MOZ_ASSERT(aTransform.Is2D());
   const Maybe<ParentLayerIntRect>& clipRect = aLayer->AsLayerComposite()->GetShadowClipRect();
   if (clipRect) {
     ParentLayerIntRect transformed = TransformTo<ParentLayerPixel>(aTransform, *clipRect);
     aLayer->AsLayerComposite()->SetShadowClipRect(Some(transformed));
   }
 }
@@ -249,17 +249,18 @@ TranslateShadowLayer(Layer* aLayer,
 
   // Apply the translation to the layer transform.
   layerTransform.PostTranslate(aTranslation.x, aTranslation.y, 0);
 
   SetShadowTransform(aLayer, layerTransform);
   aLayer->AsLayerComposite()->SetShadowTransformSetByAnimation(false);
 
   if (aAdjustClipRect) {
-    TransformClipRect(aLayer, Matrix4x4::Translation(aTranslation.x, aTranslation.y, 0));
+    TransformClipRect(aLayer,
+        ParentLayerToParentLayerMatrix4x4::Translation(aTranslation.x, aTranslation.y, 0));
 
     // If a fixed- or sticky-position layer has a mask layer, that mask should
     // move along with the layer, so apply the translation to the mask layer too.
     if (Layer* maskLayer = aLayer->GetMaskLayer()) {
       TranslateShadowLayer(maskLayer, aTranslation, false);
     }
   }
 }
@@ -462,18 +463,19 @@ AsyncCompositionManager::AlignFixedAndSt
       (oldCumulativeTransform * offsetAnchor.ToUnknownPoint()));
 
   // We want to translate the layer by the difference between |transformedAnchor|
   // and |anchor|. To achieve this, we will add a translation to the layer's
   // transform. This translation will apply on top of the layer's local
   // transform, but |anchor| and |transformedAnchor| are in a coordinate space
   // where the local transform isn't applied yet, so apply it and then subtract
   // to get the desired translation.
-  ParentLayerPoint translation = TransformTo<ParentLayerPixel>(localTransform, transformedAnchor)
-                               - TransformTo<ParentLayerPixel>(localTransform, anchor);
+  auto localTransformTyped = ViewAs<LayerToParentLayerMatrix4x4>(localTransform);
+  ParentLayerPoint translation = TransformTo<ParentLayerPixel>(localTransformTyped, transformedAnchor)
+                               - TransformTo<ParentLayerPixel>(localTransformTyped, anchor);
 
   if (aLayer->GetIsStickyPosition()) {
     // For sticky positioned layers, the difference between the two rectangles
     // defines a pair of translation intervals in each dimension through which
     // the layer should not move relative to the scroll container. To
     // accomplish this, we limit each dimension of the |translation| to that
     // part of it which overlaps those intervals.
     const LayerRect& stickyOuter = aLayer->GetStickyScrollRangeOuter();
@@ -890,17 +892,18 @@ AsyncCompositionManager::ApplyAsyncConte
     mIsFirstPaint = false;
 #endif
 
     // Transform the current local clip by this APZC's async transform. If we're
     // using containerful scrolling, then the clip is not part of the scrolled
     // frame and should not be transformed.
     if (asyncClip && !metrics.UsesContainerScrolling()) {
       MOZ_ASSERT(asyncTransform.Is2D());
-      asyncClip = Some(TransformTo<ParentLayerPixel>(asyncTransform, *asyncClip));
+      asyncClip = Some(TransformTo<ParentLayerPixel>(
+          ViewAs<ParentLayerToParentLayerMatrix4x4>(asyncTransform), *asyncClip));
     }
 
     // Combine the local clip with the ancestor scrollframe clip. This is not
     // included in the async transform above, since the ancestor clip should not
     // move with this APZC.
     if (metrics.HasClipRect()) {
       ParentLayerIntRect clip = metrics.ClipRect();
       if (aLayer->GetParent() && aLayer->GetParent()->GetTransformIsPerspective()) {
@@ -1132,17 +1135,17 @@ ApplyAsyncTransformToScrollbarForContent
 
     compensation = compensation * asyncCompensation;
 
     // We also need to make a corresponding change on the clip rect of all the
     // layers on the ancestor chain from the scrollbar layer up to but not
     // including the layer with the async transform. Otherwise the scrollbar
     // shifts but gets clipped and so appears to flicker.
     for (Layer* ancestor = aScrollbar; ancestor != aContent.GetLayer(); ancestor = ancestor->GetParent()) {
-      TransformClipRect(ancestor, asyncCompensation);
+      TransformClipRect(ancestor, ViewAs<ParentLayerToParentLayerMatrix4x4>(asyncCompensation));
     }
   }
   transform = transform * compensation;
 
   SetShadowTransform(aScrollbar, transform);
 }
 
 static LayerMetricsWrapper
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -303,18 +303,18 @@ LayerManagerComposite::PostProcessLayers
   if (insideClip) {
     visible.AndWith(*insideClip);
   }
   composite->SetShadowVisibleRegion(visible);
 
   // Transform the newly calculated visible region into our parent's space,
   // apply our clip to it (if any), and accumulate it into |aVisibleRegion|
   // for the caller to use.
-  ParentLayerIntRegion visibleParentSpace =
-    TransformTo<ParentLayerPixel>(transform, visible);
+  ParentLayerIntRegion visibleParentSpace = TransformTo<ParentLayerPixel>(
+      ViewAs<LayerToParentLayerMatrix4x4>(transform), visible);
   if (const Maybe<ParentLayerIntRect>& clipRect = composite->GetShadowClipRect()) {
     visibleParentSpace.AndWith(*clipRect);
   }
   aVisibleRegion.OrWith(ViewAs<LayerPixel>(visibleParentSpace,
       PixelCastJustification::MovingDownToChildren));
 
   // If we have a simple transform, then we can add our opaque area into
   // aOpaqueRegion.
--- a/layout/base/UnitTransforms.h
+++ b/layout/base/UnitTransforms.h
@@ -134,123 +134,136 @@ gfx::IntRegionTyped<TargetUnits> ViewAs(
 template <class TypedMatrix>
 TypedMatrix ViewAs(const gfx::Matrix4x4& aMatrix) {
   return TypedMatrix::FromUnknownMatrix(aMatrix);
 }
 
 // Convenience functions for transforming an entity from one strongly-typed
 // coordinate system to another using the provided transformation matrix.
 template <typename TargetUnits, typename SourceUnits>
-static gfx::PointTyped<TargetUnits> TransformTo(const gfx::Matrix4x4& aTransform,
-                                                const gfx::PointTyped<SourceUnits>& aPoint)
+static gfx::PointTyped<TargetUnits>
+TransformTo(const gfx::Matrix4x4Typed<SourceUnits, TargetUnits>& aTransform,
+            const gfx::PointTyped<SourceUnits>& aPoint)
 {
-  return ViewAs<TargetUnits>(aTransform * aPoint.ToUnknownPoint());
+  return aTransform * aPoint;
 }
 template <typename TargetUnits, typename SourceUnits>
-static gfx::IntPointTyped<TargetUnits> TransformTo(const gfx::Matrix4x4& aTransform,
-                                                   const gfx::IntPointTyped<SourceUnits>& aPoint)
+static gfx::IntPointTyped<TargetUnits>
+TransformTo(const gfx::Matrix4x4Typed<SourceUnits, TargetUnits>& aTransform,
+            const gfx::IntPointTyped<SourceUnits>& aPoint)
 {
   return RoundedToInt(TransformTo<TargetUnits>(aTransform, gfx::PointTyped<SourceUnits>(aPoint)));
 }
 template <typename TargetUnits, typename SourceUnits>
-static gfx::RectTyped<TargetUnits> TransformTo(const gfx::Matrix4x4& aTransform,
-                                               const gfx::RectTyped<SourceUnits>& aRect)
+static gfx::RectTyped<TargetUnits>
+TransformTo(const gfx::Matrix4x4Typed<SourceUnits, TargetUnits>& aTransform,
+            const gfx::RectTyped<SourceUnits>& aRect)
 {
-  return ViewAs<TargetUnits>(aTransform.TransformBounds(aRect.ToUnknownRect()));
+  return aTransform.TransformBounds(aRect);
 }
 template <typename TargetUnits, typename SourceUnits>
-static gfx::IntRectTyped<TargetUnits> TransformTo(const gfx::Matrix4x4& aTransform,
-                                                  const gfx::IntRectTyped<SourceUnits>& aRect)
+static gfx::IntRectTyped<TargetUnits>
+TransformTo(const gfx::Matrix4x4Typed<SourceUnits, TargetUnits>& aTransform,
+            const gfx::IntRectTyped<SourceUnits>& aRect)
 {
-  gfx::Rect rect(aRect.ToUnknownRect());
-  return RoundedToInt(ViewAs<TargetUnits>(aTransform.TransformBounds(rect)));
+  return RoundedToInt(TransformTo<TargetUnits>(aTransform, gfx::RectTyped<SourceUnits>(aRect)));
 }
 template <typename TargetUnits, typename SourceUnits>
-static gfx::IntRegionTyped<TargetUnits> TransformTo(const gfx::Matrix4x4& aTransform,
-                                                    const gfx::IntRegionTyped<SourceUnits>& aRegion)
+static gfx::IntRegionTyped<TargetUnits>
+TransformTo(const gfx::Matrix4x4Typed<SourceUnits, TargetUnits>& aTransform,
+            const gfx::IntRegionTyped<SourceUnits>& aRegion)
 {
-  return ViewAs<TargetUnits>(aRegion.ToUnknownRegion().Transform(aTransform));
+  return ViewAs<TargetUnits>(aRegion.ToUnknownRegion().Transform(
+      aTransform.ToUnknownMatrix()));
 }
 
 // Transform |aVector|, which is anchored at |aAnchor|, by the given transform
 // matrix, yielding a point in |TargetUnits|.
 // The anchor is necessary because with 3D tranforms, the location of the
 // vector can affect the result of the transform.
 template <typename TargetUnits, typename SourceUnits>
-static gfx::PointTyped<TargetUnits> TransformVector(const gfx::Matrix4x4& aTransform,
-                                                    const gfx::PointTyped<SourceUnits>& aVector,
-                                                    const gfx::PointTyped<SourceUnits>& aAnchor) {
+static gfx::PointTyped<TargetUnits>
+TransformVector(const gfx::Matrix4x4Typed<SourceUnits, TargetUnits>& aTransform,
+                const gfx::PointTyped<SourceUnits>& aVector,
+                const gfx::PointTyped<SourceUnits>& aAnchor)
+{
   gfx::PointTyped<TargetUnits> transformedStart = TransformTo<TargetUnits>(aTransform, aAnchor);
   gfx::PointTyped<TargetUnits> transformedEnd = TransformTo<TargetUnits>(aTransform, aAnchor + aVector);
   return transformedEnd - transformedStart;
 }
 
 // UntransformTo() and UntransformVector() are like TransformTo() and 
 // TransformVector(), respectively, but are intended for cases where
 // the transformation matrix is the inverse of a 3D projection. When
 // using such transforms, the resulting Point4D is only meaningful
 // if it has a positive w-coordinate. To handle this, these functions
 // return a Maybe object which contains a value if and only if the
 // result is meaningful
 template <typename TargetUnits, typename SourceUnits>
-static Maybe<gfx::PointTyped<TargetUnits>> UntransformTo(const gfx::Matrix4x4& aTransform,
-                                                const gfx::PointTyped<SourceUnits>& aPoint)
+static Maybe<gfx::PointTyped<TargetUnits>>
+UntransformTo(const gfx::Matrix4x4Typed<SourceUnits, TargetUnits>& aTransform,
+              const gfx::PointTyped<SourceUnits>& aPoint)
 {
-  gfx::Point4D point = aTransform.ProjectPoint(aPoint.ToUnknownPoint());
+  gfx::Point4DTyped<TargetUnits> point = aTransform.ProjectPoint(aPoint);
   if (!point.HasPositiveWCoord()) {
     return Nothing();
   }
-  return Some(ViewAs<TargetUnits>(point.As2DPoint()));
+  return Some(point.As2DPoint());
 }
 template <typename TargetUnits, typename SourceUnits>
-static Maybe<gfx::IntPointTyped<TargetUnits>> UntransformTo(const gfx::Matrix4x4& aTransform,
-                                                const gfx::IntPointTyped<SourceUnits>& aPoint)
+static Maybe<gfx::IntPointTyped<TargetUnits>>
+UntransformTo(const gfx::Matrix4x4Typed<SourceUnits, TargetUnits>& aTransform,
+              const gfx::IntPointTyped<SourceUnits>& aPoint)
 {
-  gfx::Point p = aPoint.ToUnknownPoint();
-  gfx::Point4D point = aTransform.ProjectPoint(p);
+  gfx::PointTyped<SourceUnits> p = aPoint;
+  gfx::Point4DTyped<TargetUnits> point = aTransform.ProjectPoint(p);
   if (!point.HasPositiveWCoord()) {
     return Nothing();
   }
-  return Some(RoundedToInt(ViewAs<TargetUnits>(point.As2DPoint())));
+  return Some(RoundedToInt(point.As2DPoint()));
 }
 
 // The versions of UntransformTo() that take a rectangle also take a clip,
 // which represents the bounds within which the target must fall. The
 // result of the transform is intersected with this clip, and is considered
 // meaningful if the intersection is not empty.
 template <typename TargetUnits, typename SourceUnits>
-static Maybe<gfx::RectTyped<TargetUnits>> UntransformTo(const gfx::Matrix4x4& aTransform,
-                                                const gfx::RectTyped<SourceUnits>& aRect,
-                                                const gfx::RectTyped<TargetUnits>& aClip)
+static Maybe<gfx::RectTyped<TargetUnits>>
+UntransformTo(const gfx::Matrix4x4Typed<SourceUnits, TargetUnits>& aTransform,
+              const gfx::RectTyped<SourceUnits>& aRect,
+              const gfx::RectTyped<TargetUnits>& aClip)
 {
-  gfx::Rect rect = aTransform.ProjectRectBounds(aRect.ToUnknownRect(), aClip.ToUnknownRect());
+  gfx::RectTyped<TargetUnits> rect = aTransform.ProjectRectBounds(aRect, aClip);
   if (rect.IsEmpty()) {
     return Nothing();
   }
-  return Some(ViewAs<TargetUnits>(rect));
+  return Some(rect);
 }
 template <typename TargetUnits, typename SourceUnits>
-static Maybe<gfx::IntRectTyped<TargetUnits>> UntransformTo(const gfx::Matrix4x4& aTransform,
-                                                const gfx::IntRectTyped<SourceUnits>& aRect,
-                                                const gfx::IntRectTyped<TargetUnits>& aClip)
+static Maybe<gfx::IntRectTyped<TargetUnits>>
+UntransformTo(const gfx::Matrix4x4Typed<SourceUnits, TargetUnits>& aTransform,
+              const gfx::IntRectTyped<SourceUnits>& aRect,
+              const gfx::IntRectTyped<TargetUnits>& aClip)
 {
-  gfx::Rect rect = aTransform.ProjectRectBounds(aRect.ToUnknownRect(), aClip.ToUnknownRect());
+  gfx::RectTyped<TargetUnits> rect = aTransform.ProjectRectBounds(aRect, aClip);
   if (rect.IsEmpty()) {
     return Nothing();
   }
-  return Some(RoundedToInt(ViewAs<TargetUnits>(rect)));
+  return Some(RoundedToInt(rect));
 }
 
 template <typename TargetUnits, typename SourceUnits>
-static Maybe<gfx::PointTyped<TargetUnits>> UntransformVector(const gfx::Matrix4x4& aTransform,
-                                                    const gfx::PointTyped<SourceUnits>& aVector,
-                                                    const gfx::PointTyped<SourceUnits>& aAnchor) {
-  gfx::Point4D projectedAnchor = aTransform.ProjectPoint(aAnchor.ToUnknownPoint());
-  gfx::Point4D projectedTarget = aTransform.ProjectPoint(aAnchor.ToUnknownPoint() + aVector.ToUnknownPoint());
+static Maybe<gfx::PointTyped<TargetUnits>>
+UntransformVector(const gfx::Matrix4x4Typed<SourceUnits, TargetUnits>& aTransform,
+                  const gfx::PointTyped<SourceUnits>& aVector,
+                  const gfx::PointTyped<SourceUnits>& aAnchor)
+{
+  gfx::Point4DTyped<TargetUnits> projectedAnchor = aTransform.ProjectPoint(aAnchor);
+  gfx::Point4DTyped<TargetUnits> projectedTarget = aTransform.ProjectPoint(aAnchor + aVector);
   if (!projectedAnchor.HasPositiveWCoord() || !projectedTarget.HasPositiveWCoord()){
     return Nothing();
   }
-  return Some(ViewAs<TargetUnits>(projectedTarget.As2DPoint() - projectedAnchor.As2DPoint()));
+  return Some(projectedTarget.As2DPoint() - projectedAnchor.As2DPoint());
 }
 
 } // namespace mozilla
 
 #endif
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -1192,27 +1192,28 @@ nsDisplayListBuilder::RecomputeCurrentAn
 
 void
 nsDisplayListBuilder::AdjustWindowDraggingRegion(nsIFrame* aFrame)
 {
   if (!mWindowDraggingAllowed || !IsForPainting()) {
     return;
   }
 
-  Matrix4x4 referenceFrameToRootReferenceFrame;
+  LayoutDeviceToLayoutDeviceMatrix4x4 referenceFrameToRootReferenceFrame;
 
   // The const_cast is for nsLayoutUtils::GetTransformToAncestor.
   nsIFrame* referenceFrame = const_cast<nsIFrame*>(FindReferenceFrameFor(aFrame));
 
   if (IsInTransform()) {
     // Only support 2d rectilinear transforms. Transform support is needed for
     // the horizontal flip transform that's applied to the urlbar textbox in
     // RTL mode - it should be able to exclude itself from the draggable region.
     referenceFrameToRootReferenceFrame =
-      nsLayoutUtils::GetTransformToAncestor(referenceFrame, mReferenceFrame);
+      ViewAs<LayoutDeviceToLayoutDeviceMatrix4x4>(
+          nsLayoutUtils::GetTransformToAncestor(referenceFrame, mReferenceFrame));
     Matrix referenceFrameToRootReferenceFrame2d;
     if (!referenceFrameToRootReferenceFrame.Is2D(&referenceFrameToRootReferenceFrame2d) ||
         !referenceFrameToRootReferenceFrame2d.IsRectilinear()) {
       return;
     }
   } else {
     MOZ_ASSERT(referenceFrame == mReferenceFrame,
                "referenceFrameToRootReferenceFrame needs to be adjusted");
--- a/widget/InputData.cpp
+++ b/widget/InputData.cpp
@@ -67,17 +67,17 @@ MouseInput::MouseInput(const WidgetMouse
       break;
     default:
       MOZ_ASSERT_UNREACHABLE("Mouse event type not supported");
       break;
   }
 }
 
 bool
-MouseInput::TransformToLocal(const gfx::Matrix4x4& aTransform)
+MouseInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform)
 {
   Maybe<ParentLayerPoint> point = UntransformTo<ParentLayerPixel>(aTransform, mOrigin);
   if (!point) {
     return false;
   }
   mLocalOrigin = *point;
 
   return true;
@@ -265,17 +265,17 @@ MultiTouchInput::MultiTouchInput(const W
                                          ViewAs<ScreenPixel>(aMouseEvent.refPoint,
                                                              PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent),
                                          ScreenSize(1, 1),
                                          180.0f,
                                          1.0f));
 }
 
 bool
-MultiTouchInput::TransformToLocal(const gfx::Matrix4x4& aTransform)
+MultiTouchInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform)
 {
   for (size_t i = 0; i < mTouches.Length(); i++) {
     Maybe<ParentLayerIntPoint> point = UntransformTo<ParentLayerPixel>(aTransform, mTouches[i].mScreenPoint);
     if (!point) { 
       return false;
     }
     mTouches[i].mLocalScreenPoint = *point;
   }
@@ -312,45 +312,45 @@ PanGestureInput::ToWidgetWheelEvent(nsIW
   wheelEvent.lineOrPageDeltaY = mLineOrPageDeltaY;
   wheelEvent.deltaX = mPanDisplacement.x;
   wheelEvent.deltaY = mPanDisplacement.y;
   wheelEvent.mFlags.mHandledByAPZ = mHandledByAPZ;
   return wheelEvent;
 }
 
 bool
-PanGestureInput::TransformToLocal(const gfx::Matrix4x4& aTransform)
+PanGestureInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform)
 { 
   Maybe<ParentLayerPoint> panStartPoint = UntransformTo<ParentLayerPixel>(aTransform, mPanStartPoint);
   if (!panStartPoint) {
     return false;
   }
   mLocalPanStartPoint = *panStartPoint;
   
   Maybe<ParentLayerPoint> panDisplacement = UntransformVector<ParentLayerPixel>(aTransform, mPanDisplacement, mPanStartPoint);
   if (!panDisplacement) {
     return false;
   }
   mLocalPanDisplacement = *panDisplacement;
   return true;
 }
 
 bool
-PinchGestureInput::TransformToLocal(const gfx::Matrix4x4& aTransform)
+PinchGestureInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform)
 { 
   Maybe<ParentLayerPoint> point = UntransformTo<ParentLayerPixel>(aTransform, mFocusPoint);
   if (!point) {
     return false;
   }
   mLocalFocusPoint = *point;
   return true;
 }
 
 bool
-TapGestureInput::TransformToLocal(const gfx::Matrix4x4& aTransform)
+TapGestureInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform)
 {
   Maybe<ParentLayerIntPoint> point = UntransformTo<ParentLayerPixel>(aTransform, mPoint);
   if (!point) {
     return false;
   }
   mLocalPoint = *point;
   return true;
 }
@@ -404,17 +404,17 @@ ScrollWheelInput::ToWidgetWheelEvent(nsI
   wheelEvent.deltaY = mDeltaY;
   wheelEvent.lineOrPageDeltaX = mLineOrPageDeltaX;
   wheelEvent.lineOrPageDeltaY = mLineOrPageDeltaY;
   wheelEvent.mFlags.mHandledByAPZ = mHandledByAPZ;
   return wheelEvent;
 }
 
 bool
-ScrollWheelInput::TransformToLocal(const gfx::Matrix4x4& aTransform)
+ScrollWheelInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform)
 {
   Maybe<ParentLayerPoint> point = UntransformTo<ParentLayerPixel>(aTransform, mOrigin);
   if (!point) {
     return false;
   }
   mLocalOrigin = *point;
   return true;
 }
--- a/widget/InputData.h
+++ b/widget/InputData.h
@@ -237,17 +237,17 @@ public:
   // This conversion from WidgetMouseEvent to MultiTouchInput is needed because
   // on the B2G emulator we can only receive mouse events, but we need to be
   // able to pan correctly. To do this, we convert the events into a format that
   // the panning code can handle. This code is very limited and only supports
   // SingleTouchData. It also sends garbage for the identifier, radius, force
   // and rotation angle.
   explicit MultiTouchInput(const WidgetMouseEvent& aMouseEvent);
 
-  bool TransformToLocal(const gfx::Matrix4x4& aTransform);
+  bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
 
   MultiTouchType mType;
   nsTArray<SingleTouchData> mTouches;
   bool mHandledByAPZ;
 };
 
 class MouseInput : public InputData
 {
@@ -279,17 +279,17 @@ public:
   MouseInput()
     : InputData(MOUSE_INPUT)
   {}
 
   explicit MouseInput(const WidgetMouseEventBase& aMouseEvent);
 
   bool IsLeftButton() const { return mButtonType == LEFT_BUTTON; }
 
-  bool TransformToLocal(const gfx::Matrix4x4& aTransform);
+  bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
 
   MouseType mType;
   ButtonType mButtonType;
   ScreenPoint mOrigin;
   ParentLayerPoint mLocalOrigin;
 };
 
 /**
@@ -361,17 +361,17 @@ public:
       mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection(false)
   {
   }
 
   bool IsMomentum() const;
 
   WidgetWheelEvent ToWidgetWheelEvent(nsIWidget* aWidget) const;
 
-  bool TransformToLocal(const gfx::Matrix4x4& aTransform);
+  bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
 
   PanGestureType mType;
   ScreenPoint mPanStartPoint;
 
   // The delta. This can be non-zero on any type of event.
   ScreenPoint mPanDisplacement;
 
   // Versions of |mPanStartPoint| and |mPanDisplacement| in the local
@@ -438,17 +438,17 @@ public:
     : InputData(PINCHGESTURE_INPUT, aTime, aTimeStamp, aModifiers),
       mType(aType),
       mLocalFocusPoint(aLocalFocusPoint),
       mCurrentSpan(aCurrentSpan),
       mPreviousSpan(aPreviousSpan)
   {
   }
 
-  bool TransformToLocal(const gfx::Matrix4x4& aTransform);
+  bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
 
   PinchGestureType mType;
 
   // Center point of the pinch gesture. That is, if there are two fingers on the
   // screen, it is their midpoint. In the case of more than two fingers, the
   // point is implementation-specific, but can for example be the midpoint
   // between the very first and very last touch. This is in device pixels and
   // are the coordinates on the screen of this midpoint.
@@ -511,17 +511,17 @@ public:
                   const ParentLayerPoint& aLocalPoint,
                   Modifiers aModifiers)
     : InputData(TAPGESTURE_INPUT, aTime, aTimeStamp, aModifiers),
       mType(aType),
       mLocalPoint(aLocalPoint)
   {
   }
 
-  bool TransformToLocal(const gfx::Matrix4x4& aTransform);
+  bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
 
   TapGestureType mType;
 
   // The location of the tap in screen pixels.
   ScreenIntPoint mPoint;
 
   // The location of the tap in the local coordinates of the APZC receiving it.
   // This is set and used by APZ.
@@ -586,17 +586,17 @@ public:
      mUserDeltaMultiplierX(1.0),
      mUserDeltaMultiplierY(1.0),
      mIsMomentum(false)
   {}
 
   explicit ScrollWheelInput(const WidgetWheelEvent& aEvent);
 
   WidgetWheelEvent ToWidgetWheelEvent(nsIWidget* aWidget) const;
-  bool TransformToLocal(const gfx::Matrix4x4& aTransform);
+  bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
 
   bool IsCustomizedByUserPrefs() const;
 
   ScrollDeltaType mDeltaType;
   ScrollMode mScrollMode;
   ScreenPoint mOrigin;
 
   bool mHandledByAPZ;