Bug 1504220 - Move ScrollableLayerGuid, ViewID, ZoomConstraints from FrameMetrics.h r=botond
authorRyan Hunt <rhunt@eqrion.net>
Thu, 01 Nov 2018 15:15:46 -0500
changeset 444295 ad0782d7c503f33cfb554d08dedc96287e1ed3f2
parent 444294 b2b79634580761f4219bd3e9ca3efc544925a6f0
child 444296 73a273670597c16d7c0644cc2d6d9b61c6fe8204
push id34986
push usershindli@mozilla.com
push dateSat, 03 Nov 2018 09:44:53 +0000
treeherdermozilla-central@ef27c14b46bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond
bugs1504220
milestone65.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 1504220 - Move ScrollableLayerGuid, ViewID, ZoomConstraints from FrameMetrics.h r=botond This commit attempts to lower the pain of modifying FrameMetrics.h. It looks like most includes really only want ViewID or ScrollableLayerGuid, so this commit factors them out into a separate header. In the process FrameMetrics::ViewID is changed to ScrollableLayerGuid::ViewID, which personally seems like a better place for it now that we have RepaintRequest. Unfortunately that requires a lot of places to be updated. After this commit there are still a couple of major places that FrameMetrics is included. * nsDisplayList.h * nsIScrollableFrame.h * Layers.h Those are going to be more tricky or impossible to fix so they're not in this commit. Differential Revision: https://phabricator.services.mozilla.com/D10722
dom/base/nsDOMWindowUtils.cpp
dom/base/nsFrameLoader.cpp
dom/ipc/CoalescedInputData.h
dom/ipc/PBrowser.ipdl
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/ipc/TabParent.cpp
gfx/layers/FrameMetrics.cpp
gfx/layers/FrameMetrics.h
gfx/layers/LayerAttributes.h
gfx/layers/LayerMetricsWrapper.h
gfx/layers/Layers.cpp
gfx/layers/Layers.h
gfx/layers/LayersLogging.cpp
gfx/layers/LayersLogging.h
gfx/layers/RepaintRequest.h
gfx/layers/ScrollableLayerGuid.h
gfx/layers/ZoomConstraints.h
gfx/layers/apz/public/APZUpdater.h
gfx/layers/apz/public/GeckoContentController.h
gfx/layers/apz/public/IAPZCTreeManager.h
gfx/layers/apz/public/MetricsSharingController.h
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/src/APZCTreeManager.h
gfx/layers/apz/src/APZUpdater.cpp
gfx/layers/apz/src/AsyncDragMetrics.h
gfx/layers/apz/src/AsyncPanZoomAnimation.h
gfx/layers/apz/src/AsyncPanZoomController.cpp
gfx/layers/apz/src/AsyncPanZoomController.h
gfx/layers/apz/src/AutoscrollAnimation.cpp
gfx/layers/apz/src/FocusState.cpp
gfx/layers/apz/src/FocusState.h
gfx/layers/apz/src/FocusTarget.h
gfx/layers/apz/src/GenericScrollAnimation.cpp
gfx/layers/apz/src/HitTestingTreeNode.cpp
gfx/layers/apz/src/HitTestingTreeNode.h
gfx/layers/apz/src/Overscroll.h
gfx/layers/apz/test/gtest/APZCTreeManagerTester.h
gfx/layers/apz/test/gtest/APZTestCommon.h
gfx/layers/apz/test/gtest/TestBasic.cpp
gfx/layers/apz/test/gtest/TestEventRegions.cpp
gfx/layers/apz/test/gtest/TestHitTesting.cpp
gfx/layers/apz/test/gtest/TestScrollHandoff.cpp
gfx/layers/apz/test/gtest/TestSnapping.cpp
gfx/layers/apz/test/gtest/TestTreeManager.cpp
gfx/layers/apz/testutil/APZTestData.h
gfx/layers/apz/util/APZCCallbackHelper.cpp
gfx/layers/apz/util/APZCCallbackHelper.h
gfx/layers/apz/util/APZEventState.h
gfx/layers/apz/util/ChromeProcessController.cpp
gfx/layers/apz/util/ChromeProcessController.h
gfx/layers/apz/util/ContentProcessController.cpp
gfx/layers/apz/util/ContentProcessController.h
gfx/layers/apz/util/InputAPZContext.h
gfx/layers/client/ClientLayerManager.h
gfx/layers/client/ClientTiledPaintedLayer.cpp
gfx/layers/composite/AsyncCompositionManager.cpp
gfx/layers/composite/AsyncCompositionManager.h
gfx/layers/ipc/APZCTreeManagerChild.cpp
gfx/layers/ipc/APZCTreeManagerChild.h
gfx/layers/ipc/CompositorBridgeChild.cpp
gfx/layers/ipc/CompositorBridgeChild.h
gfx/layers/ipc/CompositorBridgeParent.cpp
gfx/layers/ipc/CompositorBridgeParent.h
gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
gfx/layers/ipc/CrossProcessCompositorBridgeParent.h
gfx/layers/ipc/LayerTransactionParent.cpp
gfx/layers/ipc/LayerTransactionParent.h
gfx/layers/ipc/LayersMessages.ipdlh
gfx/layers/ipc/PAPZ.ipdl
gfx/layers/ipc/PAPZCTreeManager.ipdl
gfx/layers/ipc/PAPZInputBridge.ipdl
gfx/layers/ipc/PCompositorBridge.ipdl
gfx/layers/ipc/PLayerTransaction.ipdl
gfx/layers/ipc/PTexture.ipdl
gfx/layers/ipc/PWebRenderBridge.ipdl
gfx/layers/ipc/RemoteContentController.cpp
gfx/layers/ipc/RemoteContentController.h
gfx/layers/moz.build
gfx/layers/wr/ClipManager.cpp
gfx/layers/wr/WebRenderBridgeParent.cpp
gfx/layers/wr/WebRenderBridgeParent.h
gfx/layers/wr/WebRenderCommandBuilder.cpp
gfx/layers/wr/WebRenderLayerManager.h
gfx/layers/wr/WebRenderScrollData.cpp
gfx/layers/wr/WebRenderScrollData.h
gfx/layers/wr/WebRenderScrollDataWrapper.h
gfx/tests/gtest/TestLayers.cpp
gfx/thebes/gfxPlatform.cpp
gfx/webrender_bindings/WebRenderAPI.cpp
gfx/webrender_bindings/WebRenderAPI.h
gfx/webrender_bindings/WebRenderTypes.h
layout/base/PresShell.cpp
layout/base/ZoomConstraintsClient.cpp
layout/base/ZoomConstraintsClient.h
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/generic/nsFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsGfxScrollFrame.h
layout/generic/nsIScrollableFrame.h
layout/ipc/RenderFrameParent.cpp
layout/ipc/RenderFrameParent.h
layout/painting/nsDisplayList.cpp
layout/painting/nsDisplayList.h
layout/xul/nsSliderFrame.cpp
widget/PuppetWidget.cpp
widget/PuppetWidget.h
widget/android/nsWindow.cpp
widget/android/nsWindow.h
widget/nsBaseWidget.cpp
widget/nsBaseWidget.h
widget/nsIWidget.h
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2532,17 +2532,17 @@ nsDOMWindowUtils::GetAsyncPanZoomEnabled
 
 NS_IMETHODIMP
 nsDOMWindowUtils::SetAsyncScrollOffset(Element* aElement,
                                        float aX, float aY)
 {
   if (!aElement) {
     return NS_ERROR_INVALID_ARG;
   }
-  FrameMetrics::ViewID viewId;
+  ScrollableLayerGuid::ViewID viewId;
   if (!nsLayoutUtils::FindIDFor(aElement, &viewId)) {
     return NS_ERROR_UNEXPECTED;
   }
   nsIWidget* widget = GetWidget();
   if (!widget) {
     return NS_ERROR_FAILURE;
   }
   LayerManager* manager = widget->GetLayerManager();
@@ -2566,17 +2566,17 @@ nsDOMWindowUtils::SetAsyncScrollOffset(E
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::SetAsyncZoom(Element* aRootElement, float aValue)
 {
   if (!aRootElement) {
     return NS_ERROR_INVALID_ARG;
   }
-  FrameMetrics::ViewID viewId;
+  ScrollableLayerGuid::ViewID viewId;
   if (!nsLayoutUtils::FindIDFor(aRootElement, &viewId)) {
     return NS_ERROR_UNEXPECTED;
   }
   nsIWidget* widget = GetWidget();
   if (!widget) {
     return NS_ERROR_FAILURE;
   }
   LayerManager* manager = widget->GetLayerManager();
@@ -2692,17 +2692,17 @@ nsDOMWindowUtils::ZoomToFocusedInput()
   }
 
   nsIDocument* document = shell->GetDocument();
   if (!document) {
     return NS_OK;
   }
 
   uint32_t presShellId;
-  FrameMetrics::ViewID viewId;
+  ScrollableLayerGuid::ViewID viewId;
   if (APZCCallbackHelper::GetOrCreateScrollIdentifiers(document->GetDocumentElement(), &presShellId, &viewId)) {
     uint32_t flags = layers::DISABLE_ZOOM_OUT;
     if (!Preferences::GetBool("formhelper.autozoom")) {
       flags |= layers::PAN_INTO_VIEW_ONLY;
     } else {
       flags |= layers::ONLY_ZOOM_TO_DEFAULT_SCALE;
     }
 
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -120,17 +120,17 @@
 #endif
 
 using namespace mozilla;
 using namespace mozilla::hal;
 using namespace mozilla::dom;
 using namespace mozilla::dom::ipc;
 using namespace mozilla::layers;
 using namespace mozilla::layout;
-typedef FrameMetrics::ViewID ViewID;
+typedef ScrollableLayerGuid::ViewID ViewID;
 
 // Bug 136580: Limit to the number of nested content frames that can have the
 //             same URL. This is to stop content that is recursively loading
 //             itself.  Note that "#foo" on the end of URL doesn't affect
 //             whether it's considered identical, but "?foo" or ";foo" are
 //             considered and compared.
 // Limit this to 2, like chromium does.
 #define MAX_SAME_URL_CONTENT_FRAMES 2
--- a/dom/ipc/CoalescedInputData.h
+++ b/dom/ipc/CoalescedInputData.h
@@ -3,17 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_CoalescedInputData_h
 #define mozilla_dom_CoalescedInputData_h
 
 #include "mozilla/UniquePtr.h"
-#include "FrameMetrics.h"
+#include "mozilla/layers/ScrollableLayerGuid.h"
 
 namespace mozilla {
 namespace dom {
 
 template<class InputEventType>
 class CoalescedInputData
 {
 protected:
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -34,24 +34,23 @@ include "mozilla/layers/LayersMessageUti
 using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h";
 using moveonly mozilla::gfx::PaintFragment from "mozilla/gfx/CrossProcessPaint.h";
 using mozilla::gfx::Matrix from "mozilla/gfx/Matrix.h";
 using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h";
 using mozilla::LayoutDeviceIntPoint from "Units.h";
 using mozilla::LayoutDevicePoint from "Units.h";
 using mozilla::ScreenIntPoint from "Units.h";
 using ScreenIntSize from "Units.h";
-using struct mozilla::layers::FrameMetrics from "FrameMetrics.h";
-using struct mozilla::layers::ScrollableLayerGuid from "FrameMetrics.h";
-using struct mozilla::layers::ZoomConstraints from "FrameMetrics.h";
+using struct mozilla::layers::ScrollableLayerGuid from "mozilla/layers/ScrollableLayerGuid.h";
+using struct mozilla::layers::ZoomConstraints from "mozilla/layers/ZoomConstraints.h";
 using mozilla::layers::LayersId from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::LayersObserverEpoch from "mozilla/layers/LayersTypes.h";
-using mozilla::layers::MaybeZoomConstraints from "FrameMetrics.h";
+using mozilla::layers::MaybeZoomConstraints from "mozilla/layers/ZoomConstraints.h";
 using mozilla::layers::GeckoContentController::TapType from "mozilla/layers/GeckoContentController.h";
-using FrameMetrics::ViewID from "FrameMetrics.h";
+using ScrollableLayerGuid::ViewID from "mozilla/layers/ScrollableLayerGuid.h";
 using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
 using mozilla::WindowsHandle from "ipc/IPCMessageUtils.h";
 using nscolor from "nsColor.h";
 using class mozilla::WidgetCompositionEvent from "ipc/nsGUIEventIPC.h";
 using struct mozilla::widget::IMENotification from "mozilla/widget/IMEData.h";
 using struct mozilla::widget::IMENotificationRequests from "mozilla/widget/IMEData.h";
 using struct mozilla::widget::IMEState from "mozilla/widget/IMEData.h";
 using struct mozilla::widget::InputContext from "mozilla/widget/IMEData.h";
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -99,17 +99,16 @@
 #include "PuppetWidget.h"
 #include "StructuredCloneData.h"
 #include "nsViewportInfo.h"
 #include "nsILoadContext.h"
 #include "ipc/nsGUIEventIPC.h"
 #include "mozilla/gfx/Matrix.h"
 #include "UnitTransforms.h"
 #include "ClientLayerManager.h"
-#include "LayersLogging.h"
 #include "nsColorPickerProxy.h"
 #include "nsContentPermissionHelper.h"
 #include "nsNetUtil.h"
 #include "nsIPermissionManager.h"
 #include "nsIURILoader.h"
 #include "nsIScriptError.h"
 #include "mozilla/EventForwards.h"
 #include "nsDeviceContext.h"
@@ -241,17 +240,17 @@ TabChildBase::DispatchMessageManagerMess
     mm->ReceiveMessage(static_cast<EventTarget*>(kungFuDeathGrip), nullptr,
                        aMessageName, false, &data, nullptr, nullptr, nullptr,
                        IgnoreErrors());
 }
 
 bool
 TabChildBase::UpdateFrameHandler(const RepaintRequest& aRequest)
 {
-  MOZ_ASSERT(aRequest.GetScrollId() != FrameMetrics::NULL_SCROLL_ID);
+  MOZ_ASSERT(aRequest.GetScrollId() != ScrollableLayerGuid::NULL_SCROLL_ID);
 
   if (aRequest.IsRootContent()) {
     if (nsCOMPtr<nsIPresShell> shell = GetPresShell()) {
       // Guard against stale updates (updates meant for a pres shell which
       // has since been torn down and destroyed).
       if (aRequest.GetPresShellId() == shell->GetPresShellId()) {
         ProcessUpdateFrame(aRequest);
         return true;
@@ -1426,17 +1425,17 @@ TabChild::StartScrollbarDrag(const layer
 
   if (mApzcTreeManager) {
     mApzcTreeManager->StartScrollbarDrag(guid, aDragMetrics);
   }
 }
 
 void
 TabChild::ZoomToRect(const uint32_t& aPresShellId,
-                     const FrameMetrics::ViewID& aViewId,
+                     const ScrollableLayerGuid::ViewID& aViewId,
                      const CSSRect& aRect,
                      const uint32_t& aFlags)
 {
   ScrollableLayerGuid guid(mLayersId, aPresShellId, aViewId);
 
   if (mApzcTreeManager) {
     mApzcTreeManager->ZoomToRect(guid, aRect, aFlags);
   }
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -158,17 +158,17 @@ public:
     return mTabChildMessageManager->WrapObject(aCx, aGivenProto);
   }
 
 
   virtual nsIWebNavigation* WebNavigation() const = 0;
   virtual PuppetWidget* WebWidget() = 0;
   nsIPrincipal* GetPrincipal() { return mPrincipal; }
   virtual bool DoUpdateZoomConstraints(const uint32_t& aPresShellId,
-                                       const mozilla::layers::FrameMetrics::ViewID& aViewId,
+                                       const mozilla::layers::ScrollableLayerGuid::ViewID& aViewId,
                                        const Maybe<mozilla::layers::ZoomConstraints>& aConstraints) = 0;
 
   virtual ScreenIntSize GetInnerSize() = 0;
 
   // Get the Document for the top-level window in this tab.
   already_AddRefed<nsIDocument> GetDocument() const;
 
   // Get the pres-shell of the document for the top-level window in this tab.
@@ -636,17 +636,17 @@ public:
                                const nsTArray<TouchBehaviorFlags>& aFlags) const;
 
   bool UpdateFrame(const layers::RepaintRequest& aRequest);
   bool NotifyAPZStateChange(const ViewID& aViewId,
                             const layers::GeckoContentController::APZStateChange& aChange,
                             const int& aArg);
   void StartScrollbarDrag(const layers::AsyncDragMetrics& aDragMetrics);
   void ZoomToRect(const uint32_t& aPresShellId,
-                  const FrameMetrics::ViewID& aViewId,
+                  const ScrollableLayerGuid::ViewID& aViewId,
                   const CSSRect& aRect,
                   const uint32_t& aFlags);
 
   // Request that the docshell be marked as active.
   void PaintWhileInterruptingJS(const layers::LayersObserverEpoch& aEpoch,
                                 bool aForceRepaint);
 
   layers::LayersObserverEpoch LayersObserverEpoch() const { return mLayersObserverEpoch; }
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -2729,17 +2729,17 @@ TabParent::ApzAwareEventRoutingToChild(S
 
       // There may be cases where the APZ hit-testing code came to a different
       // conclusion than the main-thread hit-testing code as to where the event
       // is destined. In such cases the layersId of the APZ result may not match
       // the layersId of this renderframe. In such cases the main-thread hit-
       // testing code "wins" so we need to update the guid to reflect this.
       if (RenderFrameParent* rfp = GetRenderFrame()) {
         if (aOutTargetGuid->mLayersId != rfp->GetLayersId()) {
-          *aOutTargetGuid = ScrollableLayerGuid(rfp->GetLayersId(), 0, FrameMetrics::NULL_SCROLL_ID);
+          *aOutTargetGuid = ScrollableLayerGuid(rfp->GetLayersId(), 0, ScrollableLayerGuid::NULL_SCROLL_ID);
         }
       }
     }
     if (aOutInputBlockId) {
       *aOutInputBlockId = InputAPZContext::GetInputBlockId();
     }
     if (aOutApzResponse) {
       *aOutApzResponse = InputAPZContext::GetApzResponse();
--- a/gfx/layers/FrameMetrics.cpp
+++ b/gfx/layers/FrameMetrics.cpp
@@ -6,17 +6,17 @@
 
 #include "FrameMetrics.h"
 #include "gfxPrefs.h"
 #include "nsStyleConsts.h"
 
 namespace mozilla {
 namespace layers {
 
-const FrameMetrics::ViewID FrameMetrics::NULL_SCROLL_ID = 0;
+const ScrollableLayerGuid::ViewID ScrollableLayerGuid::NULL_SCROLL_ID = 0;
 
 void
 FrameMetrics::RecalculateViewportOffset()
 {
   if (!mIsRootContent) {
     return;
   }
   KeepLayoutViewportEnclosingVisualViewport(GetVisualViewport(), mViewport);
--- a/gfx/layers/FrameMetrics.h
+++ b/gfx/layers/FrameMetrics.h
@@ -13,16 +13,17 @@
 #include "mozilla/DefineEnum.h"         // for MOZ_DEFINE_ENUM
 #include "mozilla/HashFunctions.h"      // for HashGeneric
 #include "mozilla/Maybe.h"
 #include "mozilla/gfx/BasePoint.h"      // for BasePoint
 #include "mozilla/gfx/Rect.h"           // for RoundedIn
 #include "mozilla/gfx/ScaleFactor.h"    // for ScaleFactor
 #include "mozilla/gfx/Logging.h"        // for Log
 #include "mozilla/layers/LayersTypes.h" // for ScrollDirection
+#include "mozilla/layers/ScrollableLayerGuid.h" // for ScrollableLayerGuid
 #include "mozilla/StaticPtr.h"          // for StaticAutoPtr
 #include "mozilla/TimeStamp.h"          // for TimeStamp
 #include "nsString.h"
 #include "nsStyleCoord.h"               // for nsStyleCoord
 #include "PLDHashTable.h"               // for PLDHashNumber
 
 namespace IPC {
 template <typename T> struct ParamTraits;
@@ -45,38 +46,34 @@ struct ScrollUpdateInfo {
 /**
  * The viewport and displayport metrics for the painted frame at the
  * time of a layer-tree transaction.  These metrics are especially
  * useful for shadow layers, because the metrics values are updated
  * atomically with new pixels.
  */
 struct FrameMetrics {
   friend struct IPC::ParamTraits<mozilla::layers::FrameMetrics>;
+
+  typedef ScrollableLayerGuid::ViewID ViewID;
 public:
-  // We use IDs to identify frames across processes.
-  typedef uint64_t ViewID;
-  static const ViewID NULL_SCROLL_ID;   // This container layer does not scroll.
-  static const ViewID START_SCROLL_ID = 2;  // This is the ID that scrolling subframes
-                                        // will begin at.
-
   MOZ_DEFINE_ENUM_WITH_BASE_AT_CLASS_SCOPE(
     ScrollOffsetUpdateType, uint8_t, (
       eNone,          // The default; the scroll offset was not updated
       eMainThread,    // The scroll offset was updated by the main thread.
       ePending,       // The scroll offset was updated on the main thread, but not
                       // painted, so the layer texture data is still at the old
                       // offset.
       eRestore        // The scroll offset was updated by the main thread, but as
                       // a restore from history or after a frame reconstruction.
                       // In this case, APZ can ignore the offset change if the
                       // user has done an APZ scroll already.
   ));
 
   FrameMetrics()
-    : mScrollId(NULL_SCROLL_ID)
+    : mScrollId(ScrollableLayerGuid::NULL_SCROLL_ID)
     , mPresShellResolution(1)
     , mCompositionBounds(0, 0, 0, 0)
     , mDisplayPort(0, 0, 0, 0)
     , mCriticalDisplayPort(0, 0, 0, 0)
     , mScrollableRect(0, 0, 0, 0)
     , mCumulativeResolution()
     , mDevPixelsPerCSSPixel(1)
     , mScrollOffset(0, 0)
@@ -133,17 +130,17 @@ public:
 
   bool operator!=(const FrameMetrics& aOther) const
   {
     return !operator==(aOther);
   }
 
   bool IsScrollable() const
   {
-    return mScrollId != NULL_SCROLL_ID;
+    return mScrollId != ScrollableLayerGuid::NULL_SCROLL_ID;
   }
 
   CSSToScreenScale2D DisplayportPixelsPerCSSPixel() const
   {
     // Note: use 'mZoom * ParentLayerToLayerScale(1.0f)' as the CSS-to-Layer scale
     // instead of LayersPixelsPerCSSPixel(), because displayport calculations
     // are done in the context of a repaint request, where we ask Layout to
     // repaint at a new resolution that includes any async zoom. Until this
@@ -920,24 +917,24 @@ typedef Maybe<LayerClip> MaybeLayerClip;
  * the compositor (including APZ). This includes the scroll frame's FrameMetrics,
  * as well as other metadata. We don't put the other metadata into FrameMetrics
  * to avoid FrameMetrics becoming too bloated (as a FrameMetrics is e.g. sent
  * over IPC for every repaint request for every active scroll frame).
  */
 struct ScrollMetadata {
   friend struct IPC::ParamTraits<mozilla::layers::ScrollMetadata>;
 
-  typedef FrameMetrics::ViewID ViewID;
+  typedef ScrollableLayerGuid::ViewID ViewID;
 public:
   static StaticAutoPtr<const ScrollMetadata> sNullMetadata;   // We sometimes need an empty metadata
 
   ScrollMetadata()
     : mMetrics()
     , mSnapInfo()
-    , mScrollParentId(FrameMetrics::NULL_SCROLL_ID)
+    , mScrollParentId(ScrollableLayerGuid::NULL_SCROLL_ID)
     , mBackgroundColor()
     , mContentDescription()
     , mLineScrollAmount(0, 0)
     , mPageScrollAmount(0, 0)
     , mScrollClip()
     , mHasScrollgrab(false)
     , mIsLayersIdRoot(false)
     , mIsAutoDirRootContentRTL(false)
@@ -1163,187 +1160,14 @@ private:
   //    1. ScrollMetadata::operator ==
   //    2. AsyncPanZoomController::NotifyLayersUpdated
   //    3. The ParamTraits specialization in GfxMessageUtils.h and/or
   //       LayersMessageUtils.h
   //
   // Please add new fields above this comment.
 };
 
-/**
- * This class allows us to uniquely identify a scrollable layer. The
- * mLayersId identifies the layer tree (corresponding to a child process
- * and/or tab) that the scrollable layer belongs to. The mPresShellId
- * is a temporal identifier (corresponding to the document loaded that
- * contains the scrollable layer, which may change over time). The
- * mScrollId corresponds to the actual frame that is scrollable.
- */
-struct ScrollableLayerGuid {
-  LayersId mLayersId;
-  uint32_t mPresShellId;
-  FrameMetrics::ViewID mScrollId;
-
-  ScrollableLayerGuid()
-    : mLayersId{0}
-    , mPresShellId(0)
-    , mScrollId(0)
-  {
-  }
-
-  ScrollableLayerGuid(LayersId aLayersId, uint32_t aPresShellId,
-                      FrameMetrics::ViewID aScrollId)
-    : mLayersId(aLayersId)
-    , mPresShellId(aPresShellId)
-    , mScrollId(aScrollId)
-  {
-  }
-
-  ScrollableLayerGuid(LayersId aLayersId, const FrameMetrics& aMetrics)
-    : mLayersId(aLayersId)
-    , mPresShellId(aMetrics.GetPresShellId())
-    , mScrollId(aMetrics.GetScrollId())
-  {
-  }
-
-  ScrollableLayerGuid(const ScrollableLayerGuid& other)
-    : mLayersId(other.mLayersId)
-    , mPresShellId(other.mPresShellId)
-    , mScrollId(other.mScrollId)
-  {
-  }
-
-  ~ScrollableLayerGuid()
-  {
-  }
-
-  bool operator==(const ScrollableLayerGuid& other) const
-  {
-    return mLayersId == other.mLayersId
-        && mPresShellId == other.mPresShellId
-        && mScrollId == other.mScrollId;
-  }
-
-  bool operator!=(const ScrollableLayerGuid& other) const
-  {
-    return !(*this == other);
-  }
-
-  bool operator<(const ScrollableLayerGuid& other) const
-  {
-    if (mLayersId < other.mLayersId) {
-      return true;
-    }
-    if (mLayersId == other.mLayersId) {
-      if (mPresShellId < other.mPresShellId) {
-        return true;
-      }
-      if (mPresShellId == other.mPresShellId) {
-        return mScrollId < other.mScrollId;
-      }
-    }
-    return false;
-  }
-
-  // Helper structs to use as hash/equality functions in std::unordered_map. e.g.
-  // std::unordered_map<ScrollableLayerGuid,
-  //                    ValueType,
-  //                    ScrollableLayerGuid::HashFn> myMap;
-  // std::unordered_map<ScrollableLayerGuid,
-  //                    ValueType,
-  //                    ScrollableLayerGuid::HashIgnoringPresShellFn,
-  //                    ScrollableLayerGuid::EqualIgnoringPresShellFn> myMap;
-
-  struct HashFn
-  {
-    std::size_t operator()(const ScrollableLayerGuid& aGuid) const
-    {
-      return HashGeneric(uint64_t(aGuid.mLayersId),
-                         aGuid.mPresShellId,
-                         aGuid.mScrollId);
-    }
-  };
-
-  struct HashIgnoringPresShellFn
-  {
-    std::size_t operator()(const ScrollableLayerGuid& aGuid) const
-    {
-      return HashGeneric(uint64_t(aGuid.mLayersId),
-                         aGuid.mScrollId);
-    }
-  };
-
-  struct EqualIgnoringPresShellFn
-  {
-    bool operator()(const ScrollableLayerGuid& lhs, const ScrollableLayerGuid& rhs) const
-    {
-      return lhs.mLayersId == rhs.mLayersId
-          && lhs.mScrollId == rhs.mScrollId;
-    }
-  };
-};
-
-template <int LogLevel>
-gfx::Log<LogLevel>& operator<<(gfx::Log<LogLevel>& log, const ScrollableLayerGuid& aGuid) {
-  return log << '(' << uint64_t(aGuid.mLayersId) << ',' << aGuid.mPresShellId << ',' << aGuid.mScrollId << ')';
-}
-
-struct ZoomConstraints {
-  bool mAllowZoom;
-  bool mAllowDoubleTapZoom;
-  CSSToParentLayerScale mMinZoom;
-  CSSToParentLayerScale mMaxZoom;
-
-  ZoomConstraints()
-    : mAllowZoom(true)
-    , mAllowDoubleTapZoom(true)
-  {
-    MOZ_COUNT_CTOR(ZoomConstraints);
-  }
-
-  ZoomConstraints(bool aAllowZoom,
-                  bool aAllowDoubleTapZoom,
-                  const CSSToParentLayerScale& aMinZoom,
-                  const CSSToParentLayerScale& aMaxZoom)
-    : mAllowZoom(aAllowZoom)
-    , mAllowDoubleTapZoom(aAllowDoubleTapZoom)
-    , mMinZoom(aMinZoom)
-    , mMaxZoom(aMaxZoom)
-  {
-    MOZ_COUNT_CTOR(ZoomConstraints);
-  }
-
-  ZoomConstraints(const ZoomConstraints& other)
-    : mAllowZoom(other.mAllowZoom)
-    , mAllowDoubleTapZoom(other.mAllowDoubleTapZoom)
-    , mMinZoom(other.mMinZoom)
-    , mMaxZoom(other.mMaxZoom)
-  {
-    MOZ_COUNT_CTOR(ZoomConstraints);
-  }
-
-  ~ZoomConstraints()
-  {
-    MOZ_COUNT_DTOR(ZoomConstraints);
-  }
-
-  bool operator==(const ZoomConstraints& other) const
-  {
-    return mAllowZoom == other.mAllowZoom
-        && mAllowDoubleTapZoom == other.mAllowDoubleTapZoom
-        && mMinZoom == other.mMinZoom
-        && mMaxZoom == other.mMaxZoom;
-  }
-
-  bool operator!=(const ZoomConstraints& other) const
-  {
-    return !(*this == other);
-  }
-};
-
-
-typedef Maybe<ZoomConstraints> MaybeZoomConstraints;
-
-typedef std::map<FrameMetrics::ViewID,ScrollUpdateInfo> ScrollUpdatesMap;
+typedef std::map<ScrollableLayerGuid::ViewID,ScrollUpdateInfo> ScrollUpdatesMap;
 
 } // namespace layers
 } // namespace mozilla
 
 #endif /* GFX_FRAMEMETRICS_H */
--- a/gfx/layers/LayerAttributes.h
+++ b/gfx/layers/LayerAttributes.h
@@ -111,17 +111,17 @@ public:
 
   /**
    * Whether the scrollbar thumb can be dragged asynchronously.
    */
   bool mThumbIsAsyncDraggable = false;
 
   CSSCoord mScrollTrackStart;
   CSSCoord mScrollTrackLength;
-  uint64_t mTargetViewId = FrameMetrics::NULL_SCROLL_ID;
+  uint64_t mTargetViewId = ScrollableLayerGuid::NULL_SCROLL_ID;
 
   bool operator==(const ScrollbarData& aOther) const {
     return mDirection == aOther.mDirection &&
            mScrollbarLayerType == aOther.mScrollbarLayerType &&
            mThumbRatio == aOther.mThumbRatio &&
            mThumbStart == aOther.mThumbStart &&
            mThumbLength == aOther.mThumbLength &&
            mThumbIsAsyncDraggable == aOther.mThumbIsAsyncDraggable &&
@@ -240,17 +240,17 @@ public:
   bool SetScrolledClip(const Maybe<LayerClip>& aScrolledClip) {
     if (mScrolledClip == aScrolledClip) {
       return false;
     }
     mScrolledClip = aScrolledClip;
     return true;
   }
 
-  bool SetFixedPositionData(FrameMetrics::ViewID aTargetViewId,
+  bool SetFixedPositionData(ScrollableLayerGuid::ViewID aTargetViewId,
                             const LayerPoint& aAnchor,
                             int32_t aSides)
   {
     if (mFixedPositionData &&
         mFixedPositionData->mScrollId == aTargetViewId &&
         mFixedPositionData->mAnchor == aAnchor &&
         mFixedPositionData->mSides == aSides) {
       return false;
@@ -259,17 +259,17 @@ public:
       mFixedPositionData.emplace();
     }
     mFixedPositionData->mScrollId = aTargetViewId;
     mFixedPositionData->mAnchor = aAnchor;
     mFixedPositionData->mSides = aSides;
     return true;
   }
 
-  bool SetStickyPositionData(FrameMetrics::ViewID aScrollId,
+  bool SetStickyPositionData(ScrollableLayerGuid::ViewID aScrollId,
                              LayerRectAbsolute aOuter, LayerRectAbsolute aInner)
   {
     if (mStickyPositionData &&
         mStickyPositionData->mOuter.IsEqualEdges(aOuter) &&
         mStickyPositionData->mInner.IsEqualEdges(aInner)) {
       return false;
     }
     if (!mStickyPositionData) {
@@ -341,35 +341,35 @@ public:
   bool GetTransformIsPerspective() const {
     return mTransformIsPerspective;
   }
 
   const Maybe<LayerClip>& GetScrolledClip() const {
     return mScrolledClip;
   }
 
-  FrameMetrics::ViewID GetFixedPositionScrollContainerId() const {
+  ScrollableLayerGuid::ViewID GetFixedPositionScrollContainerId() const {
     return (mIsFixedPosition && mFixedPositionData)
            ? mFixedPositionData->mScrollId
-           : FrameMetrics::NULL_SCROLL_ID;
+           : ScrollableLayerGuid::NULL_SCROLL_ID;
   }
 
   LayerPoint GetFixedPositionAnchor() const {
     return mFixedPositionData ? mFixedPositionData->mAnchor : LayerPoint();
   }
 
   int32_t GetFixedPositionSides() const {
     return mFixedPositionData ? mFixedPositionData->mSides : eSideBitsNone;
   }
 
   bool IsStickyPosition() const {
     return !!mStickyPositionData;
   }
 
-  FrameMetrics::ViewID GetStickyScrollContainerId() const {
+  ScrollableLayerGuid::ViewID GetStickyScrollContainerId() const {
     return mStickyPositionData->mScrollId;
   }
 
   const LayerRectAbsolute& GetStickyScrollRangeOuter() const {
     return mStickyPositionData->mOuter;
   }
 
   const LayerRectAbsolute& GetStickyScrollRangeInner() const {
@@ -399,24 +399,24 @@ private:
   uint32_t mContentFlags;
   float mOpacity;
   bool mIsFixedPosition;
   ScrollbarData mScrollbarData;
   gfx::CompositionOp mMixBlendMode;
   bool mForceIsolatedGroup;
 
   struct FixedPositionData {
-    FrameMetrics::ViewID mScrollId;
+    ScrollableLayerGuid::ViewID mScrollId;
     LayerPoint mAnchor;
     int32_t mSides;
   };
   Maybe<FixedPositionData> mFixedPositionData;
 
   struct StickyPositionData {
-    FrameMetrics::ViewID mScrollId;
+    ScrollableLayerGuid::ViewID mScrollId;
     LayerRectAbsolute mOuter;
     LayerRectAbsolute mInner;
   };
   Maybe<StickyPositionData> mStickyPositionData;
 
   /**
    * This class may only contain plain-old-data members that can be safely
    * copied over IPC. Make sure to add new members to operator ==.
--- a/gfx/layers/LayerMetricsWrapper.h
+++ b/gfx/layers/LayerMetricsWrapper.h
@@ -421,17 +421,17 @@ public:
   {
     MOZ_ASSERT(IsValid());
     // This function is only really needed for template-compatibility with
     // WebRenderScrollDataWrapper. Although it will be called, the return
     // value is not used.
     return 0;
   }
 
-  FrameMetrics::ViewID GetFixedPositionScrollContainerId() const
+  ScrollableLayerGuid::ViewID GetFixedPositionScrollContainerId() const
   {
     MOZ_ASSERT(IsValid());
 
     return mLayer->GetFixedPositionScrollContainerId();
   }
 
   bool IsBackfaceHidden() const
   {
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -56,52 +56,52 @@ namespace mozilla {
 namespace layers {
 
 FILE*
 FILEOrDefault(FILE* aFile)
 {
   return aFile ? aFile : stderr;
 }
 
-typedef FrameMetrics::ViewID ViewID;
+typedef ScrollableLayerGuid::ViewID ViewID;
 
 using namespace mozilla::gfx;
 using namespace mozilla::Compression;
 
 //--------------------------------------------------
 // LayerManager
 
 /* static */ mozilla::LogModule*
 LayerManager::GetLog()
 {
   static LazyLogModule sLog("Layers");
   return sLog;
 }
 
-FrameMetrics::ViewID
+ScrollableLayerGuid::ViewID
 LayerManager::GetRootScrollableLayerId()
 {
   if (!mRoot) {
-    return FrameMetrics::NULL_SCROLL_ID;
+    return ScrollableLayerGuid::NULL_SCROLL_ID;
   }
 
   LayerMetricsWrapper layerMetricsRoot = LayerMetricsWrapper(mRoot);
 
   LayerMetricsWrapper rootScrollableLayerMetrics =
       BreadthFirstSearch<ForwardIterator>(
           layerMetricsRoot,
           [](LayerMetricsWrapper aLayerMetrics)
           {
             return aLayerMetrics.Metrics().IsScrollable();
           }
       );
 
   return rootScrollableLayerMetrics.IsValid() ?
       rootScrollableLayerMetrics.Metrics().GetScrollId() :
-      FrameMetrics::NULL_SCROLL_ID;
+      ScrollableLayerGuid::NULL_SCROLL_ID;
 }
 
 LayerMetricsWrapper
 LayerManager::GetRootContentLayer()
 {
   if (!mRoot) {
     return LayerMetricsWrapper();
   }
@@ -2373,33 +2373,33 @@ LayerManager::DumpPacket(layerscope::Lay
 
 /*static*/ bool
 LayerManager::IsLogEnabled()
 {
   return MOZ_LOG_TEST(GetLog(), LogLevel::Debug);
 }
 
 bool
-LayerManager::SetPendingScrollUpdateForNextTransaction(FrameMetrics::ViewID aScrollId,
+LayerManager::SetPendingScrollUpdateForNextTransaction(ScrollableLayerGuid::ViewID aScrollId,
                                                        const ScrollUpdateInfo& aUpdateInfo)
 {
   Layer* withPendingTransform = DepthFirstSearch<ForwardIterator>(GetRoot(),
       [](Layer* aLayer) {
         return aLayer->HasPendingTransform();
       });
   if (withPendingTransform) {
     return false;
   }
 
   mPendingScrollUpdates[aScrollId] = aUpdateInfo;
   return true;
 }
 
 Maybe<ScrollUpdateInfo>
-LayerManager::GetPendingScrollInfoUpdate(FrameMetrics::ViewID aScrollId)
+LayerManager::GetPendingScrollInfoUpdate(ScrollableLayerGuid::ViewID aScrollId)
 {
   auto it = mPendingScrollUpdates.find(aScrollId);
   if (it != mPendingScrollUpdates.end()) {
     return Some(it->second);
   }
   return Nothing();
 }
 
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -409,17 +409,17 @@ public:
   Layer* GetRoot() { return mRoot; }
 
   /**
    * Does a breadth-first search from the root layer to find the first
    * scrollable layer, and returns its ViewID. Note that there may be
    * other layers in the tree which share the same ViewID.
    * Can be called any time.
    */
-  FrameMetrics::ViewID GetRootScrollableLayerId();
+  ScrollableLayerGuid::ViewID GetRootScrollableLayerId();
 
   /**
    * Returns a LayerMetricsWrapper containing the Root
    * Content Documents layer.
    */
   LayerMetricsWrapper GetRootContentLayer();
 
   /**
@@ -758,19 +758,19 @@ protected:
   uint32_t mPaintedPixelCount;
 
 public:
   /*
    * Methods to store/get/clear a "pending scroll info update" object on a
    * per-scrollid basis. This is used for empty transactions that push over
    * scroll position updates to the APZ code.
    */
-  virtual bool SetPendingScrollUpdateForNextTransaction(FrameMetrics::ViewID aScrollId,
+  virtual bool SetPendingScrollUpdateForNextTransaction(ScrollableLayerGuid::ViewID aScrollId,
                                                         const ScrollUpdateInfo& aUpdateInfo);
-  Maybe<ScrollUpdateInfo> GetPendingScrollInfoUpdate(FrameMetrics::ViewID aScrollId);
+  Maybe<ScrollUpdateInfo> GetPendingScrollInfoUpdate(ScrollableLayerGuid::ViewID aScrollId);
   void ClearPendingScrollInfoUpdate();
 protected:
   ScrollUpdatesMap mPendingScrollUpdates;
 };
 
 /**
  * A Layer represents anything that can be rendered onto a destination
  * surface.
@@ -1220,17 +1220,17 @@ public:
    *     compositing the layer tree with a transformation (such as when
    *     asynchronously scrolling and zooming).
    *
    *   - |aSides| is the set of sides to which the element is fixed relative to.
    *     This is used if the viewport size is changed in the compositor and
    *     fixed position items need to shift accordingly. This value is made up
    *     combining appropriate values from mozilla::SideBits.
    */
-  void SetFixedPositionData(FrameMetrics::ViewID aScrollId,
+  void SetFixedPositionData(ScrollableLayerGuid::ViewID aScrollId,
                             const LayerPoint& aAnchor,
                             int32_t aSides)
   {
     if (mSimpleAttrs.SetFixedPositionData(aScrollId, aAnchor, aSides)) {
       MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) FixedPositionData", this));
       MutatedSimple();
     }
   }
@@ -1239,17 +1239,17 @@ public:
    * CONSTRUCTION PHASE ONLY
    * If a layer is "sticky position", |aScrollId| holds the scroll identifier
    * of the scrollable content that contains it. The difference between the two
    * rectangles |aOuter| and |aInner| is treated as two intervals in each
    * dimension, with the current scroll position at the origin. For each
    * dimension, while that component of the scroll position lies within either
    * interval, the layer should not move relative to its scrolling container.
    */
-  void SetStickyPositionData(FrameMetrics::ViewID aScrollId,
+  void SetStickyPositionData(ScrollableLayerGuid::ViewID aScrollId,
                              LayerRectAbsolute aOuter, LayerRectAbsolute aInner)
   {
     if (mSimpleAttrs.SetStickyPositionData(aScrollId, aOuter, aInner)) {
       MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) StickyPositionData", this));
       MutatedSimple();
     }
   }
 
@@ -1314,20 +1314,20 @@ public:
   const CSSTransformMatrix GetTransformTyped() const;
   const gfx::Matrix4x4& GetBaseTransform() const { return mSimpleAttrs.GetTransform(); }
   // Note: these are virtual because ContainerLayerComposite overrides them.
   virtual float GetPostXScale() const { return mSimpleAttrs.GetPostXScale(); }
   virtual float GetPostYScale() const { return mSimpleAttrs.GetPostYScale(); }
   bool GetIsFixedPosition() { return mSimpleAttrs.IsFixedPosition(); }
   bool GetTransformIsPerspective() const { return mSimpleAttrs.GetTransformIsPerspective(); }
   bool GetIsStickyPosition() { return mSimpleAttrs.IsStickyPosition(); }
-  FrameMetrics::ViewID GetFixedPositionScrollContainerId() { return mSimpleAttrs.GetFixedPositionScrollContainerId(); }
+  ScrollableLayerGuid::ViewID GetFixedPositionScrollContainerId() { return mSimpleAttrs.GetFixedPositionScrollContainerId(); }
   LayerPoint GetFixedPositionAnchor() { return mSimpleAttrs.GetFixedPositionAnchor(); }
   int32_t GetFixedPositionSides() { return mSimpleAttrs.GetFixedPositionSides(); }
-  FrameMetrics::ViewID GetStickyScrollContainerId() { return mSimpleAttrs.GetStickyScrollContainerId(); }
+  ScrollableLayerGuid::ViewID GetStickyScrollContainerId() { return mSimpleAttrs.GetStickyScrollContainerId(); }
   const LayerRectAbsolute& GetStickyScrollRangeOuter() { return mSimpleAttrs.GetStickyScrollRangeOuter(); }
   const LayerRectAbsolute& GetStickyScrollRangeInner() { return mSimpleAttrs.GetStickyScrollRangeInner(); }
   const ScrollbarData& GetScrollbarData() const { return mSimpleAttrs.GetScrollbarData(); }
   bool IsScrollbarContainer() const;
   Layer* GetMaskLayer() const { return mMaskLayer; }
   bool HasPendingTransform() const { return mPendingTransform; }
 
   void CheckCanary() const { mCanary.Check(); }
--- a/gfx/layers/LayersLogging.cpp
+++ b/gfx/layers/LayersLogging.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "LayersLogging.h"
 #include <stdint.h>                     // for uint8_t
+#include "FrameMetrics.h"               // for FrameMetrics, etc
 #include "ImageTypes.h"                 // for ImageFormat
 #include "mozilla/gfx/Matrix.h"         // for Matrix4x4, Matrix
 #include "mozilla/gfx/Point.h"          // for IntSize
 #include "nsDebug.h"                    // for NS_ERROR
 #include "nsPoint.h"                    // for nsPoint
 #include "nsRect.h"                     // for nsRect
 #include "nsRectAbsolute.h"             // for nsRectAbsolute
 #include "base/basictypes.h"
@@ -25,17 +26,17 @@ AppendToString(std::stringstream& aStrea
                const char* pfx, const char* sfx)
 {
   aStream << pfx;
   aStream << nsPrintfCString("%p", p).get();
   aStream << sfx;
 }
 
 void
-AppendToString(std::stringstream& aStream, FrameMetrics::ViewID n,
+AppendToString(std::stringstream& aStream, ScrollableLayerGuid::ViewID n,
                const char* pfx, const char* sfx)
 {
   aStream << pfx;
   aStream << n;
   aStream << sfx;
 }
 
 void
@@ -213,17 +214,17 @@ AppendToString(std::stringstream& aStrea
 
 void
 AppendToString(std::stringstream& aStream, const ScrollMetadata& m,
                const char* pfx, const char* sfx)
 {
   aStream << pfx;
   AppendToString(aStream, m.GetMetrics(), "{ [metrics=");
   AppendToString(aStream, m.GetBackgroundColor(), "] [color=");
-  if (m.GetScrollParentId() != FrameMetrics::NULL_SCROLL_ID) {
+  if (m.GetScrollParentId() != ScrollableLayerGuid::NULL_SCROLL_ID) {
     AppendToString(aStream, m.GetScrollParentId(), "] [scrollParent=");
   }
   if (m.HasScrollClip()) {
     AppendToString(aStream, m.ScrollClip().GetClipRect(), "] [clip=");
   }
   if (m.HasMaskLayer()) {
     AppendToString(aStream, m.ScrollClip().GetMaskLayerIndex().value(), "] [mask=");
   }
--- a/gfx/layers/LayersLogging.h
+++ b/gfx/layers/LayersLogging.h
@@ -2,17 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GFX_LAYERSLOGGING_H
 #define GFX_LAYERSLOGGING_H
 
-#include "FrameMetrics.h"               // for FrameMetrics, etc
+#include "FrameMetrics.h"               // for FrameMetrics
 #include "mozilla/gfx/Matrix.h"         // for Matrix4x4
 #include "mozilla/gfx/Point.h"          // for IntSize, etc
 #include "mozilla/gfx/TiledRegion.h"    // for TiledRegion
 #include "mozilla/gfx/Types.h"          // for SamplingFilter, SurfaceFormat
 #include "mozilla/layers/CompositorTypes.h"  // for TextureFlags
 #include "mozilla/layers/WebRenderLayersLogging.h"
 #include "nsAString.h"
 #include "nsPrintfCString.h"            // for nsPrintfCString
@@ -31,17 +31,17 @@ enum class ImageFormat;
 
 namespace layers {
 
 void
 AppendToString(std::stringstream& aStream, const void* p,
                const char* pfx="", const char* sfx="");
 
 void
-AppendToString(std::stringstream& aStream, FrameMetrics::ViewID n,
+AppendToString(std::stringstream& aStream, ScrollableLayerGuid::ViewID n,
                const char* pfx="", const char* sfx="");
 
 void
 AppendToString(std::stringstream& aStream, const gfx::Color& c,
                const char* pfx="", const char* sfx="");
 
 void
 AppendToString(std::stringstream& aStream, const nsPoint& p,
--- a/gfx/layers/RepaintRequest.h
+++ b/gfx/layers/RepaintRequest.h
@@ -30,17 +30,17 @@ public:
 
   MOZ_DEFINE_ENUM_WITH_BASE_AT_CLASS_SCOPE(
     ScrollOffsetUpdateType, uint8_t, (
       eNone,             // The default; the scroll offset was not updated.
       eUserAction        // The scroll offset was updated by APZ.
   ));
 
   RepaintRequest()
-    : mScrollId(FrameMetrics::NULL_SCROLL_ID)
+    : mScrollId(ScrollableLayerGuid::NULL_SCROLL_ID)
     , mPresShellResolution(1)
     , mCompositionBounds(0, 0, 0, 0)
     , mCumulativeResolution()
     , mDevPixelsPerCSSPixel(1)
     , mScrollOffset(0, 0)
     , mZoom()
     , mScrollGeneration(0)
     , mDisplayPortMargins(0, 0, 0, 0)
@@ -183,17 +183,17 @@ public:
     return mScrollUpdateType != eNone;
   }
 
   uint32_t GetScrollGeneration() const
   {
     return mScrollGeneration;
   }
 
-  FrameMetrics::ViewID GetScrollId() const
+  ScrollableLayerGuid::ViewID GetScrollId() const
   {
     return mScrollId;
   }
 
   const ScreenMargin& GetDisplayPortMargins() const
   {
     return mDisplayPortMargins;
   }
@@ -239,17 +239,17 @@ protected:
 
   void SetIsScrollInfoLayer(bool aIsScrollInfoLayer)
   {
     mIsScrollInfoLayer = aIsScrollInfoLayer;
   }
 
 private:
   // A unique ID assigned to each scrollable frame.
-  FrameMetrics::ViewID mScrollId;
+  ScrollableLayerGuid::ViewID mScrollId;
 
   // The pres-shell resolution that has been induced on the document containing
   // this scroll frame as a result of zooming this scroll frame (whether via
   // user action, or choosing an initial zoom level on page load). This can
   // only be different from 1.0 for frames that are zoomable, which currently
   // is just the root content document's root scroll frame (mIsRoot = true).
   // This is a plain float rather than a ScaleFactor because in and of itself
   // it does not convert between any coordinate spaces for which we have names.
copy from gfx/layers/FrameMetrics.h
copy to gfx/layers/ScrollableLayerGuid.h
--- a/gfx/layers/FrameMetrics.h
+++ b/gfx/layers/ScrollableLayerGuid.h
@@ -1,1213 +1,59 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifndef GFX_FRAMEMETRICS_H
-#define GFX_FRAMEMETRICS_H
+#ifndef GFX_SCROLLABLELAYERGUID_H
+#define GFX_SCROLLABLELAYERGUID_H
 
 #include <stdint.h>                     // for uint8_t, uint32_t, uint64_t
-#include <map>
-#include "Units.h"                      // for CSSRect, CSSPixel, etc
-#include "mozilla/DefineEnum.h"         // for MOZ_DEFINE_ENUM
 #include "mozilla/HashFunctions.h"      // for HashGeneric
-#include "mozilla/Maybe.h"
-#include "mozilla/gfx/BasePoint.h"      // for BasePoint
-#include "mozilla/gfx/Rect.h"           // for RoundedIn
-#include "mozilla/gfx/ScaleFactor.h"    // for ScaleFactor
 #include "mozilla/gfx/Logging.h"        // for Log
-#include "mozilla/layers/LayersTypes.h" // for ScrollDirection
-#include "mozilla/StaticPtr.h"          // for StaticAutoPtr
-#include "mozilla/TimeStamp.h"          // for TimeStamp
-#include "nsString.h"
-#include "nsStyleCoord.h"               // for nsStyleCoord
-#include "PLDHashTable.h"               // for PLDHashNumber
-
-namespace IPC {
-template <typename T> struct ParamTraits;
-} // namespace IPC
+#include "mozilla/layers/LayersTypes.h" // for LayersId
 
 namespace mozilla {
 namespace layers {
 
 /**
- * Helper struct to hold a couple of fields that can be updated as part of
- * an empty transaction.
- */
-struct ScrollUpdateInfo {
-  uint32_t mScrollGeneration;
-  CSSPoint mScrollOffset;
-  CSSPoint mBaseScrollOffset;
-  bool mIsRelative;
-};
-
-/**
- * The viewport and displayport metrics for the painted frame at the
- * time of a layer-tree transaction.  These metrics are especially
- * useful for shadow layers, because the metrics values are updated
- * atomically with new pixels.
- */
-struct FrameMetrics {
-  friend struct IPC::ParamTraits<mozilla::layers::FrameMetrics>;
-public:
-  // We use IDs to identify frames across processes.
-  typedef uint64_t ViewID;
-  static const ViewID NULL_SCROLL_ID;   // This container layer does not scroll.
-  static const ViewID START_SCROLL_ID = 2;  // This is the ID that scrolling subframes
-                                        // will begin at.
-
-  MOZ_DEFINE_ENUM_WITH_BASE_AT_CLASS_SCOPE(
-    ScrollOffsetUpdateType, uint8_t, (
-      eNone,          // The default; the scroll offset was not updated
-      eMainThread,    // The scroll offset was updated by the main thread.
-      ePending,       // The scroll offset was updated on the main thread, but not
-                      // painted, so the layer texture data is still at the old
-                      // offset.
-      eRestore        // The scroll offset was updated by the main thread, but as
-                      // a restore from history or after a frame reconstruction.
-                      // In this case, APZ can ignore the offset change if the
-                      // user has done an APZ scroll already.
-  ));
-
-  FrameMetrics()
-    : mScrollId(NULL_SCROLL_ID)
-    , mPresShellResolution(1)
-    , mCompositionBounds(0, 0, 0, 0)
-    , mDisplayPort(0, 0, 0, 0)
-    , mCriticalDisplayPort(0, 0, 0, 0)
-    , mScrollableRect(0, 0, 0, 0)
-    , mCumulativeResolution()
-    , mDevPixelsPerCSSPixel(1)
-    , mScrollOffset(0, 0)
-    , mBaseScrollOffset(0, 0)
-    , mZoom()
-    , mScrollGeneration(0)
-    , mSmoothScrollOffset(0, 0)
-    , mRootCompositionSize(0, 0)
-    , mDisplayPortMargins(0, 0, 0, 0)
-    , mPresShellId(-1)
-    , mViewport(0, 0, 0, 0)
-    , mExtraResolution()
-    , mPaintRequestTime()
-    , mScrollUpdateType(eNone)
-    , mIsRootContent(false)
-    , mIsRelative(false)
-    , mDoSmoothScroll(false)
-    , mUseDisplayPortMargins(false)
-    , mIsScrollInfoLayer(false)
-  {
-  }
-
-  // Default copy ctor and operator= are fine
-
-  bool operator==(const FrameMetrics& aOther) const
-  {
-    // Put mScrollId at the top since it's the most likely one to fail.
-    return mScrollId == aOther.mScrollId &&
-           mPresShellResolution == aOther.mPresShellResolution &&
-           mCompositionBounds.IsEqualEdges(aOther.mCompositionBounds) &&
-           mDisplayPort.IsEqualEdges(aOther.mDisplayPort) &&
-           mCriticalDisplayPort.IsEqualEdges(aOther.mCriticalDisplayPort) &&
-           mScrollableRect.IsEqualEdges(aOther.mScrollableRect) &&
-           mCumulativeResolution == aOther.mCumulativeResolution &&
-           mDevPixelsPerCSSPixel == aOther.mDevPixelsPerCSSPixel &&
-           mScrollOffset == aOther.mScrollOffset &&
-           mBaseScrollOffset == aOther.mBaseScrollOffset &&
-           // don't compare mZoom
-           mScrollGeneration == aOther.mScrollGeneration &&
-           mSmoothScrollOffset == aOther.mSmoothScrollOffset &&
-           mRootCompositionSize == aOther.mRootCompositionSize &&
-           mDisplayPortMargins == aOther.mDisplayPortMargins &&
-           mPresShellId == aOther.mPresShellId &&
-           mViewport.IsEqualEdges(aOther.mViewport) &&
-           mExtraResolution == aOther.mExtraResolution &&
-           mPaintRequestTime == aOther.mPaintRequestTime &&
-           mScrollUpdateType == aOther.mScrollUpdateType &&
-           mIsRootContent == aOther.mIsRootContent &&
-           mIsRelative == aOther.mIsRelative &&
-           mDoSmoothScroll == aOther.mDoSmoothScroll &&
-           mUseDisplayPortMargins == aOther.mUseDisplayPortMargins &&
-           mIsScrollInfoLayer == aOther.mIsScrollInfoLayer;
-  }
-
-  bool operator!=(const FrameMetrics& aOther) const
-  {
-    return !operator==(aOther);
-  }
-
-  bool IsScrollable() const
-  {
-    return mScrollId != NULL_SCROLL_ID;
-  }
-
-  CSSToScreenScale2D DisplayportPixelsPerCSSPixel() const
-  {
-    // Note: use 'mZoom * ParentLayerToLayerScale(1.0f)' as the CSS-to-Layer scale
-    // instead of LayersPixelsPerCSSPixel(), because displayport calculations
-    // are done in the context of a repaint request, where we ask Layout to
-    // repaint at a new resolution that includes any async zoom. Until this
-    // repaint request is processed, LayersPixelsPerCSSPixel() does not yet
-    // include the async zoom, but it will when the displayport is interpreted
-    // for the repaint.
-    return mZoom * ParentLayerToLayerScale(1.0f) / mExtraResolution;
-  }
-
-  CSSToLayerScale2D LayersPixelsPerCSSPixel() const
-  {
-    return mDevPixelsPerCSSPixel * mCumulativeResolution;
-  }
-
-  // Get the amount by which this frame has been zoomed since the last repaint.
-  LayerToParentLayerScale GetAsyncZoom() const
-  {
-    // The async portion of the zoom should be the same along the x and y
-    // axes.
-    return (mZoom / LayersPixelsPerCSSPixel()).ToScaleFactor();
-  }
-
-  // Ensure the scrollableRect is at least as big as the compositionBounds
-  // because the scrollableRect can be smaller if the content is not large
-  // and the scrollableRect hasn't been updated yet.
-  // We move the scrollableRect up because we don't know if we can move it
-  // down. i.e. we know that scrollableRect can go back as far as zero.
-  // but we don't know how much further ahead it can go.
-  CSSRect GetExpandedScrollableRect() const
-  {
-    CSSRect scrollableRect = mScrollableRect;
-    CSSSize compSize = CalculateCompositedSizeInCssPixels();
-    if (scrollableRect.Width() < compSize.width) {
-      scrollableRect.SetRectX(std::max(0.f,
-                                       scrollableRect.X() - (compSize.width - scrollableRect.Width())),
-                              compSize.width);
-    }
-
-    if (scrollableRect.Height() < compSize.height) {
-      scrollableRect.SetRectY(std::max(0.f,
-                                       scrollableRect.Y() - (compSize.height - scrollableRect.Height())),
-                              compSize.height);
-    }
-
-    return scrollableRect;
-  }
-
-  CSSSize CalculateCompositedSizeInCssPixels() const
-  {
-    if (GetZoom() == CSSToParentLayerScale2D(0, 0)) {
-      return CSSSize();  // avoid division by zero
-    }
-    return mCompositionBounds.Size() / GetZoom();
-  }
-
-  /*
-   * Calculate the composition bounds of this frame in the CSS pixels of
-   * the content surrounding the scroll frame. (This can be thought of as
-   * "parent CSS" pixels).
-   * Note that it does not make to ask for the composition bounds in the
-   * CSS pixels of the scrolled content (that is, regular CSS pixels),
-   * because the origin of the composition bounds is not meaningful in that
-   * coordinate space. (The size is, use CalculateCompositedSizeInCssPixels()
-   * for that.)
-   */
-  CSSRect CalculateCompositionBoundsInCssPixelsOfSurroundingContent() const
-  {
-    if (GetZoom() == CSSToParentLayerScale2D(0, 0)) {
-      return CSSRect();  // avoid division by zero
-    }
-    // The CSS pixels of the scrolled content and the CSS pixels of the
-    // surrounding content only differ if the scrolled content is rendered
-    // at a higher resolution, and the difference is the resolution.
-    return mCompositionBounds / GetZoom() * CSSToCSSScale{mPresShellResolution};
-  }
-
-  CSSSize CalculateBoundedCompositedSizeInCssPixels() const
-  {
-    CSSSize size = CalculateCompositedSizeInCssPixels();
-    size.width = std::min(size.width, mRootCompositionSize.width);
-    size.height = std::min(size.height, mRootCompositionSize.height);
-    return size;
-  }
-
-  CSSRect CalculateScrollRange() const
-  {
-    CSSSize scrollPortSize = CalculateCompositedSizeInCssPixels();
-    CSSRect scrollRange = mScrollableRect;
-    scrollRange.SetWidth(std::max(scrollRange.Width() - scrollPortSize.width, 0.0f));
-    scrollRange.SetHeight(std::max(scrollRange.Height() - scrollPortSize.height, 0.0f));
-    return scrollRange;
-  }
-
-  void ScrollBy(const CSSPoint& aPoint)
-  {
-    mScrollOffset += aPoint;
-  }
-
-  void ZoomBy(float aScale)
-  {
-    ZoomBy(gfxSize(aScale, aScale));
-  }
-
-  void ZoomBy(const gfxSize& aScale)
-  {
-    mZoom.xScale *= aScale.width;
-    mZoom.yScale *= aScale.height;
-  }
-
-  /*
-   * Compares an APZ frame metrics with an incoming content frame metrics
-   * to see if APZ has a scroll offset that has not been incorporated into
-   * the content frame metrics.
-   */
-  bool HasPendingScroll(const FrameMetrics& aContentFrameMetrics) const
-  {
-    return mScrollOffset != aContentFrameMetrics.mBaseScrollOffset;
-  }
-
-  void ApplyScrollUpdateFrom(const FrameMetrics& aOther)
-  {
-    mScrollOffset = aOther.mScrollOffset;
-    mScrollGeneration = aOther.mScrollGeneration;
-  }
-
-  void ApplySmoothScrollUpdateFrom(const FrameMetrics& aOther)
-  {
-    mSmoothScrollOffset = aOther.mSmoothScrollOffset;
-    mScrollGeneration = aOther.mScrollGeneration;
-    mDoSmoothScroll = aOther.mDoSmoothScroll;
-  }
-
-  /**
-   * Applies the relative scroll offset update contained in aOther to the
-   * scroll offset contained in this. The scroll delta is clamped to the
-   * scrollable region.
-   *
-   * @returns The clamped scroll offset delta that was applied
-   */
-  CSSPoint ApplyRelativeScrollUpdateFrom(const FrameMetrics& aOther)
-  {
-    MOZ_ASSERT(aOther.IsRelative());
-    CSSPoint origin = mScrollOffset;
-    CSSPoint delta = (aOther.mScrollOffset - aOther.mBaseScrollOffset);
-    ClampAndSetScrollOffset(mScrollOffset + delta);
-    mScrollGeneration = aOther.mScrollGeneration;
-    return mScrollOffset - origin;
-  }
-
-  /**
-   * Applies the relative scroll offset update contained in aOther to the
-   * smooth scroll destination offset contained in this. The scroll delta is
-   * clamped to the scrollable region.
-   */
-  void ApplyRelativeSmoothScrollUpdateFrom(const FrameMetrics& aOther)
-  {
-    MOZ_ASSERT(aOther.IsRelative());
-    CSSPoint delta = (aOther.mSmoothScrollOffset - aOther.mBaseScrollOffset);
-    ClampAndSetSmoothScrollOffset(mScrollOffset + delta);
-    mScrollGeneration = aOther.mScrollGeneration;
-    mDoSmoothScroll = aOther.mDoSmoothScroll;
-  }
-
-  void UpdatePendingScrollInfo(const ScrollUpdateInfo& aInfo)
-  {
-    mScrollOffset = aInfo.mScrollOffset;
-    mBaseScrollOffset = aInfo.mBaseScrollOffset;
-    mScrollGeneration = aInfo.mScrollGeneration;
-    mScrollUpdateType = ePending;
-    mIsRelative = aInfo.mIsRelative;
-  }
-
-public:
-  void SetPresShellResolution(float aPresShellResolution)
-  {
-    mPresShellResolution = aPresShellResolution;
-  }
-
-  float GetPresShellResolution() const
-  {
-    return mPresShellResolution;
-  }
-
-  void SetCompositionBounds(const ParentLayerRect& aCompositionBounds)
-  {
-    mCompositionBounds = aCompositionBounds;
-  }
-
-  const ParentLayerRect& GetCompositionBounds() const
-  {
-    return mCompositionBounds;
-  }
-
-  void SetDisplayPort(const CSSRect& aDisplayPort)
-  {
-    mDisplayPort = aDisplayPort;
-  }
-
-  const CSSRect& GetDisplayPort() const
-  {
-    return mDisplayPort;
-  }
-
-  void SetCriticalDisplayPort(const CSSRect& aCriticalDisplayPort)
-  {
-    mCriticalDisplayPort = aCriticalDisplayPort;
-  }
-
-  const CSSRect& GetCriticalDisplayPort() const
-  {
-    return mCriticalDisplayPort;
-  }
-
-  void SetCumulativeResolution(const LayoutDeviceToLayerScale2D& aCumulativeResolution)
-  {
-    mCumulativeResolution = aCumulativeResolution;
-  }
-
-  const LayoutDeviceToLayerScale2D& GetCumulativeResolution() const
-  {
-    return mCumulativeResolution;
-  }
-
-  void SetDevPixelsPerCSSPixel(const CSSToLayoutDeviceScale& aDevPixelsPerCSSPixel)
-  {
-    mDevPixelsPerCSSPixel = aDevPixelsPerCSSPixel;
-  }
-
-  const CSSToLayoutDeviceScale& GetDevPixelsPerCSSPixel() const
-  {
-    return mDevPixelsPerCSSPixel;
-  }
-
-  void SetIsRootContent(bool aIsRootContent)
-  {
-    mIsRootContent = aIsRootContent;
-  }
-
-  bool IsRootContent() const
-  {
-    return mIsRootContent;
-  }
-
-  void SetScrollOffset(const CSSPoint& aScrollOffset)
-  {
-    mScrollOffset = aScrollOffset;
-  }
-
-  void SetBaseScrollOffset(const CSSPoint& aScrollOffset)
-  {
-    mBaseScrollOffset = aScrollOffset;
-  }
-
-  // Set scroll offset, first clamping to the scroll range.
-  void ClampAndSetScrollOffset(const CSSPoint& aScrollOffset)
-  {
-    SetScrollOffset(CalculateScrollRange().ClampPoint(aScrollOffset));
-  }
-
-  const CSSPoint& GetScrollOffset() const
-  {
-    return mScrollOffset;
-  }
-
-  const CSSPoint& GetBaseScrollOffset() const
-  {
-    return mBaseScrollOffset;
-  }
-
-  void SetSmoothScrollOffset(const CSSPoint& aSmoothScrollDestination)
-  {
-    mSmoothScrollOffset = aSmoothScrollDestination;
-  }
-
-  void ClampAndSetSmoothScrollOffset(const CSSPoint& aSmoothScrollOffset)
-  {
-    SetSmoothScrollOffset(CalculateScrollRange().ClampPoint(aSmoothScrollOffset));
-  }
-
-  const CSSPoint& GetSmoothScrollOffset() const
-  {
-    return mSmoothScrollOffset;
-  }
-
-  void SetZoom(const CSSToParentLayerScale2D& aZoom)
-  {
-    mZoom = aZoom;
-  }
-
-  const CSSToParentLayerScale2D& GetZoom() const
-  {
-    return mZoom;
-  }
-
-  void SetScrollGeneration(uint32_t aScrollGeneration)
-  {
-    mScrollGeneration = aScrollGeneration;
-  }
-
-  void SetScrollOffsetUpdateType(ScrollOffsetUpdateType aScrollUpdateType)
-  {
-    mScrollUpdateType = aScrollUpdateType;
-  }
-
-  void SetSmoothScrollOffsetUpdated(int32_t aScrollGeneration)
-  {
-    mDoSmoothScroll = true;
-    mScrollGeneration = aScrollGeneration;
-  }
-
-  ScrollOffsetUpdateType GetScrollUpdateType() const
-  {
-    return mScrollUpdateType;
-  }
-
-  bool GetScrollOffsetUpdated() const
-  {
-    return mScrollUpdateType != eNone;
-  }
-
-  void SetIsRelative(bool aIsRelative)
-  {
-    mIsRelative = aIsRelative;
-  }
-
-  bool IsRelative() const
-  {
-    return mIsRelative;
-  }
-
-  bool GetDoSmoothScroll() const
-  {
-    return mDoSmoothScroll;
-  }
-
-  uint32_t GetScrollGeneration() const
-  {
-    return mScrollGeneration;
-  }
-
-  ViewID GetScrollId() const
-  {
-    return mScrollId;
-  }
-
-  void SetScrollId(ViewID scrollId)
-  {
-    mScrollId = scrollId;
-  }
-
-  void SetRootCompositionSize(const CSSSize& aRootCompositionSize)
-  {
-    mRootCompositionSize = aRootCompositionSize;
-  }
-
-  const CSSSize& GetRootCompositionSize() const
-  {
-    return mRootCompositionSize;
-  }
-
-  void SetDisplayPortMargins(const ScreenMargin& aDisplayPortMargins)
-  {
-    mDisplayPortMargins = aDisplayPortMargins;
-  }
-
-  const ScreenMargin& GetDisplayPortMargins() const
-  {
-    return mDisplayPortMargins;
-  }
-
-  void SetUseDisplayPortMargins(bool aValue)
-  {
-    mUseDisplayPortMargins = aValue;
-  }
-
-  bool GetUseDisplayPortMargins() const
-  {
-    return mUseDisplayPortMargins;
-  }
-
-  uint32_t GetPresShellId() const
-  {
-    return mPresShellId;
-  }
-
-  void SetPresShellId(uint32_t aPresShellId)
-  {
-    mPresShellId = aPresShellId;
-  }
-
-  void SetViewport(const CSSRect& aViewport)
-  {
-    mViewport = aViewport;
-  }
-
-  const CSSRect& GetViewport() const
-  {
-    return mViewport;
-  }
-
-  CSSRect GetVisualViewport() const
-  {
-    return CSSRect(mScrollOffset, CalculateCompositedSizeInCssPixels());
-  }
-
-  void SetExtraResolution(const ScreenToLayerScale2D& aExtraResolution)
-  {
-    mExtraResolution = aExtraResolution;
-  }
-
-  const ScreenToLayerScale2D& GetExtraResolution() const
-  {
-    return mExtraResolution;
-  }
-
-  const CSSRect& GetScrollableRect() const
-  {
-    return mScrollableRect;
-  }
-
-  void SetScrollableRect(const CSSRect& aScrollableRect)
-  {
-    mScrollableRect = aScrollableRect;
-  }
-
-  // If the frame is in vertical-RTL writing mode(E.g. "writing-mode:
-  // vertical-rl" in CSS), or if it's in horizontal-RTL writing-mode(E.g.
-  // "writing-mode: horizontal-tb; direction: rtl;" in CSS), then this function
-  // returns true. From the representation perspective, frames whose horizontal
-  // contents start at rightside also cause their horizontal scrollbars, if any,
-  // initially start at rightside. So we can also learn about the initial side
-  // of the horizontal scrollbar for the frame by calling this function.
-  bool IsHorizontalContentRightToLeft() const {
-    return mScrollableRect.x < 0;
-  }
-
-  void SetPaintRequestTime(const TimeStamp& aTime) {
-    mPaintRequestTime = aTime;
-  }
-  const TimeStamp& GetPaintRequestTime() const {
-    return mPaintRequestTime;
-  }
-
-  void SetIsScrollInfoLayer(bool aIsScrollInfoLayer) {
-    mIsScrollInfoLayer = aIsScrollInfoLayer;
-  }
-  bool IsScrollInfoLayer() const {
-    return mIsScrollInfoLayer;
-  }
-
-  // Determine if the visual viewport is outside of the layout viewport and
-  // adjust the x,y-offset in mViewport accordingly. This is necessary to
-  // allow APZ to async-scroll the layout viewport.
-  //
-  // This is a no-op if mIsRootContent is false.
-  void RecalculateViewportOffset();
-
-  // Helper function for RecalculateViewportOffset(). Exposed so that
-  // APZC can perform the operation on other copies of the layout
-  // and visual viewport rects (e.g. the "effective" ones used to implement
-  // the frame delay).
-  // Modifies |aLayoutViewport| to continue enclosing |aVisualViewport|
-  // if possible.
-  static void KeepLayoutViewportEnclosingVisualViewport(
-      const CSSRect& aVisualViewport,
-      CSSRect& aLayoutViewport);
-
-private:
-  // A unique ID assigned to each scrollable frame.
-  ViewID mScrollId;
-
-  // The pres-shell resolution that has been induced on the document containing
-  // this scroll frame as a result of zooming this scroll frame (whether via
-  // user action, or choosing an initial zoom level on page load). This can
-  // only be different from 1.0 for frames that are zoomable, which currently
-  // is just the root content document's root scroll frame (mIsRoot = true).
-  // This is a plain float rather than a ScaleFactor because in and of itself
-  // it does not convert between any coordinate spaces for which we have names.
-  float mPresShellResolution;
-
-  // This is the area within the widget that we're compositing to. It is in the
-  // same coordinate space as the reference frame for the scrolled frame.
-  //
-  // This is useful because, on mobile, the viewport and composition dimensions
-  // are not always the same. In this case, we calculate the displayport using
-  // an area bigger than the region we're compositing to. If we used the
-  // viewport dimensions to calculate the displayport, we'd run into situations
-  // where we're prerendering the wrong regions and the content may be clipped,
-  // or too much of it prerendered. If the composition dimensions are the same
-  // as the viewport dimensions, there is no need for this and we can just use
-  // the viewport instead.
-  //
-  // This value is valid for nested scrollable layers as well, and is still
-  // relative to the layer tree origin. This value is provided by Gecko at
-  // layout/paint time.
-  ParentLayerRect mCompositionBounds;
-
-  // The area of a frame's contents that has been painted, relative to
-  // mCompositionBounds.
-  //
-  // Note that this is structured in such a way that it doesn't depend on the
-  // method layout uses to scroll content.
-  //
-  // May be larger or smaller than |mScrollableRect|.
-  //
-  // To pre-render a margin of 100 CSS pixels around the window,
-  // { x = -100, y = - 100,
-  //   width = window.innerWidth + 200, height = window.innerHeight + 200 }
-  CSSRect mDisplayPort;
-
-  // If non-empty, the area of a frame's contents that is considered critical
-  // to paint. Area outside of this area (i.e. area inside mDisplayPort, but
-  // outside of mCriticalDisplayPort) is considered low-priority, and may be
-  // painted with lower precision, or not painted at all.
-  //
-  // The same restrictions for mDisplayPort apply here.
-  CSSRect mCriticalDisplayPort;
-
-  // The scrollable bounds of a frame. This is determined by reflow.
-  // Ordinarily the x and y will be 0 and the width and height will be the
-  // size of the element being scrolled. However for RTL pages or elements
-  // the x value may be negative.
-  //
-  // For scrollable frames that are overflow:hidden the x and y are usually
-  // set to the value of the current scroll offset, and the width and height
-  // will match the composition bounds width and height. In effect this reduces
-  // the scrollable range to 0.
-  //
-  // This is in the same coordinate space as |mScrollOffset|, but a different
-  // coordinate space than |mViewport| and |mDisplayPort|. Note also that this
-  // coordinate system is understood by window.scrollTo().
-  //
-  // This is valid on any layer unless it has no content.
-  CSSRect mScrollableRect;
-
-  // The cumulative resolution that the current frame has been painted at.
-  // This is the product of the pres-shell resolutions of the document
-  // containing this scroll frame and its ancestors, and any css-driven
-  // resolution. This information is provided by Gecko at layout/paint time.
-  // Note that this is allowed to have different x- and y-scales, but only
-  // for subframes (mIsRoot = false). (The same applies to other scales that
-  // "inherit" the 2D-ness of this one, such as mZoom.)
-  LayoutDeviceToLayerScale2D mCumulativeResolution;
-
-  // New fields from now on should be made private and old fields should
-  // be refactored to be private.
-
-  // The conversion factor between CSS pixels and device pixels for this frame.
-  // This can vary based on a variety of things, such as reflowing-zoom. The
-  // conversion factor for device pixels to layers pixels is just the
-  // resolution.
-  CSSToLayoutDeviceScale mDevPixelsPerCSSPixel;
-
-  // The position of the top-left of the CSS viewport, relative to the document
-  // (or the document relative to the viewport, if that helps understand it).
-  //
-  // Thus it is relative to the document. It is in the same coordinate space as
-  // |mScrollableRect|, but a different coordinate space than |mViewport| and
-  // |mDisplayPort|.
-  //
-  // It is required that the rect:
-  // { x = mScrollOffset.x, y = mScrollOffset.y,
-  //   width = mCompositionBounds.x / mResolution.scale,
-  //   height = mCompositionBounds.y / mResolution.scale }
-  // Be within |mScrollableRect|.
-  //
-  // This is valid for any layer, but is always relative to this frame and
-  // not any parents, regardless of parent transforms.
-  CSSPoint mScrollOffset;
-
-  // The base scroll offset to use for calculating a relative update to a
-  // scroll offset.
-  CSSPoint mBaseScrollOffset;
-
-  // The "user zoom". Content is painted by gecko at mResolution * mDevPixelsPerCSSPixel,
-  // but will be drawn to the screen at mZoom. In the steady state, the
-  // two will be the same, but during an async zoom action the two may
-  // diverge. This information is initialized in Gecko but updated in the APZC.
-  CSSToParentLayerScale2D mZoom;
-
-  // The scroll generation counter used to acknowledge the scroll offset update.
-  uint32_t mScrollGeneration;
-
-  // If mDoSmoothScroll is true, the scroll offset will be animated smoothly
-  // to this value.
-  CSSPoint mSmoothScrollOffset;
-
-  // The size of the root scrollable's composition bounds, but in local CSS pixels.
-  CSSSize mRootCompositionSize;
-
-  // A display port expressed as layer margins that apply to the rect of what
-  // is drawn of the scrollable element.
-  ScreenMargin mDisplayPortMargins;
-
-  uint32_t mPresShellId;
-
-  // The CSS viewport, which is the dimensions we're using to constrain the
-  // <html> element of this frame, relative to the top-left of the layer. Note
-  // that its offset is structured in such a way that it doesn't depend on the
-  // method layout uses to scroll content.
-  //
-  // This is mainly useful on the root layer, however nested iframes can have
-  // their own viewport, which will just be the size of the window of the
-  // iframe. For layers that don't correspond to a document, this metric is
-  // meaningless and invalid.
-  CSSRect mViewport;
-
-  // The extra resolution at which content in this scroll frame is drawn beyond
-  // that necessary to draw one Layer pixel per Screen pixel.
-  ScreenToLayerScale2D mExtraResolution;
-
-  // The time at which the APZC last requested a repaint for this scrollframe.
-  TimeStamp mPaintRequestTime;
-
-  // Whether mScrollOffset was updated by something other than the APZ code, and
-  // if the APZC receiving this metrics should update its local copy.
-  ScrollOffsetUpdateType mScrollUpdateType;
-
-  // Whether or not this is the root scroll frame for the root content document.
-  bool mIsRootContent:1;
-
-  // When mIsRelative, the scroll offset was updated using a relative API,
-  // such as `ScrollBy`, and can combined with an async scroll.
-  bool mIsRelative:1;
-
-  // When mDoSmoothScroll, the scroll offset should be animated to
-  // smoothly transition to mScrollOffset rather than be updated instantly.
-  bool mDoSmoothScroll:1;
-
-  // If this is true then we use the display port margins on this metrics,
-  // otherwise use the display port rect.
-  bool mUseDisplayPortMargins:1;
-
-  // Whether or not this frame has a "scroll info layer" to capture events.
-  bool mIsScrollInfoLayer:1;
-
-  // WARNING!!!!
-  //
-  // When adding a new field:
-  //
-  //  - First, consider whether the field can be added to ScrollMetadata
-  //    instead. If so, prefer that.
-  //
-  //  - Otherwise, the following places should be updated to include them
-  //    (as needed):
-  //      FrameMetrics::operator ==
-  //      AsyncPanZoomController::NotifyLayersUpdated
-  //      The ParamTraits specialization in GfxMessageUtils.h
-  //
-  // Please add new fields above this comment.
-
-  // Private helpers for IPC purposes
-  void SetDoSmoothScroll(bool aValue) {
-    mDoSmoothScroll = aValue;
-  }
-};
-
-struct ScrollSnapInfo {
-  ScrollSnapInfo()
-    : mScrollSnapTypeX(NS_STYLE_SCROLL_SNAP_TYPE_NONE)
-    , mScrollSnapTypeY(NS_STYLE_SCROLL_SNAP_TYPE_NONE)
-  {}
-
-  bool operator==(const ScrollSnapInfo& aOther) const
-  {
-    return mScrollSnapTypeX == aOther.mScrollSnapTypeX &&
-           mScrollSnapTypeY == aOther.mScrollSnapTypeY &&
-           mScrollSnapIntervalX == aOther.mScrollSnapIntervalX &&
-           mScrollSnapIntervalY == aOther.mScrollSnapIntervalY &&
-           mScrollSnapDestination == aOther.mScrollSnapDestination &&
-           mScrollSnapCoordinates == aOther.mScrollSnapCoordinates;
-  }
-
-  bool HasScrollSnapping() const
-  {
-    return mScrollSnapTypeY != NS_STYLE_SCROLL_SNAP_TYPE_NONE ||
-           mScrollSnapTypeX != NS_STYLE_SCROLL_SNAP_TYPE_NONE;
-  }
-
-  // The scroll frame's scroll-snap-type.
-  // One of NS_STYLE_SCROLL_SNAP_{NONE, MANDATORY, PROXIMITY}.
-  uint8_t mScrollSnapTypeX;
-  uint8_t mScrollSnapTypeY;
-
-  // The intervals derived from the scroll frame's scroll-snap-points.
-  Maybe<nscoord> mScrollSnapIntervalX;
-  Maybe<nscoord> mScrollSnapIntervalY;
-
-  // The scroll frame's scroll-snap-destination, in cooked form (to avoid
-  // shipping the raw nsStyleCoord::CalcValue over IPC).
-  nsPoint mScrollSnapDestination;
-
-  // The scroll-snap-coordinates of any descendant frames of the scroll frame,
-  // relative to the origin of the scrolled frame.
-  nsTArray<nsPoint> mScrollSnapCoordinates;
-};
-
-MOZ_DEFINE_ENUM_CLASS_WITH_BASE(
-  OverscrollBehavior, uint8_t, (
-    Auto,
-    Contain,
-    None
-));
-
-struct OverscrollBehaviorInfo {
-  OverscrollBehaviorInfo()
-    : mBehaviorX(OverscrollBehavior::Auto)
-    , mBehaviorY(OverscrollBehavior::Auto)
-  {}
-
-  // Construct from StyleOverscrollBehavior values.
-  static OverscrollBehaviorInfo FromStyleConstants(StyleOverscrollBehavior aBehaviorX,
-                                                   StyleOverscrollBehavior aBehaviorY);
-
-  bool operator==(const OverscrollBehaviorInfo& aOther) const {
-    return mBehaviorX == aOther.mBehaviorX &&
-           mBehaviorY == aOther.mBehaviorY;
-  }
-
-  OverscrollBehavior mBehaviorX;
-  OverscrollBehavior mBehaviorY;
-};
-
-/**
- * A clip that applies to a layer, that may be scrolled by some of the
- * scroll frames associated with the layer.
- */
-struct LayerClip {
-  friend struct IPC::ParamTraits<mozilla::layers::LayerClip>;
-
-public:
-  LayerClip()
-    : mClipRect()
-    , mMaskLayerIndex()
-  {}
-
-  explicit LayerClip(const ParentLayerIntRect& aClipRect)
-    : mClipRect(aClipRect)
-    , mMaskLayerIndex()
-  {}
-
-  bool operator==(const LayerClip& aOther) const
-  {
-    return mClipRect == aOther.mClipRect &&
-           mMaskLayerIndex == aOther.mMaskLayerIndex;
-  }
-
-  void SetClipRect(const ParentLayerIntRect& aClipRect) {
-    mClipRect = aClipRect;
-  }
-  const ParentLayerIntRect& GetClipRect() const {
-    return mClipRect;
-  }
-
-  void SetMaskLayerIndex(const Maybe<size_t>& aIndex) {
-    mMaskLayerIndex = aIndex;
-  }
-  const Maybe<size_t>& GetMaskLayerIndex() const {
-    return mMaskLayerIndex;
-  }
-
-private:
-  ParentLayerIntRect mClipRect;
-
-  // Optionally, specifies a mask layer that's part of the clip.
-  // This is an index into the MetricsMaskLayers array on the Layer.
-  Maybe<size_t> mMaskLayerIndex;
-};
-
-typedef Maybe<LayerClip> MaybeLayerClip;  // for passing over IPDL
-
-/**
- * Metadata about a scroll frame that's stored in the layer tree for use by
- * the compositor (including APZ). This includes the scroll frame's FrameMetrics,
- * as well as other metadata. We don't put the other metadata into FrameMetrics
- * to avoid FrameMetrics becoming too bloated (as a FrameMetrics is e.g. sent
- * over IPC for every repaint request for every active scroll frame).
- */
-struct ScrollMetadata {
-  friend struct IPC::ParamTraits<mozilla::layers::ScrollMetadata>;
-
-  typedef FrameMetrics::ViewID ViewID;
-public:
-  static StaticAutoPtr<const ScrollMetadata> sNullMetadata;   // We sometimes need an empty metadata
-
-  ScrollMetadata()
-    : mMetrics()
-    , mSnapInfo()
-    , mScrollParentId(FrameMetrics::NULL_SCROLL_ID)
-    , mBackgroundColor()
-    , mContentDescription()
-    , mLineScrollAmount(0, 0)
-    , mPageScrollAmount(0, 0)
-    , mScrollClip()
-    , mHasScrollgrab(false)
-    , mIsLayersIdRoot(false)
-    , mIsAutoDirRootContentRTL(false)
-    , mUsesContainerScrolling(false)
-    , mForceDisableApz(false)
-    , mOverscrollBehavior()
-  {}
-
-  bool operator==(const ScrollMetadata& aOther) const
-  {
-    return mMetrics == aOther.mMetrics &&
-           mSnapInfo == aOther.mSnapInfo &&
-           mScrollParentId == aOther.mScrollParentId &&
-           mBackgroundColor == aOther.mBackgroundColor &&
-           // don't compare mContentDescription
-           mLineScrollAmount == aOther.mLineScrollAmount &&
-           mPageScrollAmount == aOther.mPageScrollAmount &&
-           mScrollClip == aOther.mScrollClip &&
-           mHasScrollgrab == aOther.mHasScrollgrab &&
-           mIsLayersIdRoot == aOther.mIsLayersIdRoot &&
-           mIsAutoDirRootContentRTL == aOther.mIsAutoDirRootContentRTL &&
-           mUsesContainerScrolling == aOther.mUsesContainerScrolling &&
-           mForceDisableApz == aOther.mForceDisableApz &&
-           mDisregardedDirection == aOther.mDisregardedDirection &&
-           mOverscrollBehavior == aOther.mOverscrollBehavior;
-  }
-
-  bool operator!=(const ScrollMetadata& aOther) const
-  {
-    return !operator==(aOther);
-  }
-
-  bool IsDefault() const
-  {
-    ScrollMetadata def;
-
-    def.mMetrics.SetPresShellId(mMetrics.GetPresShellId());
-    return (def == *this);
-  }
-
-  FrameMetrics& GetMetrics() { return mMetrics; }
-  const FrameMetrics& GetMetrics() const { return mMetrics; }
-
-  void SetSnapInfo(ScrollSnapInfo&& aSnapInfo) {
-    mSnapInfo = std::move(aSnapInfo);
-  }
-  const ScrollSnapInfo& GetSnapInfo() const { return mSnapInfo; }
-
-  ViewID GetScrollParentId() const {
-    return mScrollParentId;
-  }
-
-  void SetScrollParentId(ViewID aParentId) {
-    mScrollParentId = aParentId;
-  }
-  const gfx::Color& GetBackgroundColor() const {
-    return mBackgroundColor;
-  }
-  void SetBackgroundColor(const gfx::Color& aBackgroundColor) {
-    mBackgroundColor = aBackgroundColor;
-  }
-  const nsCString& GetContentDescription() const {
-    return mContentDescription;
-  }
-  void SetContentDescription(const nsCString& aContentDescription) {
-    mContentDescription = aContentDescription;
-  }
-  const LayoutDeviceIntSize& GetLineScrollAmount() const {
-    return mLineScrollAmount;
-  }
-  void SetLineScrollAmount(const LayoutDeviceIntSize& size) {
-    mLineScrollAmount = size;
-  }
-  const LayoutDeviceIntSize& GetPageScrollAmount() const {
-    return mPageScrollAmount;
-  }
-  void SetPageScrollAmount(const LayoutDeviceIntSize& size) {
-    mPageScrollAmount = size;
-  }
-
-  void SetScrollClip(const Maybe<LayerClip>& aScrollClip) {
-    mScrollClip = aScrollClip;
-  }
-  const Maybe<LayerClip>& GetScrollClip() const {
-    return mScrollClip;
-  }
-  bool HasScrollClip() const {
-    return mScrollClip.isSome();
-  }
-  const LayerClip& ScrollClip() const {
-    return mScrollClip.ref();
-  }
-  LayerClip& ScrollClip() {
-    return mScrollClip.ref();
-  }
-
-  bool HasMaskLayer() const {
-    return HasScrollClip() && ScrollClip().GetMaskLayerIndex();
-  }
-  Maybe<ParentLayerIntRect> GetClipRect() const {
-    return mScrollClip.isSome() ? Some(mScrollClip->GetClipRect()) : Nothing();
-  }
-
-  void SetHasScrollgrab(bool aHasScrollgrab) {
-    mHasScrollgrab = aHasScrollgrab;
-  }
-  bool GetHasScrollgrab() const {
-    return mHasScrollgrab;
-  }
-  void SetIsLayersIdRoot(bool aValue) {
-    mIsLayersIdRoot = aValue;
-  }
-  bool IsLayersIdRoot() const {
-    return mIsLayersIdRoot;
-  }
-  void SetIsAutoDirRootContentRTL(bool aValue) {
-    mIsAutoDirRootContentRTL = aValue;
-  }
-  bool IsAutoDirRootContentRTL() const {
-    return mIsAutoDirRootContentRTL;
-  }
-  // Implemented out of line because the implementation needs gfxPrefs.h
-  // and we don't want to include that from FrameMetrics.h.
-  void SetUsesContainerScrolling(bool aValue);
-  bool UsesContainerScrolling() const {
-    return mUsesContainerScrolling;
-  }
-  void SetForceDisableApz(bool aForceDisable) {
-    mForceDisableApz = aForceDisable;
-  }
-  bool IsApzForceDisabled() const {
-    return mForceDisableApz;
-  }
-
-  // For more details about the concept of a disregarded direction, refer to the
-  // code which defines mDisregardedDirection.
-  Maybe<ScrollDirection> GetDisregardedDirection() const {
-    return mDisregardedDirection;
-  }
-  void
-  SetDisregardedDirection(const Maybe<ScrollDirection>& aValue) {
-    mDisregardedDirection = aValue;
-  }
-
-  void SetOverscrollBehavior(const OverscrollBehaviorInfo& aOverscrollBehavior) {
-    mOverscrollBehavior = aOverscrollBehavior;
-  }
-  const OverscrollBehaviorInfo& GetOverscrollBehavior() const {
-    return mOverscrollBehavior;
-  }
-
-private:
-  FrameMetrics mMetrics;
-
-  // Information used to determine where to snap to for a given scroll.
-  ScrollSnapInfo mSnapInfo;
-
-  // The ViewID of the scrollable frame to which overscroll should be handed off.
-  ViewID mScrollParentId;
-
-  // The background color to use when overscrolling.
-  gfx::Color mBackgroundColor;
-
-  // A description of the content element corresponding to this frame.
-  // This is empty unless this is a scrollable layer and the
-  // apz.printtree pref is turned on.
-  nsCString mContentDescription;
-
-  // The value of GetLineScrollAmount(), for scroll frames.
-  LayoutDeviceIntSize mLineScrollAmount;
-
-  // The value of GetPageScrollAmount(), for scroll frames.
-  LayoutDeviceIntSize mPageScrollAmount;
-
-  // A clip to apply when compositing the layer bearing this ScrollMetadata,
-  // after applying any transform arising from scrolling this scroll frame.
-  // Note that, unlike most other fields of ScrollMetadata, this is allowed
-  // to differ between different layers scrolled by the same scroll frame.
-  // TODO: Group the fields of ScrollMetadata into sub-structures to separate
-  // fields with this property better.
-  Maybe<LayerClip> mScrollClip;
-
-  // Whether or not this frame is for an element marked 'scrollgrab'.
-  bool mHasScrollgrab:1;
-
-  // Whether these framemetrics are for the root scroll frame (root element if
-  // we don't have a root scroll frame) for its layers id.
-  bool mIsLayersIdRoot:1;
-
-  // The AutoDirRootContent is the <body> element in an HTML document, or the
-  // root scrollframe if there is no body. This member variable indicates
-  // whether this element's content in the horizontal direction starts from
-  // right to left (e.g. it's true either if "writing-mode: vertical-rl", or
-  // "writing-mode: horizontal-tb; direction: rtl" in CSS).
-  // When we do auto-dir scrolling (@see mozilla::WheelDeltaAdjustmentStrategy
-  // or refer to bug 1358017 for details), setting a pref can make the code use
-  // the writing mode of this root element instead of the target scrollframe,
-  // and so we need to know if the writing mode is RTL or not.
-  bool mIsAutoDirRootContentRTL:1;
-
-  // True if scrolling using containers, false otherwise. This can be removed
-  // when containerful scrolling is eliminated.
-  bool mUsesContainerScrolling:1;
-
-  // Whether or not the compositor should actually do APZ-scrolling on this
-  // scrollframe.
-  bool mForceDisableApz:1;
-
-  // The disregarded direction means the direction which is disregarded anyway,
-  // even if the scroll frame overflows in that direction and the direction is
-  // specified as scrollable. This could happen in some scenarios, for instance,
-  // a single-line text control frame should disregard wheel scroll in
-  // its block-flow direction even if it overflows in that direction.
-  Maybe<ScrollDirection> mDisregardedDirection;
-
-  // The overscroll behavior for this scroll frame.
-  OverscrollBehaviorInfo mOverscrollBehavior;
-
-  // WARNING!!!!
-  //
-  // When adding new fields to ScrollMetadata, the following places should be
-  // updated to include them (as needed):
-  //    1. ScrollMetadata::operator ==
-  //    2. AsyncPanZoomController::NotifyLayersUpdated
-  //    3. The ParamTraits specialization in GfxMessageUtils.h and/or
-  //       LayersMessageUtils.h
-  //
-  // Please add new fields above this comment.
-};
-
-/**
  * This class allows us to uniquely identify a scrollable layer. The
  * mLayersId identifies the layer tree (corresponding to a child process
  * and/or tab) that the scrollable layer belongs to. The mPresShellId
  * is a temporal identifier (corresponding to the document loaded that
  * contains the scrollable layer, which may change over time). The
  * mScrollId corresponds to the actual frame that is scrollable.
  */
 struct ScrollableLayerGuid {
+  // We use IDs to identify frames across processes.
+  typedef uint64_t ViewID;
+  static const ViewID NULL_SCROLL_ID;   // This container layer does not scroll.
+  static const ViewID START_SCROLL_ID = 2;  // This is the ID that scrolling subframes
+                                        // will begin at.
+
   LayersId mLayersId;
   uint32_t mPresShellId;
-  FrameMetrics::ViewID mScrollId;
+  ViewID mScrollId;
 
   ScrollableLayerGuid()
     : mLayersId{0}
     , mPresShellId(0)
     , mScrollId(0)
   {
   }
 
   ScrollableLayerGuid(LayersId aLayersId, uint32_t aPresShellId,
-                      FrameMetrics::ViewID aScrollId)
+                      ViewID aScrollId)
     : mLayersId(aLayersId)
     , mPresShellId(aPresShellId)
     , mScrollId(aScrollId)
   {
   }
 
-  ScrollableLayerGuid(LayersId aLayersId, const FrameMetrics& aMetrics)
-    : mLayersId(aLayersId)
-    , mPresShellId(aMetrics.GetPresShellId())
-    , mScrollId(aMetrics.GetScrollId())
-  {
-  }
-
   ScrollableLayerGuid(const ScrollableLayerGuid& other)
     : mLayersId(other.mLayersId)
     , mPresShellId(other.mPresShellId)
     , mScrollId(other.mScrollId)
   {
   }
 
   ~ScrollableLayerGuid()
@@ -1280,70 +126,12 @@ struct ScrollableLayerGuid {
   };
 };
 
 template <int LogLevel>
 gfx::Log<LogLevel>& operator<<(gfx::Log<LogLevel>& log, const ScrollableLayerGuid& aGuid) {
   return log << '(' << uint64_t(aGuid.mLayersId) << ',' << aGuid.mPresShellId << ',' << aGuid.mScrollId << ')';
 }
 
-struct ZoomConstraints {
-  bool mAllowZoom;
-  bool mAllowDoubleTapZoom;
-  CSSToParentLayerScale mMinZoom;
-  CSSToParentLayerScale mMaxZoom;
-
-  ZoomConstraints()
-    : mAllowZoom(true)
-    , mAllowDoubleTapZoom(true)
-  {
-    MOZ_COUNT_CTOR(ZoomConstraints);
-  }
-
-  ZoomConstraints(bool aAllowZoom,
-                  bool aAllowDoubleTapZoom,
-                  const CSSToParentLayerScale& aMinZoom,
-                  const CSSToParentLayerScale& aMaxZoom)
-    : mAllowZoom(aAllowZoom)
-    , mAllowDoubleTapZoom(aAllowDoubleTapZoom)
-    , mMinZoom(aMinZoom)
-    , mMaxZoom(aMaxZoom)
-  {
-    MOZ_COUNT_CTOR(ZoomConstraints);
-  }
-
-  ZoomConstraints(const ZoomConstraints& other)
-    : mAllowZoom(other.mAllowZoom)
-    , mAllowDoubleTapZoom(other.mAllowDoubleTapZoom)
-    , mMinZoom(other.mMinZoom)
-    , mMaxZoom(other.mMaxZoom)
-  {
-    MOZ_COUNT_CTOR(ZoomConstraints);
-  }
-
-  ~ZoomConstraints()
-  {
-    MOZ_COUNT_DTOR(ZoomConstraints);
-  }
-
-  bool operator==(const ZoomConstraints& other) const
-  {
-    return mAllowZoom == other.mAllowZoom
-        && mAllowDoubleTapZoom == other.mAllowDoubleTapZoom
-        && mMinZoom == other.mMinZoom
-        && mMaxZoom == other.mMaxZoom;
-  }
-
-  bool operator!=(const ZoomConstraints& other) const
-  {
-    return !(*this == other);
-  }
-};
-
-
-typedef Maybe<ZoomConstraints> MaybeZoomConstraints;
-
-typedef std::map<FrameMetrics::ViewID,ScrollUpdateInfo> ScrollUpdatesMap;
-
 } // namespace layers
 } // namespace mozilla
 
-#endif /* GFX_FRAMEMETRICS_H */
+#endif /* GFX_SCROLLABLELAYERGUID_H */
copy from gfx/layers/FrameMetrics.h
copy to gfx/layers/ZoomConstraints.h
--- a/gfx/layers/FrameMetrics.h
+++ b/gfx/layers/ZoomConstraints.h
@@ -1,1295 +1,24 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifndef GFX_FRAMEMETRICS_H
-#define GFX_FRAMEMETRICS_H
+#ifndef GFX_ZOOMCONSTRAINTS_H
+#define GFX_ZOOMCONSTRAINTS_H
 
-#include <stdint.h>                     // for uint8_t, uint32_t, uint64_t
-#include <map>
 #include "Units.h"                      // for CSSRect, CSSPixel, etc
-#include "mozilla/DefineEnum.h"         // for MOZ_DEFINE_ENUM
-#include "mozilla/HashFunctions.h"      // for HashGeneric
 #include "mozilla/Maybe.h"
-#include "mozilla/gfx/BasePoint.h"      // for BasePoint
-#include "mozilla/gfx/Rect.h"           // for RoundedIn
-#include "mozilla/gfx/ScaleFactor.h"    // for ScaleFactor
-#include "mozilla/gfx/Logging.h"        // for Log
-#include "mozilla/layers/LayersTypes.h" // for ScrollDirection
-#include "mozilla/StaticPtr.h"          // for StaticAutoPtr
-#include "mozilla/TimeStamp.h"          // for TimeStamp
-#include "nsString.h"
-#include "nsStyleCoord.h"               // for nsStyleCoord
-#include "PLDHashTable.h"               // for PLDHashNumber
-
-namespace IPC {
-template <typename T> struct ParamTraits;
-} // namespace IPC
+#include "mozilla/layers/ScrollableLayerGuid.h" // for ScrollableLayerGuid
 
 namespace mozilla {
 namespace layers {
 
-/**
- * Helper struct to hold a couple of fields that can be updated as part of
- * an empty transaction.
- */
-struct ScrollUpdateInfo {
-  uint32_t mScrollGeneration;
-  CSSPoint mScrollOffset;
-  CSSPoint mBaseScrollOffset;
-  bool mIsRelative;
-};
-
-/**
- * The viewport and displayport metrics for the painted frame at the
- * time of a layer-tree transaction.  These metrics are especially
- * useful for shadow layers, because the metrics values are updated
- * atomically with new pixels.
- */
-struct FrameMetrics {
-  friend struct IPC::ParamTraits<mozilla::layers::FrameMetrics>;
-public:
-  // We use IDs to identify frames across processes.
-  typedef uint64_t ViewID;
-  static const ViewID NULL_SCROLL_ID;   // This container layer does not scroll.
-  static const ViewID START_SCROLL_ID = 2;  // This is the ID that scrolling subframes
-                                        // will begin at.
-
-  MOZ_DEFINE_ENUM_WITH_BASE_AT_CLASS_SCOPE(
-    ScrollOffsetUpdateType, uint8_t, (
-      eNone,          // The default; the scroll offset was not updated
-      eMainThread,    // The scroll offset was updated by the main thread.
-      ePending,       // The scroll offset was updated on the main thread, but not
-                      // painted, so the layer texture data is still at the old
-                      // offset.
-      eRestore        // The scroll offset was updated by the main thread, but as
-                      // a restore from history or after a frame reconstruction.
-                      // In this case, APZ can ignore the offset change if the
-                      // user has done an APZ scroll already.
-  ));
-
-  FrameMetrics()
-    : mScrollId(NULL_SCROLL_ID)
-    , mPresShellResolution(1)
-    , mCompositionBounds(0, 0, 0, 0)
-    , mDisplayPort(0, 0, 0, 0)
-    , mCriticalDisplayPort(0, 0, 0, 0)
-    , mScrollableRect(0, 0, 0, 0)
-    , mCumulativeResolution()
-    , mDevPixelsPerCSSPixel(1)
-    , mScrollOffset(0, 0)
-    , mBaseScrollOffset(0, 0)
-    , mZoom()
-    , mScrollGeneration(0)
-    , mSmoothScrollOffset(0, 0)
-    , mRootCompositionSize(0, 0)
-    , mDisplayPortMargins(0, 0, 0, 0)
-    , mPresShellId(-1)
-    , mViewport(0, 0, 0, 0)
-    , mExtraResolution()
-    , mPaintRequestTime()
-    , mScrollUpdateType(eNone)
-    , mIsRootContent(false)
-    , mIsRelative(false)
-    , mDoSmoothScroll(false)
-    , mUseDisplayPortMargins(false)
-    , mIsScrollInfoLayer(false)
-  {
-  }
-
-  // Default copy ctor and operator= are fine
-
-  bool operator==(const FrameMetrics& aOther) const
-  {
-    // Put mScrollId at the top since it's the most likely one to fail.
-    return mScrollId == aOther.mScrollId &&
-           mPresShellResolution == aOther.mPresShellResolution &&
-           mCompositionBounds.IsEqualEdges(aOther.mCompositionBounds) &&
-           mDisplayPort.IsEqualEdges(aOther.mDisplayPort) &&
-           mCriticalDisplayPort.IsEqualEdges(aOther.mCriticalDisplayPort) &&
-           mScrollableRect.IsEqualEdges(aOther.mScrollableRect) &&
-           mCumulativeResolution == aOther.mCumulativeResolution &&
-           mDevPixelsPerCSSPixel == aOther.mDevPixelsPerCSSPixel &&
-           mScrollOffset == aOther.mScrollOffset &&
-           mBaseScrollOffset == aOther.mBaseScrollOffset &&
-           // don't compare mZoom
-           mScrollGeneration == aOther.mScrollGeneration &&
-           mSmoothScrollOffset == aOther.mSmoothScrollOffset &&
-           mRootCompositionSize == aOther.mRootCompositionSize &&
-           mDisplayPortMargins == aOther.mDisplayPortMargins &&
-           mPresShellId == aOther.mPresShellId &&
-           mViewport.IsEqualEdges(aOther.mViewport) &&
-           mExtraResolution == aOther.mExtraResolution &&
-           mPaintRequestTime == aOther.mPaintRequestTime &&
-           mScrollUpdateType == aOther.mScrollUpdateType &&
-           mIsRootContent == aOther.mIsRootContent &&
-           mIsRelative == aOther.mIsRelative &&
-           mDoSmoothScroll == aOther.mDoSmoothScroll &&
-           mUseDisplayPortMargins == aOther.mUseDisplayPortMargins &&
-           mIsScrollInfoLayer == aOther.mIsScrollInfoLayer;
-  }
-
-  bool operator!=(const FrameMetrics& aOther) const
-  {
-    return !operator==(aOther);
-  }
-
-  bool IsScrollable() const
-  {
-    return mScrollId != NULL_SCROLL_ID;
-  }
-
-  CSSToScreenScale2D DisplayportPixelsPerCSSPixel() const
-  {
-    // Note: use 'mZoom * ParentLayerToLayerScale(1.0f)' as the CSS-to-Layer scale
-    // instead of LayersPixelsPerCSSPixel(), because displayport calculations
-    // are done in the context of a repaint request, where we ask Layout to
-    // repaint at a new resolution that includes any async zoom. Until this
-    // repaint request is processed, LayersPixelsPerCSSPixel() does not yet
-    // include the async zoom, but it will when the displayport is interpreted
-    // for the repaint.
-    return mZoom * ParentLayerToLayerScale(1.0f) / mExtraResolution;
-  }
-
-  CSSToLayerScale2D LayersPixelsPerCSSPixel() const
-  {
-    return mDevPixelsPerCSSPixel * mCumulativeResolution;
-  }
-
-  // Get the amount by which this frame has been zoomed since the last repaint.
-  LayerToParentLayerScale GetAsyncZoom() const
-  {
-    // The async portion of the zoom should be the same along the x and y
-    // axes.
-    return (mZoom / LayersPixelsPerCSSPixel()).ToScaleFactor();
-  }
-
-  // Ensure the scrollableRect is at least as big as the compositionBounds
-  // because the scrollableRect can be smaller if the content is not large
-  // and the scrollableRect hasn't been updated yet.
-  // We move the scrollableRect up because we don't know if we can move it
-  // down. i.e. we know that scrollableRect can go back as far as zero.
-  // but we don't know how much further ahead it can go.
-  CSSRect GetExpandedScrollableRect() const
-  {
-    CSSRect scrollableRect = mScrollableRect;
-    CSSSize compSize = CalculateCompositedSizeInCssPixels();
-    if (scrollableRect.Width() < compSize.width) {
-      scrollableRect.SetRectX(std::max(0.f,
-                                       scrollableRect.X() - (compSize.width - scrollableRect.Width())),
-                              compSize.width);
-    }
-
-    if (scrollableRect.Height() < compSize.height) {
-      scrollableRect.SetRectY(std::max(0.f,
-                                       scrollableRect.Y() - (compSize.height - scrollableRect.Height())),
-                              compSize.height);
-    }
-
-    return scrollableRect;
-  }
-
-  CSSSize CalculateCompositedSizeInCssPixels() const
-  {
-    if (GetZoom() == CSSToParentLayerScale2D(0, 0)) {
-      return CSSSize();  // avoid division by zero
-    }
-    return mCompositionBounds.Size() / GetZoom();
-  }
-
-  /*
-   * Calculate the composition bounds of this frame in the CSS pixels of
-   * the content surrounding the scroll frame. (This can be thought of as
-   * "parent CSS" pixels).
-   * Note that it does not make to ask for the composition bounds in the
-   * CSS pixels of the scrolled content (that is, regular CSS pixels),
-   * because the origin of the composition bounds is not meaningful in that
-   * coordinate space. (The size is, use CalculateCompositedSizeInCssPixels()
-   * for that.)
-   */
-  CSSRect CalculateCompositionBoundsInCssPixelsOfSurroundingContent() const
-  {
-    if (GetZoom() == CSSToParentLayerScale2D(0, 0)) {
-      return CSSRect();  // avoid division by zero
-    }
-    // The CSS pixels of the scrolled content and the CSS pixels of the
-    // surrounding content only differ if the scrolled content is rendered
-    // at a higher resolution, and the difference is the resolution.
-    return mCompositionBounds / GetZoom() * CSSToCSSScale{mPresShellResolution};
-  }
-
-  CSSSize CalculateBoundedCompositedSizeInCssPixels() const
-  {
-    CSSSize size = CalculateCompositedSizeInCssPixels();
-    size.width = std::min(size.width, mRootCompositionSize.width);
-    size.height = std::min(size.height, mRootCompositionSize.height);
-    return size;
-  }
-
-  CSSRect CalculateScrollRange() const
-  {
-    CSSSize scrollPortSize = CalculateCompositedSizeInCssPixels();
-    CSSRect scrollRange = mScrollableRect;
-    scrollRange.SetWidth(std::max(scrollRange.Width() - scrollPortSize.width, 0.0f));
-    scrollRange.SetHeight(std::max(scrollRange.Height() - scrollPortSize.height, 0.0f));
-    return scrollRange;
-  }
-
-  void ScrollBy(const CSSPoint& aPoint)
-  {
-    mScrollOffset += aPoint;
-  }
-
-  void ZoomBy(float aScale)
-  {
-    ZoomBy(gfxSize(aScale, aScale));
-  }
-
-  void ZoomBy(const gfxSize& aScale)
-  {
-    mZoom.xScale *= aScale.width;
-    mZoom.yScale *= aScale.height;
-  }
-
-  /*
-   * Compares an APZ frame metrics with an incoming content frame metrics
-   * to see if APZ has a scroll offset that has not been incorporated into
-   * the content frame metrics.
-   */
-  bool HasPendingScroll(const FrameMetrics& aContentFrameMetrics) const
-  {
-    return mScrollOffset != aContentFrameMetrics.mBaseScrollOffset;
-  }
-
-  void ApplyScrollUpdateFrom(const FrameMetrics& aOther)
-  {
-    mScrollOffset = aOther.mScrollOffset;
-    mScrollGeneration = aOther.mScrollGeneration;
-  }
-
-  void ApplySmoothScrollUpdateFrom(const FrameMetrics& aOther)
-  {
-    mSmoothScrollOffset = aOther.mSmoothScrollOffset;
-    mScrollGeneration = aOther.mScrollGeneration;
-    mDoSmoothScroll = aOther.mDoSmoothScroll;
-  }
-
-  /**
-   * Applies the relative scroll offset update contained in aOther to the
-   * scroll offset contained in this. The scroll delta is clamped to the
-   * scrollable region.
-   *
-   * @returns The clamped scroll offset delta that was applied
-   */
-  CSSPoint ApplyRelativeScrollUpdateFrom(const FrameMetrics& aOther)
-  {
-    MOZ_ASSERT(aOther.IsRelative());
-    CSSPoint origin = mScrollOffset;
-    CSSPoint delta = (aOther.mScrollOffset - aOther.mBaseScrollOffset);
-    ClampAndSetScrollOffset(mScrollOffset + delta);
-    mScrollGeneration = aOther.mScrollGeneration;
-    return mScrollOffset - origin;
-  }
-
-  /**
-   * Applies the relative scroll offset update contained in aOther to the
-   * smooth scroll destination offset contained in this. The scroll delta is
-   * clamped to the scrollable region.
-   */
-  void ApplyRelativeSmoothScrollUpdateFrom(const FrameMetrics& aOther)
-  {
-    MOZ_ASSERT(aOther.IsRelative());
-    CSSPoint delta = (aOther.mSmoothScrollOffset - aOther.mBaseScrollOffset);
-    ClampAndSetSmoothScrollOffset(mScrollOffset + delta);
-    mScrollGeneration = aOther.mScrollGeneration;
-    mDoSmoothScroll = aOther.mDoSmoothScroll;
-  }
-
-  void UpdatePendingScrollInfo(const ScrollUpdateInfo& aInfo)
-  {
-    mScrollOffset = aInfo.mScrollOffset;
-    mBaseScrollOffset = aInfo.mBaseScrollOffset;
-    mScrollGeneration = aInfo.mScrollGeneration;
-    mScrollUpdateType = ePending;
-    mIsRelative = aInfo.mIsRelative;
-  }
-
-public:
-  void SetPresShellResolution(float aPresShellResolution)
-  {
-    mPresShellResolution = aPresShellResolution;
-  }
-
-  float GetPresShellResolution() const
-  {
-    return mPresShellResolution;
-  }
-
-  void SetCompositionBounds(const ParentLayerRect& aCompositionBounds)
-  {
-    mCompositionBounds = aCompositionBounds;
-  }
-
-  const ParentLayerRect& GetCompositionBounds() const
-  {
-    return mCompositionBounds;
-  }
-
-  void SetDisplayPort(const CSSRect& aDisplayPort)
-  {
-    mDisplayPort = aDisplayPort;
-  }
-
-  const CSSRect& GetDisplayPort() const
-  {
-    return mDisplayPort;
-  }
-
-  void SetCriticalDisplayPort(const CSSRect& aCriticalDisplayPort)
-  {
-    mCriticalDisplayPort = aCriticalDisplayPort;
-  }
-
-  const CSSRect& GetCriticalDisplayPort() const
-  {
-    return mCriticalDisplayPort;
-  }
-
-  void SetCumulativeResolution(const LayoutDeviceToLayerScale2D& aCumulativeResolution)
-  {
-    mCumulativeResolution = aCumulativeResolution;
-  }
-
-  const LayoutDeviceToLayerScale2D& GetCumulativeResolution() const
-  {
-    return mCumulativeResolution;
-  }
-
-  void SetDevPixelsPerCSSPixel(const CSSToLayoutDeviceScale& aDevPixelsPerCSSPixel)
-  {
-    mDevPixelsPerCSSPixel = aDevPixelsPerCSSPixel;
-  }
-
-  const CSSToLayoutDeviceScale& GetDevPixelsPerCSSPixel() const
-  {
-    return mDevPixelsPerCSSPixel;
-  }
-
-  void SetIsRootContent(bool aIsRootContent)
-  {
-    mIsRootContent = aIsRootContent;
-  }
-
-  bool IsRootContent() const
-  {
-    return mIsRootContent;
-  }
-
-  void SetScrollOffset(const CSSPoint& aScrollOffset)
-  {
-    mScrollOffset = aScrollOffset;
-  }
-
-  void SetBaseScrollOffset(const CSSPoint& aScrollOffset)
-  {
-    mBaseScrollOffset = aScrollOffset;
-  }
-
-  // Set scroll offset, first clamping to the scroll range.
-  void ClampAndSetScrollOffset(const CSSPoint& aScrollOffset)
-  {
-    SetScrollOffset(CalculateScrollRange().ClampPoint(aScrollOffset));
-  }
-
-  const CSSPoint& GetScrollOffset() const
-  {
-    return mScrollOffset;
-  }
-
-  const CSSPoint& GetBaseScrollOffset() const
-  {
-    return mBaseScrollOffset;
-  }
-
-  void SetSmoothScrollOffset(const CSSPoint& aSmoothScrollDestination)
-  {
-    mSmoothScrollOffset = aSmoothScrollDestination;
-  }
-
-  void ClampAndSetSmoothScrollOffset(const CSSPoint& aSmoothScrollOffset)
-  {
-    SetSmoothScrollOffset(CalculateScrollRange().ClampPoint(aSmoothScrollOffset));
-  }
-
-  const CSSPoint& GetSmoothScrollOffset() const
-  {
-    return mSmoothScrollOffset;
-  }
-
-  void SetZoom(const CSSToParentLayerScale2D& aZoom)
-  {
-    mZoom = aZoom;
-  }
-
-  const CSSToParentLayerScale2D& GetZoom() const
-  {
-    return mZoom;
-  }
-
-  void SetScrollGeneration(uint32_t aScrollGeneration)
-  {
-    mScrollGeneration = aScrollGeneration;
-  }
-
-  void SetScrollOffsetUpdateType(ScrollOffsetUpdateType aScrollUpdateType)
-  {
-    mScrollUpdateType = aScrollUpdateType;
-  }
-
-  void SetSmoothScrollOffsetUpdated(int32_t aScrollGeneration)
-  {
-    mDoSmoothScroll = true;
-    mScrollGeneration = aScrollGeneration;
-  }
-
-  ScrollOffsetUpdateType GetScrollUpdateType() const
-  {
-    return mScrollUpdateType;
-  }
-
-  bool GetScrollOffsetUpdated() const
-  {
-    return mScrollUpdateType != eNone;
-  }
-
-  void SetIsRelative(bool aIsRelative)
-  {
-    mIsRelative = aIsRelative;
-  }
-
-  bool IsRelative() const
-  {
-    return mIsRelative;
-  }
-
-  bool GetDoSmoothScroll() const
-  {
-    return mDoSmoothScroll;
-  }
-
-  uint32_t GetScrollGeneration() const
-  {
-    return mScrollGeneration;
-  }
-
-  ViewID GetScrollId() const
-  {
-    return mScrollId;
-  }
-
-  void SetScrollId(ViewID scrollId)
-  {
-    mScrollId = scrollId;
-  }
-
-  void SetRootCompositionSize(const CSSSize& aRootCompositionSize)
-  {
-    mRootCompositionSize = aRootCompositionSize;
-  }
-
-  const CSSSize& GetRootCompositionSize() const
-  {
-    return mRootCompositionSize;
-  }
-
-  void SetDisplayPortMargins(const ScreenMargin& aDisplayPortMargins)
-  {
-    mDisplayPortMargins = aDisplayPortMargins;
-  }
-
-  const ScreenMargin& GetDisplayPortMargins() const
-  {
-    return mDisplayPortMargins;
-  }
-
-  void SetUseDisplayPortMargins(bool aValue)
-  {
-    mUseDisplayPortMargins = aValue;
-  }
-
-  bool GetUseDisplayPortMargins() const
-  {
-    return mUseDisplayPortMargins;
-  }
-
-  uint32_t GetPresShellId() const
-  {
-    return mPresShellId;
-  }
-
-  void SetPresShellId(uint32_t aPresShellId)
-  {
-    mPresShellId = aPresShellId;
-  }
-
-  void SetViewport(const CSSRect& aViewport)
-  {
-    mViewport = aViewport;
-  }
-
-  const CSSRect& GetViewport() const
-  {
-    return mViewport;
-  }
-
-  CSSRect GetVisualViewport() const
-  {
-    return CSSRect(mScrollOffset, CalculateCompositedSizeInCssPixels());
-  }
-
-  void SetExtraResolution(const ScreenToLayerScale2D& aExtraResolution)
-  {
-    mExtraResolution = aExtraResolution;
-  }
-
-  const ScreenToLayerScale2D& GetExtraResolution() const
-  {
-    return mExtraResolution;
-  }
-
-  const CSSRect& GetScrollableRect() const
-  {
-    return mScrollableRect;
-  }
-
-  void SetScrollableRect(const CSSRect& aScrollableRect)
-  {
-    mScrollableRect = aScrollableRect;
-  }
-
-  // If the frame is in vertical-RTL writing mode(E.g. "writing-mode:
-  // vertical-rl" in CSS), or if it's in horizontal-RTL writing-mode(E.g.
-  // "writing-mode: horizontal-tb; direction: rtl;" in CSS), then this function
-  // returns true. From the representation perspective, frames whose horizontal
-  // contents start at rightside also cause their horizontal scrollbars, if any,
-  // initially start at rightside. So we can also learn about the initial side
-  // of the horizontal scrollbar for the frame by calling this function.
-  bool IsHorizontalContentRightToLeft() const {
-    return mScrollableRect.x < 0;
-  }
-
-  void SetPaintRequestTime(const TimeStamp& aTime) {
-    mPaintRequestTime = aTime;
-  }
-  const TimeStamp& GetPaintRequestTime() const {
-    return mPaintRequestTime;
-  }
-
-  void SetIsScrollInfoLayer(bool aIsScrollInfoLayer) {
-    mIsScrollInfoLayer = aIsScrollInfoLayer;
-  }
-  bool IsScrollInfoLayer() const {
-    return mIsScrollInfoLayer;
-  }
-
-  // Determine if the visual viewport is outside of the layout viewport and
-  // adjust the x,y-offset in mViewport accordingly. This is necessary to
-  // allow APZ to async-scroll the layout viewport.
-  //
-  // This is a no-op if mIsRootContent is false.
-  void RecalculateViewportOffset();
-
-  // Helper function for RecalculateViewportOffset(). Exposed so that
-  // APZC can perform the operation on other copies of the layout
-  // and visual viewport rects (e.g. the "effective" ones used to implement
-  // the frame delay).
-  // Modifies |aLayoutViewport| to continue enclosing |aVisualViewport|
-  // if possible.
-  static void KeepLayoutViewportEnclosingVisualViewport(
-      const CSSRect& aVisualViewport,
-      CSSRect& aLayoutViewport);
-
-private:
-  // A unique ID assigned to each scrollable frame.
-  ViewID mScrollId;
-
-  // The pres-shell resolution that has been induced on the document containing
-  // this scroll frame as a result of zooming this scroll frame (whether via
-  // user action, or choosing an initial zoom level on page load). This can
-  // only be different from 1.0 for frames that are zoomable, which currently
-  // is just the root content document's root scroll frame (mIsRoot = true).
-  // This is a plain float rather than a ScaleFactor because in and of itself
-  // it does not convert between any coordinate spaces for which we have names.
-  float mPresShellResolution;
-
-  // This is the area within the widget that we're compositing to. It is in the
-  // same coordinate space as the reference frame for the scrolled frame.
-  //
-  // This is useful because, on mobile, the viewport and composition dimensions
-  // are not always the same. In this case, we calculate the displayport using
-  // an area bigger than the region we're compositing to. If we used the
-  // viewport dimensions to calculate the displayport, we'd run into situations
-  // where we're prerendering the wrong regions and the content may be clipped,
-  // or too much of it prerendered. If the composition dimensions are the same
-  // as the viewport dimensions, there is no need for this and we can just use
-  // the viewport instead.
-  //
-  // This value is valid for nested scrollable layers as well, and is still
-  // relative to the layer tree origin. This value is provided by Gecko at
-  // layout/paint time.
-  ParentLayerRect mCompositionBounds;
-
-  // The area of a frame's contents that has been painted, relative to
-  // mCompositionBounds.
-  //
-  // Note that this is structured in such a way that it doesn't depend on the
-  // method layout uses to scroll content.
-  //
-  // May be larger or smaller than |mScrollableRect|.
-  //
-  // To pre-render a margin of 100 CSS pixels around the window,
-  // { x = -100, y = - 100,
-  //   width = window.innerWidth + 200, height = window.innerHeight + 200 }
-  CSSRect mDisplayPort;
-
-  // If non-empty, the area of a frame's contents that is considered critical
-  // to paint. Area outside of this area (i.e. area inside mDisplayPort, but
-  // outside of mCriticalDisplayPort) is considered low-priority, and may be
-  // painted with lower precision, or not painted at all.
-  //
-  // The same restrictions for mDisplayPort apply here.
-  CSSRect mCriticalDisplayPort;
-
-  // The scrollable bounds of a frame. This is determined by reflow.
-  // Ordinarily the x and y will be 0 and the width and height will be the
-  // size of the element being scrolled. However for RTL pages or elements
-  // the x value may be negative.
-  //
-  // For scrollable frames that are overflow:hidden the x and y are usually
-  // set to the value of the current scroll offset, and the width and height
-  // will match the composition bounds width and height. In effect this reduces
-  // the scrollable range to 0.
-  //
-  // This is in the same coordinate space as |mScrollOffset|, but a different
-  // coordinate space than |mViewport| and |mDisplayPort|. Note also that this
-  // coordinate system is understood by window.scrollTo().
-  //
-  // This is valid on any layer unless it has no content.
-  CSSRect mScrollableRect;
-
-  // The cumulative resolution that the current frame has been painted at.
-  // This is the product of the pres-shell resolutions of the document
-  // containing this scroll frame and its ancestors, and any css-driven
-  // resolution. This information is provided by Gecko at layout/paint time.
-  // Note that this is allowed to have different x- and y-scales, but only
-  // for subframes (mIsRoot = false). (The same applies to other scales that
-  // "inherit" the 2D-ness of this one, such as mZoom.)
-  LayoutDeviceToLayerScale2D mCumulativeResolution;
-
-  // New fields from now on should be made private and old fields should
-  // be refactored to be private.
-
-  // The conversion factor between CSS pixels and device pixels for this frame.
-  // This can vary based on a variety of things, such as reflowing-zoom. The
-  // conversion factor for device pixels to layers pixels is just the
-  // resolution.
-  CSSToLayoutDeviceScale mDevPixelsPerCSSPixel;
-
-  // The position of the top-left of the CSS viewport, relative to the document
-  // (or the document relative to the viewport, if that helps understand it).
-  //
-  // Thus it is relative to the document. It is in the same coordinate space as
-  // |mScrollableRect|, but a different coordinate space than |mViewport| and
-  // |mDisplayPort|.
-  //
-  // It is required that the rect:
-  // { x = mScrollOffset.x, y = mScrollOffset.y,
-  //   width = mCompositionBounds.x / mResolution.scale,
-  //   height = mCompositionBounds.y / mResolution.scale }
-  // Be within |mScrollableRect|.
-  //
-  // This is valid for any layer, but is always relative to this frame and
-  // not any parents, regardless of parent transforms.
-  CSSPoint mScrollOffset;
-
-  // The base scroll offset to use for calculating a relative update to a
-  // scroll offset.
-  CSSPoint mBaseScrollOffset;
-
-  // The "user zoom". Content is painted by gecko at mResolution * mDevPixelsPerCSSPixel,
-  // but will be drawn to the screen at mZoom. In the steady state, the
-  // two will be the same, but during an async zoom action the two may
-  // diverge. This information is initialized in Gecko but updated in the APZC.
-  CSSToParentLayerScale2D mZoom;
-
-  // The scroll generation counter used to acknowledge the scroll offset update.
-  uint32_t mScrollGeneration;
-
-  // If mDoSmoothScroll is true, the scroll offset will be animated smoothly
-  // to this value.
-  CSSPoint mSmoothScrollOffset;
-
-  // The size of the root scrollable's composition bounds, but in local CSS pixels.
-  CSSSize mRootCompositionSize;
-
-  // A display port expressed as layer margins that apply to the rect of what
-  // is drawn of the scrollable element.
-  ScreenMargin mDisplayPortMargins;
-
-  uint32_t mPresShellId;
-
-  // The CSS viewport, which is the dimensions we're using to constrain the
-  // <html> element of this frame, relative to the top-left of the layer. Note
-  // that its offset is structured in such a way that it doesn't depend on the
-  // method layout uses to scroll content.
-  //
-  // This is mainly useful on the root layer, however nested iframes can have
-  // their own viewport, which will just be the size of the window of the
-  // iframe. For layers that don't correspond to a document, this metric is
-  // meaningless and invalid.
-  CSSRect mViewport;
-
-  // The extra resolution at which content in this scroll frame is drawn beyond
-  // that necessary to draw one Layer pixel per Screen pixel.
-  ScreenToLayerScale2D mExtraResolution;
-
-  // The time at which the APZC last requested a repaint for this scrollframe.
-  TimeStamp mPaintRequestTime;
-
-  // Whether mScrollOffset was updated by something other than the APZ code, and
-  // if the APZC receiving this metrics should update its local copy.
-  ScrollOffsetUpdateType mScrollUpdateType;
-
-  // Whether or not this is the root scroll frame for the root content document.
-  bool mIsRootContent:1;
-
-  // When mIsRelative, the scroll offset was updated using a relative API,
-  // such as `ScrollBy`, and can combined with an async scroll.
-  bool mIsRelative:1;
-
-  // When mDoSmoothScroll, the scroll offset should be animated to
-  // smoothly transition to mScrollOffset rather than be updated instantly.
-  bool mDoSmoothScroll:1;
-
-  // If this is true then we use the display port margins on this metrics,
-  // otherwise use the display port rect.
-  bool mUseDisplayPortMargins:1;
-
-  // Whether or not this frame has a "scroll info layer" to capture events.
-  bool mIsScrollInfoLayer:1;
-
-  // WARNING!!!!
-  //
-  // When adding a new field:
-  //
-  //  - First, consider whether the field can be added to ScrollMetadata
-  //    instead. If so, prefer that.
-  //
-  //  - Otherwise, the following places should be updated to include them
-  //    (as needed):
-  //      FrameMetrics::operator ==
-  //      AsyncPanZoomController::NotifyLayersUpdated
-  //      The ParamTraits specialization in GfxMessageUtils.h
-  //
-  // Please add new fields above this comment.
-
-  // Private helpers for IPC purposes
-  void SetDoSmoothScroll(bool aValue) {
-    mDoSmoothScroll = aValue;
-  }
-};
-
-struct ScrollSnapInfo {
-  ScrollSnapInfo()
-    : mScrollSnapTypeX(NS_STYLE_SCROLL_SNAP_TYPE_NONE)
-    , mScrollSnapTypeY(NS_STYLE_SCROLL_SNAP_TYPE_NONE)
-  {}
-
-  bool operator==(const ScrollSnapInfo& aOther) const
-  {
-    return mScrollSnapTypeX == aOther.mScrollSnapTypeX &&
-           mScrollSnapTypeY == aOther.mScrollSnapTypeY &&
-           mScrollSnapIntervalX == aOther.mScrollSnapIntervalX &&
-           mScrollSnapIntervalY == aOther.mScrollSnapIntervalY &&
-           mScrollSnapDestination == aOther.mScrollSnapDestination &&
-           mScrollSnapCoordinates == aOther.mScrollSnapCoordinates;
-  }
-
-  bool HasScrollSnapping() const
-  {
-    return mScrollSnapTypeY != NS_STYLE_SCROLL_SNAP_TYPE_NONE ||
-           mScrollSnapTypeX != NS_STYLE_SCROLL_SNAP_TYPE_NONE;
-  }
-
-  // The scroll frame's scroll-snap-type.
-  // One of NS_STYLE_SCROLL_SNAP_{NONE, MANDATORY, PROXIMITY}.
-  uint8_t mScrollSnapTypeX;
-  uint8_t mScrollSnapTypeY;
-
-  // The intervals derived from the scroll frame's scroll-snap-points.
-  Maybe<nscoord> mScrollSnapIntervalX;
-  Maybe<nscoord> mScrollSnapIntervalY;
-
-  // The scroll frame's scroll-snap-destination, in cooked form (to avoid
-  // shipping the raw nsStyleCoord::CalcValue over IPC).
-  nsPoint mScrollSnapDestination;
-
-  // The scroll-snap-coordinates of any descendant frames of the scroll frame,
-  // relative to the origin of the scrolled frame.
-  nsTArray<nsPoint> mScrollSnapCoordinates;
-};
-
-MOZ_DEFINE_ENUM_CLASS_WITH_BASE(
-  OverscrollBehavior, uint8_t, (
-    Auto,
-    Contain,
-    None
-));
-
-struct OverscrollBehaviorInfo {
-  OverscrollBehaviorInfo()
-    : mBehaviorX(OverscrollBehavior::Auto)
-    , mBehaviorY(OverscrollBehavior::Auto)
-  {}
-
-  // Construct from StyleOverscrollBehavior values.
-  static OverscrollBehaviorInfo FromStyleConstants(StyleOverscrollBehavior aBehaviorX,
-                                                   StyleOverscrollBehavior aBehaviorY);
-
-  bool operator==(const OverscrollBehaviorInfo& aOther) const {
-    return mBehaviorX == aOther.mBehaviorX &&
-           mBehaviorY == aOther.mBehaviorY;
-  }
-
-  OverscrollBehavior mBehaviorX;
-  OverscrollBehavior mBehaviorY;
-};
-
-/**
- * A clip that applies to a layer, that may be scrolled by some of the
- * scroll frames associated with the layer.
- */
-struct LayerClip {
-  friend struct IPC::ParamTraits<mozilla::layers::LayerClip>;
-
-public:
-  LayerClip()
-    : mClipRect()
-    , mMaskLayerIndex()
-  {}
-
-  explicit LayerClip(const ParentLayerIntRect& aClipRect)
-    : mClipRect(aClipRect)
-    , mMaskLayerIndex()
-  {}
-
-  bool operator==(const LayerClip& aOther) const
-  {
-    return mClipRect == aOther.mClipRect &&
-           mMaskLayerIndex == aOther.mMaskLayerIndex;
-  }
-
-  void SetClipRect(const ParentLayerIntRect& aClipRect) {
-    mClipRect = aClipRect;
-  }
-  const ParentLayerIntRect& GetClipRect() const {
-    return mClipRect;
-  }
-
-  void SetMaskLayerIndex(const Maybe<size_t>& aIndex) {
-    mMaskLayerIndex = aIndex;
-  }
-  const Maybe<size_t>& GetMaskLayerIndex() const {
-    return mMaskLayerIndex;
-  }
-
-private:
-  ParentLayerIntRect mClipRect;
-
-  // Optionally, specifies a mask layer that's part of the clip.
-  // This is an index into the MetricsMaskLayers array on the Layer.
-  Maybe<size_t> mMaskLayerIndex;
-};
-
-typedef Maybe<LayerClip> MaybeLayerClip;  // for passing over IPDL
-
-/**
- * Metadata about a scroll frame that's stored in the layer tree for use by
- * the compositor (including APZ). This includes the scroll frame's FrameMetrics,
- * as well as other metadata. We don't put the other metadata into FrameMetrics
- * to avoid FrameMetrics becoming too bloated (as a FrameMetrics is e.g. sent
- * over IPC for every repaint request for every active scroll frame).
- */
-struct ScrollMetadata {
-  friend struct IPC::ParamTraits<mozilla::layers::ScrollMetadata>;
-
-  typedef FrameMetrics::ViewID ViewID;
-public:
-  static StaticAutoPtr<const ScrollMetadata> sNullMetadata;   // We sometimes need an empty metadata
-
-  ScrollMetadata()
-    : mMetrics()
-    , mSnapInfo()
-    , mScrollParentId(FrameMetrics::NULL_SCROLL_ID)
-    , mBackgroundColor()
-    , mContentDescription()
-    , mLineScrollAmount(0, 0)
-    , mPageScrollAmount(0, 0)
-    , mScrollClip()
-    , mHasScrollgrab(false)
-    , mIsLayersIdRoot(false)
-    , mIsAutoDirRootContentRTL(false)
-    , mUsesContainerScrolling(false)
-    , mForceDisableApz(false)
-    , mOverscrollBehavior()
-  {}
-
-  bool operator==(const ScrollMetadata& aOther) const
-  {
-    return mMetrics == aOther.mMetrics &&
-           mSnapInfo == aOther.mSnapInfo &&
-           mScrollParentId == aOther.mScrollParentId &&
-           mBackgroundColor == aOther.mBackgroundColor &&
-           // don't compare mContentDescription
-           mLineScrollAmount == aOther.mLineScrollAmount &&
-           mPageScrollAmount == aOther.mPageScrollAmount &&
-           mScrollClip == aOther.mScrollClip &&
-           mHasScrollgrab == aOther.mHasScrollgrab &&
-           mIsLayersIdRoot == aOther.mIsLayersIdRoot &&
-           mIsAutoDirRootContentRTL == aOther.mIsAutoDirRootContentRTL &&
-           mUsesContainerScrolling == aOther.mUsesContainerScrolling &&
-           mForceDisableApz == aOther.mForceDisableApz &&
-           mDisregardedDirection == aOther.mDisregardedDirection &&
-           mOverscrollBehavior == aOther.mOverscrollBehavior;
-  }
-
-  bool operator!=(const ScrollMetadata& aOther) const
-  {
-    return !operator==(aOther);
-  }
-
-  bool IsDefault() const
-  {
-    ScrollMetadata def;
-
-    def.mMetrics.SetPresShellId(mMetrics.GetPresShellId());
-    return (def == *this);
-  }
-
-  FrameMetrics& GetMetrics() { return mMetrics; }
-  const FrameMetrics& GetMetrics() const { return mMetrics; }
-
-  void SetSnapInfo(ScrollSnapInfo&& aSnapInfo) {
-    mSnapInfo = std::move(aSnapInfo);
-  }
-  const ScrollSnapInfo& GetSnapInfo() const { return mSnapInfo; }
-
-  ViewID GetScrollParentId() const {
-    return mScrollParentId;
-  }
-
-  void SetScrollParentId(ViewID aParentId) {
-    mScrollParentId = aParentId;
-  }
-  const gfx::Color& GetBackgroundColor() const {
-    return mBackgroundColor;
-  }
-  void SetBackgroundColor(const gfx::Color& aBackgroundColor) {
-    mBackgroundColor = aBackgroundColor;
-  }
-  const nsCString& GetContentDescription() const {
-    return mContentDescription;
-  }
-  void SetContentDescription(const nsCString& aContentDescription) {
-    mContentDescription = aContentDescription;
-  }
-  const LayoutDeviceIntSize& GetLineScrollAmount() const {
-    return mLineScrollAmount;
-  }
-  void SetLineScrollAmount(const LayoutDeviceIntSize& size) {
-    mLineScrollAmount = size;
-  }
-  const LayoutDeviceIntSize& GetPageScrollAmount() const {
-    return mPageScrollAmount;
-  }
-  void SetPageScrollAmount(const LayoutDeviceIntSize& size) {
-    mPageScrollAmount = size;
-  }
-
-  void SetScrollClip(const Maybe<LayerClip>& aScrollClip) {
-    mScrollClip = aScrollClip;
-  }
-  const Maybe<LayerClip>& GetScrollClip() const {
-    return mScrollClip;
-  }
-  bool HasScrollClip() const {
-    return mScrollClip.isSome();
-  }
-  const LayerClip& ScrollClip() const {
-    return mScrollClip.ref();
-  }
-  LayerClip& ScrollClip() {
-    return mScrollClip.ref();
-  }
-
-  bool HasMaskLayer() const {
-    return HasScrollClip() && ScrollClip().GetMaskLayerIndex();
-  }
-  Maybe<ParentLayerIntRect> GetClipRect() const {
-    return mScrollClip.isSome() ? Some(mScrollClip->GetClipRect()) : Nothing();
-  }
-
-  void SetHasScrollgrab(bool aHasScrollgrab) {
-    mHasScrollgrab = aHasScrollgrab;
-  }
-  bool GetHasScrollgrab() const {
-    return mHasScrollgrab;
-  }
-  void SetIsLayersIdRoot(bool aValue) {
-    mIsLayersIdRoot = aValue;
-  }
-  bool IsLayersIdRoot() const {
-    return mIsLayersIdRoot;
-  }
-  void SetIsAutoDirRootContentRTL(bool aValue) {
-    mIsAutoDirRootContentRTL = aValue;
-  }
-  bool IsAutoDirRootContentRTL() const {
-    return mIsAutoDirRootContentRTL;
-  }
-  // Implemented out of line because the implementation needs gfxPrefs.h
-  // and we don't want to include that from FrameMetrics.h.
-  void SetUsesContainerScrolling(bool aValue);
-  bool UsesContainerScrolling() const {
-    return mUsesContainerScrolling;
-  }
-  void SetForceDisableApz(bool aForceDisable) {
-    mForceDisableApz = aForceDisable;
-  }
-  bool IsApzForceDisabled() const {
-    return mForceDisableApz;
-  }
-
-  // For more details about the concept of a disregarded direction, refer to the
-  // code which defines mDisregardedDirection.
-  Maybe<ScrollDirection> GetDisregardedDirection() const {
-    return mDisregardedDirection;
-  }
-  void
-  SetDisregardedDirection(const Maybe<ScrollDirection>& aValue) {
-    mDisregardedDirection = aValue;
-  }
-
-  void SetOverscrollBehavior(const OverscrollBehaviorInfo& aOverscrollBehavior) {
-    mOverscrollBehavior = aOverscrollBehavior;
-  }
-  const OverscrollBehaviorInfo& GetOverscrollBehavior() const {
-    return mOverscrollBehavior;
-  }
-
-private:
-  FrameMetrics mMetrics;
-
-  // Information used to determine where to snap to for a given scroll.
-  ScrollSnapInfo mSnapInfo;
-
-  // The ViewID of the scrollable frame to which overscroll should be handed off.
-  ViewID mScrollParentId;
-
-  // The background color to use when overscrolling.
-  gfx::Color mBackgroundColor;
-
-  // A description of the content element corresponding to this frame.
-  // This is empty unless this is a scrollable layer and the
-  // apz.printtree pref is turned on.
-  nsCString mContentDescription;
-
-  // The value of GetLineScrollAmount(), for scroll frames.
-  LayoutDeviceIntSize mLineScrollAmount;
-
-  // The value of GetPageScrollAmount(), for scroll frames.
-  LayoutDeviceIntSize mPageScrollAmount;
-
-  // A clip to apply when compositing the layer bearing this ScrollMetadata,
-  // after applying any transform arising from scrolling this scroll frame.
-  // Note that, unlike most other fields of ScrollMetadata, this is allowed
-  // to differ between different layers scrolled by the same scroll frame.
-  // TODO: Group the fields of ScrollMetadata into sub-structures to separate
-  // fields with this property better.
-  Maybe<LayerClip> mScrollClip;
-
-  // Whether or not this frame is for an element marked 'scrollgrab'.
-  bool mHasScrollgrab:1;
-
-  // Whether these framemetrics are for the root scroll frame (root element if
-  // we don't have a root scroll frame) for its layers id.
-  bool mIsLayersIdRoot:1;
-
-  // The AutoDirRootContent is the <body> element in an HTML document, or the
-  // root scrollframe if there is no body. This member variable indicates
-  // whether this element's content in the horizontal direction starts from
-  // right to left (e.g. it's true either if "writing-mode: vertical-rl", or
-  // "writing-mode: horizontal-tb; direction: rtl" in CSS).
-  // When we do auto-dir scrolling (@see mozilla::WheelDeltaAdjustmentStrategy
-  // or refer to bug 1358017 for details), setting a pref can make the code use
-  // the writing mode of this root element instead of the target scrollframe,
-  // and so we need to know if the writing mode is RTL or not.
-  bool mIsAutoDirRootContentRTL:1;
-
-  // True if scrolling using containers, false otherwise. This can be removed
-  // when containerful scrolling is eliminated.
-  bool mUsesContainerScrolling:1;
-
-  // Whether or not the compositor should actually do APZ-scrolling on this
-  // scrollframe.
-  bool mForceDisableApz:1;
-
-  // The disregarded direction means the direction which is disregarded anyway,
-  // even if the scroll frame overflows in that direction and the direction is
-  // specified as scrollable. This could happen in some scenarios, for instance,
-  // a single-line text control frame should disregard wheel scroll in
-  // its block-flow direction even if it overflows in that direction.
-  Maybe<ScrollDirection> mDisregardedDirection;
-
-  // The overscroll behavior for this scroll frame.
-  OverscrollBehaviorInfo mOverscrollBehavior;
-
-  // WARNING!!!!
-  //
-  // When adding new fields to ScrollMetadata, the following places should be
-  // updated to include them (as needed):
-  //    1. ScrollMetadata::operator ==
-  //    2. AsyncPanZoomController::NotifyLayersUpdated
-  //    3. The ParamTraits specialization in GfxMessageUtils.h and/or
-  //       LayersMessageUtils.h
-  //
-  // Please add new fields above this comment.
-};
-
-/**
- * This class allows us to uniquely identify a scrollable layer. The
- * mLayersId identifies the layer tree (corresponding to a child process
- * and/or tab) that the scrollable layer belongs to. The mPresShellId
- * is a temporal identifier (corresponding to the document loaded that
- * contains the scrollable layer, which may change over time). The
- * mScrollId corresponds to the actual frame that is scrollable.
- */
-struct ScrollableLayerGuid {
-  LayersId mLayersId;
-  uint32_t mPresShellId;
-  FrameMetrics::ViewID mScrollId;
-
-  ScrollableLayerGuid()
-    : mLayersId{0}
-    , mPresShellId(0)
-    , mScrollId(0)
-  {
-  }
-
-  ScrollableLayerGuid(LayersId aLayersId, uint32_t aPresShellId,
-                      FrameMetrics::ViewID aScrollId)
-    : mLayersId(aLayersId)
-    , mPresShellId(aPresShellId)
-    , mScrollId(aScrollId)
-  {
-  }
-
-  ScrollableLayerGuid(LayersId aLayersId, const FrameMetrics& aMetrics)
-    : mLayersId(aLayersId)
-    , mPresShellId(aMetrics.GetPresShellId())
-    , mScrollId(aMetrics.GetScrollId())
-  {
-  }
-
-  ScrollableLayerGuid(const ScrollableLayerGuid& other)
-    : mLayersId(other.mLayersId)
-    , mPresShellId(other.mPresShellId)
-    , mScrollId(other.mScrollId)
-  {
-  }
-
-  ~ScrollableLayerGuid()
-  {
-  }
-
-  bool operator==(const ScrollableLayerGuid& other) const
-  {
-    return mLayersId == other.mLayersId
-        && mPresShellId == other.mPresShellId
-        && mScrollId == other.mScrollId;
-  }
-
-  bool operator!=(const ScrollableLayerGuid& other) const
-  {
-    return !(*this == other);
-  }
-
-  bool operator<(const ScrollableLayerGuid& other) const
-  {
-    if (mLayersId < other.mLayersId) {
-      return true;
-    }
-    if (mLayersId == other.mLayersId) {
-      if (mPresShellId < other.mPresShellId) {
-        return true;
-      }
-      if (mPresShellId == other.mPresShellId) {
-        return mScrollId < other.mScrollId;
-      }
-    }
-    return false;
-  }
-
-  // Helper structs to use as hash/equality functions in std::unordered_map. e.g.
-  // std::unordered_map<ScrollableLayerGuid,
-  //                    ValueType,
-  //                    ScrollableLayerGuid::HashFn> myMap;
-  // std::unordered_map<ScrollableLayerGuid,
-  //                    ValueType,
-  //                    ScrollableLayerGuid::HashIgnoringPresShellFn,
-  //                    ScrollableLayerGuid::EqualIgnoringPresShellFn> myMap;
-
-  struct HashFn
-  {
-    std::size_t operator()(const ScrollableLayerGuid& aGuid) const
-    {
-      return HashGeneric(uint64_t(aGuid.mLayersId),
-                         aGuid.mPresShellId,
-                         aGuid.mScrollId);
-    }
-  };
-
-  struct HashIgnoringPresShellFn
-  {
-    std::size_t operator()(const ScrollableLayerGuid& aGuid) const
-    {
-      return HashGeneric(uint64_t(aGuid.mLayersId),
-                         aGuid.mScrollId);
-    }
-  };
-
-  struct EqualIgnoringPresShellFn
-  {
-    bool operator()(const ScrollableLayerGuid& lhs, const ScrollableLayerGuid& rhs) const
-    {
-      return lhs.mLayersId == rhs.mLayersId
-          && lhs.mScrollId == rhs.mScrollId;
-    }
-  };
-};
-
-template <int LogLevel>
-gfx::Log<LogLevel>& operator<<(gfx::Log<LogLevel>& log, const ScrollableLayerGuid& aGuid) {
-  return log << '(' << uint64_t(aGuid.mLayersId) << ',' << aGuid.mPresShellId << ',' << aGuid.mScrollId << ')';
-}
-
 struct ZoomConstraints {
   bool mAllowZoom;
   bool mAllowDoubleTapZoom;
   CSSToParentLayerScale mMinZoom;
   CSSToParentLayerScale mMaxZoom;
 
   ZoomConstraints()
     : mAllowZoom(true)
@@ -1336,14 +65,12 @@ struct ZoomConstraints {
   {
     return !(*this == other);
   }
 };
 
 
 typedef Maybe<ZoomConstraints> MaybeZoomConstraints;
 
-typedef std::map<FrameMetrics::ViewID,ScrollUpdateInfo> ScrollUpdatesMap;
-
 } // namespace layers
 } // namespace mozilla
 
-#endif /* GFX_FRAMEMETRICS_H */
+#endif /* GFX_ZOOMCONSTRAINTS_H */
--- a/gfx/layers/apz/public/APZUpdater.h
+++ b/gfx/layers/apz/public/APZUpdater.h
@@ -96,20 +96,20 @@ public:
 
   void NotifyLayerTreeAdopted(LayersId aLayersId,
                               const RefPtr<APZUpdater>& aOldUpdater);
   void NotifyLayerTreeRemoved(LayersId aLayersId);
 
   bool GetAPZTestData(LayersId aLayersId, APZTestData* aOutData);
 
   void SetTestAsyncScrollOffset(LayersId aLayersId,
-                                const FrameMetrics::ViewID& aScrollId,
+                                const ScrollableLayerGuid::ViewID& aScrollId,
                                 const CSSPoint& aOffset);
   void SetTestAsyncZoom(LayersId aLayersId,
-                        const FrameMetrics::ViewID& aScrollId,
+                        const ScrollableLayerGuid::ViewID& aScrollId,
                         const LayerToParentLayerScale& aZoom);
 
   // This can only be called on the updater thread.
   const WebRenderScrollData* GetScrollData(LayersId aLayersId) const;
 
   /**
    * This can be used to assert that the current thread is the
    * updater thread (which samples the async transform).
--- a/gfx/layers/apz/public/GeckoContentController.h
+++ b/gfx/layers/apz/public/GeckoContentController.h
@@ -2,23 +2,23 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_layers_GeckoContentController_h
 #define mozilla_layers_GeckoContentController_h
 
-#include "FrameMetrics.h"               // for FrameMetrics, etc
 #include "InputData.h"                  // for PinchGestureInput
 #include "Units.h"                      // for CSSPoint, CSSRect, etc
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT_HELPER2
 #include "mozilla/DefineEnum.h"         // for MOZ_DEFINE_ENUM
 #include "mozilla/EventForwards.h"      // for Modifiers
 #include "mozilla/layers/RepaintRequest.h" // for RepaintRequest
+#include "mozilla/layers/ScrollableLayerGuid.h" // for ScrollableLayerGuid, etc
 #include "nsISupportsImpl.h"
 
 namespace mozilla {
 
 class Runnable;
 
 namespace layers {
 
@@ -143,26 +143,26 @@ public:
    */
   virtual void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
                                     APZStateChange aChange,
                                     int aArg = 0) {}
 
   /**
    * Notify content of a MozMouseScrollFailed event.
    */
-  virtual void NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId, const nsString& aEvent)
+  virtual void NotifyMozMouseScrollEvent(const ScrollableLayerGuid::ViewID& aScrollId, const nsString& aEvent)
   {}
 
   /**
    * Notify content that the repaint requests have been flushed.
    */
   virtual void NotifyFlushComplete() = 0;
 
-  virtual void NotifyAsyncScrollbarDragRejected(const FrameMetrics::ViewID& aScrollId) = 0;
-  virtual void NotifyAsyncAutoscrollRejected(const FrameMetrics::ViewID& aScrollId) = 0;
+  virtual void NotifyAsyncScrollbarDragRejected(const ScrollableLayerGuid::ViewID& aScrollId) = 0;
+  virtual void NotifyAsyncAutoscrollRejected(const ScrollableLayerGuid::ViewID& aScrollId) = 0;
 
   virtual void CancelAutoscroll(const ScrollableLayerGuid& aGuid) = 0;
 
   virtual void UpdateOverscrollVelocity(float aX, float aY, bool aIsRootContent) {}
   virtual void UpdateOverscrollOffset(float aX, float aY, bool aIsRootContent) {}
 
   GeckoContentController() {}
 
--- a/gfx/layers/apz/public/IAPZCTreeManager.h
+++ b/gfx/layers/apz/public/IAPZCTreeManager.h
@@ -4,18 +4,18 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_layers_IAPZCTreeManager_h
 #define mozilla_layers_IAPZCTreeManager_h
 
 #include <stdint.h>                     // for uint64_t, uint32_t
 
-#include "FrameMetrics.h"               // for FrameMetrics, etc
 #include "mozilla/layers/LayersTypes.h" // for TouchBehaviorFlags
+#include "mozilla/layers/ScrollableLayerGuid.h" // for ScrollableLayerGuid, etc
 #include "nsTArrayForwardDeclare.h"     // for nsTArray, nsTArray_Impl, etc
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
 #include "Units.h"                      // for CSSRect, etc
 
 namespace mozilla {
 namespace layers {
 
 class APZInputBridge;
@@ -74,17 +74,17 @@ public:
    * When the event regions code is enabled, this function should be invoked to
    * to confirm the target of the input block. This is only needed in cases
    * where the initial input event of the block hit a dispatch-to-content region
    * but is safe to call for all input blocks. This function should always be
    * invoked on the controller thread.
    * The different elements in the array of targets correspond to the targets
    * for the different touch points. In the case where the touch point has no
    * target, or the target is not a scrollable frame, the target's |mScrollId|
-   * should be set to FrameMetrics::NULL_SCROLL_ID.
+   * should be set to ScrollableLayerGuid::NULL_SCROLL_ID.
    */
   virtual void SetTargetAPZC(
       uint64_t aInputBlockId,
       const nsTArray<ScrollableLayerGuid>& aTargets) = 0;
 
   /**
    * Updates any zoom constraints contained in the <meta name="viewport"> tag.
    * If the |aConstraints| is Nothing() then previously-provided constraints for
--- a/gfx/layers/apz/public/MetricsSharingController.h
+++ b/gfx/layers/apz/public/MetricsSharingController.h
@@ -20,17 +20,17 @@ class MetricsSharingController
 public:
   NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
 
   virtual base::ProcessId RemotePid() = 0;
   virtual bool StartSharingMetrics(mozilla::ipc::SharedMemoryBasic::Handle aHandle,
                                    CrossProcessMutexHandle aMutexHandle,
                                    LayersId aLayersId,
                                    uint32_t aApzcId) = 0;
-  virtual bool StopSharingMetrics(FrameMetrics::ViewID aScrollId,
+  virtual bool StopSharingMetrics(ScrollableLayerGuid::ViewID aScrollId,
                                   uint32_t aApzcId) = 0;
 
 protected:
   virtual ~MetricsSharingController() {}
 };
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -911,17 +911,18 @@ APZCTreeManager::PrepareNodeForLayer(con
   // If we get here, aLayer is a scrollable layer and somebody
   // has registered a GeckoContentController for it, so we need to ensure
   // it has an APZC instance to manage its scrolling.
 
   // aState.mApzcMap allows reusing the exact same APZC instance for different layers
   // with the same FrameMetrics data. This is needed because in some cases content
   // that is supposed to scroll together is split into multiple layers because of
   // e.g. non-scrolling content interleaved in z-index order.
-  ScrollableLayerGuid guid(aLayersId, aMetrics);
+  ScrollableLayerGuid guid(aLayersId, aMetrics.GetPresShellId(),
+                           aMetrics.GetScrollId());
   auto insertResult = aState.mApzcMap.insert(std::make_pair(guid, static_cast<AsyncPanZoomController*>(nullptr)));
   if (!insertResult.second) {
     apzc = insertResult.first->second;
     PrintAPZCInfo(aLayer, apzc);
   }
   APZCTM_LOG("Found APZC %p for layer %p with identifiers %" PRIx64 " %" PRId64 "\n",
       apzc, aLayer.GetLayer(), uint64_t(guid.mLayersId), guid.mScrollId);
 
@@ -1283,17 +1284,17 @@ APZCTreeManager::ReceiveInputEvent(Input
           if (untransformedRefPoint) {
             mouseInput.mOrigin = *untransformedRefPoint;
           }
         } else {
           // Likewise, if the input was targeted at a scrollbar, we don't want to
           // apply the callback transform in the main thread, so we remove the
           // scrollid from the guid. We need to keep the layersId intact so
           // that the response from the child process doesn't get discarded.
-          aOutTargetGuid->mScrollId = FrameMetrics::NULL_SCROLL_ID;
+          aOutTargetGuid->mScrollId = ScrollableLayerGuid::NULL_SCROLL_ID;
         }
       }
       break;
     } case SCROLLWHEEL_INPUT: {
       FlushRepaintsToClearScreenToGeckoTransform();
 
       ScrollWheelInput& wheelInput = aEvent.AsScrollWheelInput();
       wheelInput.mHandledByAPZ = WillHandleInput(wheelInput);
@@ -1806,17 +1807,17 @@ APZCTreeManager::ProcessTouchInputForScr
   // Since the input was targeted at a scrollbar:
   //    - The original touch event (which will be sent on to content) will
   //      not be untransformed.
   //    - We don't want to apply the callback transform in the main thread,
   //      so we remove the scrollid from the guid.
   // Both of these match the behaviour of mouse events that target a scrollbar;
   // see the code for handling mouse events in ReceiveInputEvent() for
   // additional explanation.
-  aOutTargetGuid->mScrollId = FrameMetrics::NULL_SCROLL_ID;
+  aOutTargetGuid->mScrollId = ScrollableLayerGuid::NULL_SCROLL_ID;
 
   return result;
 }
 
 void
 APZCTreeManager::SetupScrollbarDrag(MouseInput& aMouseInput,
                                     const HitTestingTreeNodeAutoLock& aScrollThumbNode,
                                     AsyncPanZoomController* aApzc)
@@ -2453,17 +2454,17 @@ static bool
 GuidComparatorIgnoringPresShell(const ScrollableLayerGuid& aOne, const ScrollableLayerGuid& aTwo)
 {
   return aOne.mLayersId == aTwo.mLayersId
       && aOne.mScrollId == aTwo.mScrollId;
 }
 
 already_AddRefed<AsyncPanZoomController>
 APZCTreeManager::GetTargetAPZC(const LayersId& aLayersId,
-                               const FrameMetrics::ViewID& aScrollId)
+                               const ScrollableLayerGuid::ViewID& aScrollId)
 {
   MutexAutoLock lock(mMapLock);
   ScrollableLayerGuid guid(aLayersId, 0, aScrollId);
   auto it = mApzcMap.find(guid);
   RefPtr<AsyncPanZoomController> apzc = (it != mApzcMap.end() ? it->second : nullptr);
   return apzc.forget();
 }
 
@@ -2532,29 +2533,29 @@ APZCTreeManager::GetAPZCAtPointWR(const 
     // here allows those tests which are not specifically
     // testing the hit-test algorithm to still work.
     result = FindRootApzcForLayersId(mRootLayersId);
     *aOutHitResult = CompositorHitTestFlags::eVisibleToHitTest;
     return result.forget();
   }
 
   wr::WrPipelineId pipelineId;
-  FrameMetrics::ViewID scrollId;
+  ScrollableLayerGuid::ViewID scrollId;
   gfx::CompositorHitTestInfo hitInfo;
   bool hitSomething = wr->HitTest(wr::ToWorldPoint(aHitTestPoint),
       pipelineId, scrollId, hitInfo);
   if (!hitSomething) {
     return result.forget();
   }
 
   LayersId layersId = wr::AsLayersId(pipelineId);
   result = GetTargetAPZC(layersId, scrollId);
   if (!result) {
     // It falls back to the root
-    MOZ_ASSERT(scrollId == FrameMetrics::NULL_SCROLL_ID);
+    MOZ_ASSERT(scrollId == ScrollableLayerGuid::NULL_SCROLL_ID);
     result = FindRootApzcForLayersId(layersId);
     MOZ_ASSERT(result);
   }
 
   const bool isScrollbar = hitInfo.contains(gfx::CompositorHitTestFlags::eScrollbar);
   const bool isScrollbarThumb = hitInfo.contains(gfx::CompositorHitTestFlags::eScrollbarThumb);
   const ScrollDirection direction = hitInfo.contains(gfx::CompositorHitTestFlags::eScrollbarVertical)
                             ? ScrollDirection::eVertical
@@ -2594,17 +2595,17 @@ APZCTreeManager::BuildOverscrollHandoffC
   // needed to deal with scroll info layers, because they participate in handoff
   // but do not follow the expected layer tree structure. If there are no
   // scroll parent links we just walk up the tree to find the scroll parent.
   OverscrollHandoffChain* result = new OverscrollHandoffChain;
   AsyncPanZoomController* apzc = aInitialTarget;
   while (apzc != nullptr) {
     result->Add(apzc);
 
-    if (apzc->GetScrollHandoffParentId() == FrameMetrics::NULL_SCROLL_ID) {
+    if (apzc->GetScrollHandoffParentId() == ScrollableLayerGuid::NULL_SCROLL_ID) {
       if (!apzc->IsRootForLayersId()) {
         // This probably indicates a bug or missed case in layout code
         NS_WARNING("Found a non-root APZ with no handoff parent");
       }
       apzc = apzc->GetParent();
       continue;
     }
 
@@ -2663,17 +2664,17 @@ APZCTreeManager::GetTargetApzcForNode(Hi
 {
   for (const HitTestingTreeNode* n = aNode;
        n && n->GetLayersId() == aNode->GetLayersId();
        n = n->GetParent()) {
     if (n->GetApzc()) {
       APZCTM_LOG("Found target %p using ancestor lookup\n", n->GetApzc());
       return n->GetApzc();
     }
-    if (n->GetFixedPosTarget() != FrameMetrics::NULL_SCROLL_ID) {
+    if (n->GetFixedPosTarget() != ScrollableLayerGuid::NULL_SCROLL_ID) {
       RefPtr<AsyncPanZoomController> fpTarget =
           GetTargetAPZC(n->GetLayersId(), n->GetFixedPosTarget());
       APZCTM_LOG("Found target APZC %p using fixed-pos lookup on %" PRIu64 "\n", fpTarget.get(), n->GetFixedPosTarget());
       return fpTarget.get();
     }
   }
   return nullptr;
 }
--- a/gfx/layers/apz/src/APZCTreeManager.h
+++ b/gfx/layers/apz/src/APZCTreeManager.h
@@ -302,17 +302,17 @@ public:
    * When the event regions code is enabled, this function should be invoked to
    * to confirm the target of the input block. This is only needed in cases
    * where the initial input event of the block hit a dispatch-to-content region
    * but is safe to call for all input blocks. This function should always be
    * invoked on the controller thread.
    * The different elements in the array of targets correspond to the targets
    * for the different touch points. In the case where the touch point has no
    * target, or the target is not a scrollable frame, the target's |mScrollId|
-   * should be set to FrameMetrics::NULL_SCROLL_ID.
+   * should be set to ScrollableLayerGuid::NULL_SCROLL_ID.
    * Note: For mouse events that start a scrollbar drag, both SetTargetAPZC()
    *       and StartScrollbarDrag() will be called, and the calls may happen
    *       in either order. That's fine - whichever arrives first will confirm
    *       the block, and StartScrollbarDrag() will fill in the drag metrics.
    *       If the block is confirmed before we have drag metrics, some events
    *       in the drag block may be handled as no-ops until the drag metrics
    *       arrive.
    */
@@ -577,17 +577,17 @@ public:
      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,
                                                          gfx::CompositorHitTestInfo* aOutHitResult,
                                                          HitTestingTreeNodeAutoLock* aOutScrollbarNode = nullptr);
   already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const LayersId& aLayersId,
-                                                         const FrameMetrics::ViewID& aScrollId);
+                                                         const ScrollableLayerGuid::ViewID& aScrollId);
   ScreenToParentLayerMatrix4x4 GetScreenToApzcTransform(const AsyncPanZoomController *aApzc) const;
   ParentLayerToScreenMatrix4x4 GetApzcToGeckoTransform(const AsyncPanZoomController *aApzc) const;
   ScreenPoint GetCurrentMousePosition() const;
 
   /**
    * Process a movement of the dynamic toolbar by |aDeltaY| over the time
    * period from |aStartTimestampMs| to |aEndTimestampMs|.
    * This is used to track velocities accurately in the presence of movement
--- a/gfx/layers/apz/src/APZUpdater.cpp
+++ b/gfx/layers/apz/src/APZUpdater.cpp
@@ -304,17 +304,17 @@ APZUpdater::GetAPZTestData(LayersId aLay
   // Wait until the task posted above has run and populated aOutData and ret
   waiter.Wait();
 
   return ret;
 }
 
 void
 APZUpdater::SetTestAsyncScrollOffset(LayersId aLayersId,
-                                     const FrameMetrics::ViewID& aScrollId,
+                                     const ScrollableLayerGuid::ViewID& aScrollId,
                                      const CSSPoint& aOffset)
 {
   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
   RefPtr<APZCTreeManager> apz = mApz;
   RunOnUpdaterThread(aLayersId, NS_NewRunnableFunction(
     "APZUpdater::SetTestAsyncScrollOffset",
     [=]() {
       RefPtr<AsyncPanZoomController> apzc = apz->GetTargetAPZC(aLayersId, aScrollId);
@@ -324,17 +324,17 @@ APZUpdater::SetTestAsyncScrollOffset(Lay
         NS_WARNING("Unable to find APZC in SetTestAsyncScrollOffset");
       }
     }
   ));
 }
 
 void
 APZUpdater::SetTestAsyncZoom(LayersId aLayersId,
-                             const FrameMetrics::ViewID& aScrollId,
+                             const ScrollableLayerGuid::ViewID& aScrollId,
                              const LayerToParentLayerScale& aZoom)
 {
   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
   RefPtr<APZCTreeManager> apz = mApz;
   RunOnUpdaterThread(aLayersId, NS_NewRunnableFunction(
     "APZUpdater::SetTestAsyncZoom",
     [=]() {
       RefPtr<AsyncPanZoomController> apzc = apz->GetTargetAPZC(aLayersId, aScrollId);
--- a/gfx/layers/apz/src/AsyncDragMetrics.h
+++ b/gfx/layers/apz/src/AsyncDragMetrics.h
@@ -2,17 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_layers_DragMetrics_h
 #define mozilla_layers_DragMetrics_h
 
-#include "FrameMetrics.h"
+#include "mozilla/layers/ScrollableLayerGuid.h"
 #include "LayersTypes.h"
 #include "mozilla/Maybe.h"
 
 namespace IPC {
 template <typename T> struct ParamTraits;
 } // namespace IPC
 
 namespace mozilla {
@@ -26,29 +26,29 @@ public:
   // IPC constructor
   AsyncDragMetrics()
     : mViewId(0)
     , mPresShellId(0)
     , mDragStartSequenceNumber(0)
     , mScrollbarDragOffset(0)
   {}
 
-  AsyncDragMetrics(const FrameMetrics::ViewID& aViewId,
+  AsyncDragMetrics(const ScrollableLayerGuid::ViewID& aViewId,
                    uint32_t aPresShellId,
                    uint64_t aDragStartSequenceNumber,
                    CSSCoord aScrollbarDragOffset,
                    ScrollDirection aDirection)
     : mViewId(aViewId)
     , mPresShellId(aPresShellId)
     , mDragStartSequenceNumber(aDragStartSequenceNumber)
     , mScrollbarDragOffset(aScrollbarDragOffset)
     , mDirection(Some(aDirection))
   {}
 
-  FrameMetrics::ViewID mViewId;
+  ScrollableLayerGuid::ViewID mViewId;
   uint32_t mPresShellId;
   uint64_t mDragStartSequenceNumber;
   CSSCoord mScrollbarDragOffset;  // relative to the thumb's start offset
   Maybe<ScrollDirection> mDirection;
 };
 
 }
 }
--- a/gfx/layers/apz/src/AsyncPanZoomAnimation.h
+++ b/gfx/layers/apz/src/AsyncPanZoomAnimation.h
@@ -6,23 +6,24 @@
 
 #ifndef mozilla_layers_AsyncPanZoomAnimation_h_
 #define mozilla_layers_AsyncPanZoomAnimation_h_
 
 #include "APZUtils.h"
 #include "base/message_loop.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/TimeStamp.h"
-#include "FrameMetrics.h"
 #include "nsISupportsImpl.h"
 #include "nsTArray.h"
 
 namespace mozilla {
 namespace layers {
 
+struct FrameMetrics;
+
 class WheelScrollAnimation;
 class KeyboardScrollAnimation;
 class SmoothScrollAnimation;
 
 class AsyncPanZoomAnimation {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncPanZoomAnimation)
 
 public:
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -4847,17 +4847,18 @@ void AsyncPanZoomController::GetGuid(Scr
 {
   if (aGuidOut) {
     *aGuidOut = GetGuid();
   }
 }
 
 ScrollableLayerGuid AsyncPanZoomController::GetGuid() const
 {
-  return ScrollableLayerGuid(mLayersId, Metrics());
+  return ScrollableLayerGuid(mLayersId, Metrics().GetPresShellId(),
+                             Metrics().GetScrollId());
 }
 
 void AsyncPanZoomController::UpdateSharedCompositorFrameMetrics()
 {
   mRecursiveMutex.AssertCurrentThreadIn();
 
   FrameMetrics* frame = mSharedFrameMetricsBuffer ?
       static_cast<FrameMetrics*>(mSharedFrameMetricsBuffer->memory()) : nullptr;
--- a/gfx/layers/apz/src/AsyncPanZoomController.h
+++ b/gfx/layers/apz/src/AsyncPanZoomController.h
@@ -1337,17 +1337,17 @@ private:
   RefPtr<AsyncPanZoomController> mParent;
 
 
   /* ===================================================================
    * The functions and members in this section are used for scrolling,
    * including handing off scroll to another APZC, and overscrolling.
    */
 public:
-  FrameMetrics::ViewID GetScrollHandoffParentId() const {
+  ScrollableLayerGuid::ViewID GetScrollHandoffParentId() const {
     return mScrollMetadata.GetScrollParentId();
   }
 
   /**
    * Attempt to scroll in response to a touch-move from |aStartPoint| to
    * |aEndPoint|, which are in our (transformed) screen coordinates.
    * Due to overscroll handling, there may not actually have been a touch-move
    * at these points, but this function will scroll as if there had been.
--- a/gfx/layers/apz/src/AutoscrollAnimation.cpp
+++ b/gfx/layers/apz/src/AutoscrollAnimation.cpp
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "AutoscrollAnimation.h"
 
 #include <cmath>  // for sqrtf()
 
 #include "AsyncPanZoomController.h"
+#include "FrameMetrics.h"
 #include "mozilla/Telemetry.h"                  // for Telemetry
 
 namespace mozilla {
 namespace layers {
 
 // Helper function for AutoscrollAnimation::DoSample().
 // Basically copied as-is from toolkit/content/browser-content.js.
 static float
--- a/gfx/layers/apz/src/FocusState.cpp
+++ b/gfx/layers/apz/src/FocusState.cpp
@@ -16,18 +16,18 @@ namespace layers {
 
 FocusState::FocusState()
   : mMutex("FocusStateMutex")
   , mLastAPZProcessedEvent(1)
   , mLastContentProcessedEvent(0)
   , mFocusHasKeyEventListeners(false)
   , mReceivedUpdate(false)
   , mFocusLayersId{0}
-  , mFocusHorizontalTarget(FrameMetrics::NULL_SCROLL_ID)
-  , mFocusVerticalTarget(FrameMetrics::NULL_SCROLL_ID)
+  , mFocusHorizontalTarget(ScrollableLayerGuid::NULL_SCROLL_ID)
+  , mFocusVerticalTarget(ScrollableLayerGuid::NULL_SCROLL_ID)
 {
 }
 
 uint64_t
 FocusState::LastAPZProcessedEvent() const
 {
   APZThreadUtils::AssertOnControllerThread();
   MutexAutoLock lock(mMutex);
@@ -83,18 +83,18 @@ FocusState::Update(LayersId aRootLayerTr
   mReceivedUpdate = true;
 
   // Update the focus tree with the latest target
   mFocusTree[aOriginatingLayersId] = aState;
 
   // Reset our internal state so we can recalculate it
   mFocusHasKeyEventListeners = false;
   mFocusLayersId = aRootLayerTreeId;
-  mFocusHorizontalTarget = FrameMetrics::NULL_SCROLL_ID;
-  mFocusVerticalTarget = FrameMetrics::NULL_SCROLL_ID;
+  mFocusHorizontalTarget = ScrollableLayerGuid::NULL_SCROLL_ID;
+  mFocusVerticalTarget = ScrollableLayerGuid::NULL_SCROLL_ID;
 
   // To update the focus state for the entire APZCTreeManager, we need
   // to traverse the focus tree to find the current leaf which is the global
   // focus target we can use for async keyboard scrolling
   while (true) {
     auto currentNode = mFocusTree.find(mFocusLayersId);
     if (currentNode == mFocusTree.end()) {
       FS_LOG("Setting target to nil (cannot find lt=%" PRIu64 ")\n",
@@ -198,17 +198,17 @@ FocusState::GetHorizontalTarget() const
   MutexAutoLock lock(mMutex);
 
   // There is not a scrollable layer to async scroll if
   //   1. We aren't current
   //   2. There are event listeners that could change the focus
   //   3. The target has not been layerized
   if (!IsCurrent(lock) ||
       mFocusHasKeyEventListeners ||
-      mFocusHorizontalTarget == FrameMetrics::NULL_SCROLL_ID) {
+      mFocusHorizontalTarget == ScrollableLayerGuid::NULL_SCROLL_ID) {
     return Nothing();
   }
   return Some(ScrollableLayerGuid(mFocusLayersId, 0, mFocusHorizontalTarget));
 }
 
 Maybe<ScrollableLayerGuid>
 FocusState::GetVerticalTarget() const
 {
@@ -216,17 +216,17 @@ FocusState::GetVerticalTarget() const
   MutexAutoLock lock(mMutex);
 
   // There is not a scrollable layer to async scroll if:
   //   1. We aren't current
   //   2. There are event listeners that could change the focus
   //   3. The target has not been layerized
   if (!IsCurrent(lock) ||
       mFocusHasKeyEventListeners ||
-      mFocusVerticalTarget == FrameMetrics::NULL_SCROLL_ID) {
+      mFocusVerticalTarget == ScrollableLayerGuid::NULL_SCROLL_ID) {
     return Nothing();
   }
   return Some(ScrollableLayerGuid(mFocusLayersId, 0, mFocusVerticalTarget));
 }
 
 bool
 FocusState::CanIgnoreKeyboardShortcutMisses() const
 {
--- a/gfx/layers/apz/src/FocusState.h
+++ b/gfx/layers/apz/src/FocusState.h
@@ -5,18 +5,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_layers_FocusState_h
 #define mozilla_layers_FocusState_h
 
 #include <unordered_map>    // for std::unordered_map
 #include <unordered_set>    // for std::unordered_set
 
-#include "FrameMetrics.h"   // for FrameMetrics::ViewID
 #include "mozilla/layers/FocusTarget.h" // for FocusTarget
+#include "mozilla/layers/ScrollableLayerGuid.h"   // for ViewID
 #include "mozilla/Mutex.h"  // for Mutex
 
 namespace mozilla {
 namespace layers {
 
 /**
  * This class is used for tracking chrome and content focus targets and calculating
  * global focus information from them for use by APZCTreeManager for async keyboard
@@ -162,16 +162,16 @@ private:
   // A flag that is false until the first call to Update().
   bool mReceivedUpdate;
 
   // The layer tree ID which contains the scrollable frame of the focused element
   LayersId mFocusLayersId;
   // The scrollable layer corresponding to the scrollable frame that is used to
   // scroll the focused element. This depends on the direction the user is
   // scrolling.
-  FrameMetrics::ViewID mFocusHorizontalTarget;
-  FrameMetrics::ViewID mFocusVerticalTarget;
+  ScrollableLayerGuid::ViewID mFocusHorizontalTarget;
+  ScrollableLayerGuid::ViewID mFocusVerticalTarget;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // mozilla_layers_FocusState_h
--- a/gfx/layers/apz/src/FocusTarget.h
+++ b/gfx/layers/apz/src/FocusTarget.h
@@ -4,18 +4,18 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_layers_FocusTarget_h
 #define mozilla_layers_FocusTarget_h
 
 #include <stdint.h> // for int32_t, uint32_t
 
-#include "FrameMetrics.h"        // for FrameMetrics::ViewID
 #include "mozilla/DefineEnum.h"  // for MOZ_DEFINE_ENUM
+#include "mozilla/layers/ScrollableLayerGuid.h" // for ViewID
 #include "mozilla/Variant.h"     // for Variant
 
 class nsIPresShell;
 
 namespace mozilla {
 namespace layers {
 
 /**
@@ -24,18 +24,18 @@ namespace layers {
  * it. It is created on the main thread at paint-time, but is then passed over
  * IPC to the compositor/APZ code.
  */
 class FocusTarget final
 {
 public:
   struct ScrollTargets
   {
-    FrameMetrics::ViewID mHorizontal;
-    FrameMetrics::ViewID mVertical;
+    ScrollableLayerGuid::ViewID mHorizontal;
+    ScrollableLayerGuid::ViewID mVertical;
 
     bool operator==(const ScrollTargets& aRhs) const
     {
       return mHorizontal == aRhs.mHorizontal &&
              mVertical == aRhs.mVertical;
     }
   };
 
--- a/gfx/layers/apz/src/GenericScrollAnimation.cpp
+++ b/gfx/layers/apz/src/GenericScrollAnimation.cpp
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "GenericScrollAnimation.h"
 
 #include "AsyncPanZoomController.h"
+#include "FrameMetrics.h"
 #include "gfxPrefs.h"
 #include "nsPoint.h"
 #include "ScrollAnimationPhysics.h"
 #include "ScrollAnimationBezierPhysics.h"
 #include "ScrollAnimationMSDPhysics.h"
 
 namespace mozilla {
 namespace layers {
--- a/gfx/layers/apz/src/HitTestingTreeNode.cpp
+++ b/gfx/layers/apz/src/HitTestingTreeNode.cpp
@@ -25,17 +25,17 @@ using gfx::CompositorHitTestInvisibleToH
 HitTestingTreeNode::HitTestingTreeNode(AsyncPanZoomController* aApzc,
                                        bool aIsPrimaryHolder,
                                        LayersId aLayersId)
   : mApzc(aApzc)
   , mIsPrimaryApzcHolder(aIsPrimaryHolder)
   , mLockCount(0)
   , mLayersId(aLayersId)
   , mScrollbarAnimationId(0)
-  , mFixedPosTarget(FrameMetrics::NULL_SCROLL_ID)
+  , mFixedPosTarget(ScrollableLayerGuid::NULL_SCROLL_ID)
   , mIsBackfaceHidden(false)
   , mOverride(EventRegionsOverride::NoOverride)
 {
   if (mIsPrimaryApzcHolder) {
     MOZ_ASSERT(mApzc);
   }
   MOZ_ASSERT(!mApzc || mApzc->GetLayersId() == mLayersId);
 }
@@ -130,17 +130,17 @@ HitTestingTreeNode::IsScrollbarNode() co
 ScrollDirection
 HitTestingTreeNode::GetScrollbarDirection() const
 {
   MOZ_ASSERT(IsScrollbarNode());
   MOZ_ASSERT(mScrollbarData.mDirection.isSome());
   return *mScrollbarData.mDirection;
 }
 
-FrameMetrics::ViewID
+ScrollableLayerGuid::ViewID
 HitTestingTreeNode::GetScrollTargetId() const
 {
   return mScrollbarData.mTargetViewId;
 }
 
 const uint64_t&
 HitTestingTreeNode::GetScrollbarAnimationId() const
 {
@@ -149,22 +149,22 @@ HitTestingTreeNode::GetScrollbarAnimatio
 
 const ScrollbarData&
 HitTestingTreeNode::GetScrollbarData() const
 {
   return mScrollbarData;
 }
 
 void
-HitTestingTreeNode::SetFixedPosData(FrameMetrics::ViewID aFixedPosTarget)
+HitTestingTreeNode::SetFixedPosData(ScrollableLayerGuid::ViewID aFixedPosTarget)
 {
   mFixedPosTarget = aFixedPosTarget;
 }
 
-FrameMetrics::ViewID
+ScrollableLayerGuid::ViewID
 HitTestingTreeNode::GetFixedPosTarget() const
 {
   return mFixedPosTarget;
 }
 
 void
 HitTestingTreeNode::SetPrevSibling(HitTestingTreeNode* aSibling)
 {
@@ -383,17 +383,17 @@ HitTestingTreeNode::Dump(const char* aPr
   if (mPrevSibling) {
     mPrevSibling->Dump(aPrefix);
   }
   printf_stderr("%sHitTestingTreeNode (%p) APZC (%p) g=(%s) %s%s%sr=(%s) t=(%s) c=(%s)%s%s\n",
     aPrefix, this, mApzc.get(),
     mApzc ? Stringify(mApzc->GetGuid()).c_str() : nsPrintfCString("l=0x%" PRIx64, uint64_t(mLayersId)).get(),
     (mOverride & EventRegionsOverride::ForceDispatchToContent) ? "fdtc " : "",
     (mOverride & EventRegionsOverride::ForceEmptyHitRegion) ? "fehr " : "",
-    (mFixedPosTarget != FrameMetrics::NULL_SCROLL_ID) ? nsPrintfCString("fixed=%" PRIu64 " ", mFixedPosTarget).get() : "",
+    (mFixedPosTarget != ScrollableLayerGuid::NULL_SCROLL_ID) ? nsPrintfCString("fixed=%" PRIu64 " ", mFixedPosTarget).get() : "",
     Stringify(mEventRegions).c_str(), Stringify(mTransform).c_str(),
     mClipRegion ? Stringify(mClipRegion.ref()).c_str() : "none",
     mScrollbarData.mDirection.isSome() ? " scrollbar" : "",
     IsScrollThumbNode() ? " scrollthumb" : "");
   if (mLastChild) {
     mLastChild->Dump(nsPrintfCString("%s  ", aPrefix).get());
   }
 }
--- a/gfx/layers/apz/src/HitTestingTreeNode.h
+++ b/gfx/layers/apz/src/HitTestingTreeNode.h
@@ -2,21 +2,21 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_layers_HitTestingTreeNode_h
 #define mozilla_layers_HitTestingTreeNode_h
 
-#include "FrameMetrics.h"                   // for ScrollableLayerGuid
 #include "Layers.h"
 #include "mozilla/gfx/CompositorHitTestInfo.h"
 #include "mozilla/gfx/Matrix.h"             // for Matrix4x4
 #include "mozilla/layers/LayersTypes.h"     // for EventRegions
+#include "mozilla/layers/ScrollableLayerGuid.h" // for ScrollableLayerGuid
 #include "mozilla/Maybe.h"                  // for Maybe
 #include "mozilla/RefPtr.h"               // for nsRefPtr
 
 namespace mozilla {
 namespace layers {
 
 class AsyncDragMetrics;
 class AsyncPanZoomController;
@@ -113,24 +113,24 @@ public:
 
   void SetScrollbarData(const uint64_t& aScrollbarAnimationId,
                         const ScrollbarData& aScrollbarData);
   bool MatchesScrollDragMetrics(const AsyncDragMetrics& aDragMetrics) const;
   bool IsScrollbarNode() const;  // Scroll thumb or scrollbar container layer.
   // This can only be called if IsScrollbarNode() is true
   ScrollDirection GetScrollbarDirection() const;
   bool IsScrollThumbNode() const;  // Scroll thumb container layer.
-  FrameMetrics::ViewID GetScrollTargetId() const;
+  ScrollableLayerGuid::ViewID GetScrollTargetId() const;
   const ScrollbarData& GetScrollbarData() const;
   const uint64_t& GetScrollbarAnimationId() const;
 
   /* Fixed pos info */
 
-  void SetFixedPosData(FrameMetrics::ViewID aFixedPosTarget);
-  FrameMetrics::ViewID GetFixedPosTarget() const;
+  void SetFixedPosData(ScrollableLayerGuid::ViewID aFixedPosTarget);
+  ScrollableLayerGuid::ViewID GetFixedPosTarget() const;
 
   /* Convert |aPoint| into the LayerPixel space for the layer corresponding to
    * this node. |aTransform| is the complete (content + async) transform for
    * this node. */
   Maybe<LayerPoint> Untransform(const ParentLayerPoint& aPoint,
                                 const LayerToParentLayerMatrix4x4& aTransform) const;
   /* Assuming aPoint is inside the clip region for this node, check which of the
    * event region spaces it falls inside. */
@@ -165,17 +165,17 @@ private:
   // This is only set to non-zero if WebRender is enabled, and only for HTTNs
   // where IsScrollThumbNode() returns true. It holds the animation id that we
   // use to move the thumb node to reflect async scrolling.
   uint64_t mScrollbarAnimationId;
 
   // This is set for scrollbar Container and Thumb layers.
   ScrollbarData mScrollbarData;
 
-  FrameMetrics::ViewID mFixedPosTarget;
+  ScrollableLayerGuid::ViewID mFixedPosTarget;
 
   /* Let {L,M} be the {layer, scrollable metrics} pair that this node
    * corresponds to in the layer tree. mEventRegions contains the event regions
    * from L, in the case where event-regions are enabled. If event-regions are
    * disabled, it will contain the visible region of L, which we use as an
    * approximation to the hit region for the purposes of obscuring other layers.
    * This value is in L's LayerPixels.
    */
--- a/gfx/layers/apz/src/Overscroll.h
+++ b/gfx/layers/apz/src/Overscroll.h
@@ -4,17 +4,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_layers_Overscroll_h
 #define mozilla_layers_Overscroll_h
 
 #include "AsyncPanZoomAnimation.h"
 #include "AsyncPanZoomController.h"
-#include "FrameMetrics.h"
 #include "mozilla/TimeStamp.h"
 #include "nsThreadUtils.h"
 
 namespace mozilla {
 namespace layers {
 
 // Animation used by GenericOverscrollEffect.
 class OverscrollAnimation: public AsyncPanZoomAnimation {
--- a/gfx/layers/apz/test/gtest/APZCTreeManagerTester.h
+++ b/gfx/layers/apz/test/gtest/APZCTreeManagerTester.h
@@ -57,25 +57,25 @@ protected:
   RefPtr<LayerManager> lm;
   RefPtr<Layer> root;
 
   RefPtr<TestAPZCTreeManager> manager;
   RefPtr<APZSampler> sampler;
   RefPtr<APZUpdater> updater;
 
 protected:
-  static ScrollMetadata BuildScrollMetadata(FrameMetrics::ViewID aScrollId,
+  static ScrollMetadata BuildScrollMetadata(ScrollableLayerGuid::ViewID aScrollId,
                                             const CSSRect& aScrollableRect,
                                             const ParentLayerRect& aCompositionBounds)
   {
     ScrollMetadata metadata;
     FrameMetrics& metrics = metadata.GetMetrics();
     metrics.SetScrollId(aScrollId);
     // By convention in this test file, START_SCROLL_ID is the root, so mark it as such.
-    if (aScrollId == FrameMetrics::START_SCROLL_ID) {
+    if (aScrollId == ScrollableLayerGuid::START_SCROLL_ID) {
       metadata.SetIsLayersIdRoot(true);
     }
     metrics.SetCompositionBounds(aCompositionBounds);
     metrics.SetScrollableRect(aScrollableRect);
     metrics.SetScrollOffset(CSSPoint(0, 0));
     metadata.SetPageScrollAmount(LayoutDeviceIntSize(50, 100));
     metadata.SetLineScrollAmount(LayoutDeviceIntSize(5, 10));
     return metadata;
@@ -94,17 +94,17 @@ protected:
           scrollableRect * metrics.LayersPixelsPerCSSPixel()).ToUnknownRect();
       er.mHitRegion = nsIntRegion(IntRect(
           RoundedToInt(metrics.GetCompositionBounds().TopLeft().ToUnknownPoint()),
           scrollRect.Size()));
       aLayer->SetEventRegions(er);
     }
   }
 
-  static void SetScrollableFrameMetrics(Layer* aLayer, FrameMetrics::ViewID aScrollId,
+  static void SetScrollableFrameMetrics(Layer* aLayer, ScrollableLayerGuid::ViewID aScrollId,
                                         CSSRect aScrollableRect = CSSRect(-1, -1, -1, -1)) {
     ParentLayerIntRect compositionBounds =
         RoundedToInt(aLayer->GetLocalTransformTyped().
             TransformBounds(LayerRect(aLayer->GetVisibleRegion().GetBounds())));
     ScrollMetadata metadata = BuildScrollMetadata(aScrollId, aScrollableRect,
         ParentLayerRect(compositionBounds));
     aLayer->SetScrollMetadata(metadata);
     aLayer->SetClipRect(Some(compositionBounds));
@@ -128,26 +128,26 @@ protected:
   }
 
   void CreateSimpleScrollingLayer() {
     const char* layerTreeSyntax = "t";
     nsIntRegion layerVisibleRegion[] = {
       nsIntRegion(IntRect(0,0,200,200)),
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
-    SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 500, 500));
+    SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID, CSSRect(0, 0, 500, 500));
   }
 
   void CreateSimpleDTCScrollingLayer() {
     const char* layerTreeSyntax = "t";
     nsIntRegion layerVisibleRegion[] = {
       nsIntRegion(IntRect(0,0,200,200)),
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
-    SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 500, 500));
+    SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID, CSSRect(0, 0, 500, 500));
 
     EventRegions regions;
     regions.mHitRegion = nsIntRegion(IntRect(0, 0, 200, 200));
     regions.mDispatchToContentHitRegion = regions.mHitRegion;
     layers[0]->SetEventRegions(regions);
   }
 
   void CreateSimpleMultiLayerTree() {
@@ -160,33 +160,33 @@ protected:
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
   }
 
   void CreatePotentiallyLeakingTree() {
     const char* layerTreeSyntax = "c(c(c(t))c(c(t)))";
     // LayerID                     0 1 2 3  4 5 6
     root = CreateLayerTree(layerTreeSyntax, nullptr, nullptr, lm, layers);
-    SetScrollableFrameMetrics(layers[0], FrameMetrics::START_SCROLL_ID);
-    SetScrollableFrameMetrics(layers[2], FrameMetrics::START_SCROLL_ID + 1);
-    SetScrollableFrameMetrics(layers[5], FrameMetrics::START_SCROLL_ID + 1);
-    SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 2);
-    SetScrollableFrameMetrics(layers[6], FrameMetrics::START_SCROLL_ID + 3);
+    SetScrollableFrameMetrics(layers[0], ScrollableLayerGuid::START_SCROLL_ID);
+    SetScrollableFrameMetrics(layers[2], ScrollableLayerGuid::START_SCROLL_ID + 1);
+    SetScrollableFrameMetrics(layers[5], ScrollableLayerGuid::START_SCROLL_ID + 1);
+    SetScrollableFrameMetrics(layers[3], ScrollableLayerGuid::START_SCROLL_ID + 2);
+    SetScrollableFrameMetrics(layers[6], ScrollableLayerGuid::START_SCROLL_ID + 3);
   }
 
   void CreateBug1194876Tree() {
     const char* layerTreeSyntax = "c(t)";
     // LayerID                     0 1
     nsIntRegion layerVisibleRegion[] = {
       nsIntRegion(IntRect(0,0,100,100)),
       nsIntRegion(IntRect(0,0,100,100)),
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
-    SetScrollableFrameMetrics(layers[0], FrameMetrics::START_SCROLL_ID);
-    SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1);
+    SetScrollableFrameMetrics(layers[0], ScrollableLayerGuid::START_SCROLL_ID);
+    SetScrollableFrameMetrics(layers[1], ScrollableLayerGuid::START_SCROLL_ID + 1);
     SetScrollHandoff(layers[1], layers[0]);
 
     // Make layers[1] the root content
     ScrollMetadata childMetadata = layers[1]->GetScrollMetadata(0);
     childMetadata.GetMetrics().SetIsRootContent(true);
     layers[1]->SetScrollMetadata(childMetadata);
 
     // Both layers are fully dispatch-to-content
--- a/gfx/layers/apz/test/gtest/APZTestCommon.h
+++ b/gfx/layers/apz/test/gtest/APZTestCommon.h
@@ -97,34 +97,34 @@ private:
 static TimeStamp GetStartupTime() {
   static TimeStamp sStartupTime = TimeStamp::Now();
   return sStartupTime;
 }
 
 class MockContentController : public GeckoContentController {
 public:
   MOCK_METHOD1(RequestContentRepaint, void(const RepaintRequest&));
-  MOCK_METHOD2(RequestFlingSnap, void(const FrameMetrics::ViewID& aScrollId, const mozilla::CSSPoint& aDestination));
-  MOCK_METHOD2(AcknowledgeScrollUpdate, void(const FrameMetrics::ViewID&, const uint32_t& aScrollGeneration));
+  MOCK_METHOD2(RequestFlingSnap, void(const ScrollableLayerGuid::ViewID& aScrollId, const mozilla::CSSPoint& aDestination));
+  MOCK_METHOD2(AcknowledgeScrollUpdate, void(const ScrollableLayerGuid::ViewID&, const uint32_t& aScrollGeneration));
   MOCK_METHOD5(HandleTap, void(TapType, const LayoutDevicePoint&, Modifiers, const ScrollableLayerGuid&, uint64_t));
   MOCK_METHOD4(NotifyPinchGesture, void(PinchGestureInput::PinchGestureType, const ScrollableLayerGuid&, LayoutDeviceCoord, Modifiers));
   // Can't use the macros with already_AddRefed :(
   void PostDelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs) {
     RefPtr<Runnable> task = aTask;
   }
   bool IsRepaintThread() {
     return NS_IsMainThread();
   }
   void DispatchToRepaintThread(already_AddRefed<Runnable> aTask) {
     NS_DispatchToMainThread(std::move(aTask));
   }
   MOCK_METHOD3(NotifyAPZStateChange, void(const ScrollableLayerGuid& aGuid, APZStateChange aChange, int aArg));
   MOCK_METHOD0(NotifyFlushComplete, void());
-  MOCK_METHOD1(NotifyAsyncScrollbarDragRejected, void(const FrameMetrics::ViewID&));
-  MOCK_METHOD1(NotifyAsyncAutoscrollRejected, void(const FrameMetrics::ViewID&));
+  MOCK_METHOD1(NotifyAsyncScrollbarDragRejected, void(const ScrollableLayerGuid::ViewID&));
+  MOCK_METHOD1(NotifyAsyncAutoscrollRejected, void(const ScrollableLayerGuid::ViewID&));
   MOCK_METHOD1(CancelAutoscroll, void(const ScrollableLayerGuid&));
 };
 
 class MockContentControllerDelayed : public MockContentController {
 public:
   MockContentControllerDelayed()
     : mTime(GetStartupTime())
   {
--- a/gfx/layers/apz/test/gtest/TestBasic.cpp
+++ b/gfx/layers/apz/test/gtest/TestBasic.cpp
@@ -84,21 +84,21 @@ TEST_F(APZCBasicTester, ComplexTransform
   metrics.SetCompositionBounds(ParentLayerRect(0, 0, 24, 24));
   metrics.SetDisplayPort(CSSRect(-1, -1, 6, 6));
   metrics.SetScrollOffset(CSSPoint(10, 10));
   metrics.SetScrollableRect(CSSRect(0, 0, 50, 50));
   metrics.SetCumulativeResolution(LayoutDeviceToLayerScale2D(2, 2));
   metrics.SetPresShellResolution(2.0f);
   metrics.SetZoom(CSSToParentLayerScale2D(6, 6));
   metrics.SetDevPixelsPerCSSPixel(CSSToLayoutDeviceScale(3));
-  metrics.SetScrollId(FrameMetrics::START_SCROLL_ID);
+  metrics.SetScrollId(ScrollableLayerGuid::START_SCROLL_ID);
 
   ScrollMetadata childMetadata = metadata;
   FrameMetrics& childMetrics = childMetadata.GetMetrics();
-  childMetrics.SetScrollId(FrameMetrics::START_SCROLL_ID + 1);
+  childMetrics.SetScrollId(ScrollableLayerGuid::START_SCROLL_ID + 1);
 
   layers[0]->SetScrollMetadata(metadata);
   layers[1]->SetScrollMetadata(childMetadata);
 
   ParentLayerPoint pointOut;
   AsyncTransform viewTransformOut;
 
   // Both the parent and child layer should behave exactly the same here, because
--- a/gfx/layers/apz/test/gtest/TestEventRegions.cpp
+++ b/gfx/layers/apz/test/gtest/TestEventRegions.cpp
@@ -16,19 +16,19 @@ protected:
   void CreateEventRegionsLayerTree1() {
     const char* layerTreeSyntax = "c(tt)";
     nsIntRegion layerVisibleRegions[] = {
       nsIntRegion(IntRect(0, 0, 200, 200)),     // root
       nsIntRegion(IntRect(0, 0, 100, 200)),     // left half
       nsIntRegion(IntRect(0, 100, 200, 100)),   // bottom half
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegions, nullptr, lm, layers);
-    SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID);
-    SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1);
-    SetScrollableFrameMetrics(layers[2], FrameMetrics::START_SCROLL_ID + 2);
+    SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID);
+    SetScrollableFrameMetrics(layers[1], ScrollableLayerGuid::START_SCROLL_ID + 1);
+    SetScrollableFrameMetrics(layers[2], ScrollableLayerGuid::START_SCROLL_ID + 2);
     SetScrollHandoff(layers[1], root);
     SetScrollHandoff(layers[2], root);
 
     // Set up the event regions over a 200x200 area. The root layer has the
     // whole 200x200 as the hit region; layers[1] has the left half and
     // layers[2] has the bottom half. The bottom-left 100x100 area is also
     // in the d-t-c region for both layers[1] and layers[2] (but layers[2] is
     // on top so it gets the events by default if the main thread doesn't
@@ -48,17 +48,17 @@ protected:
 
   void CreateEventRegionsLayerTree2() {
     const char* layerTreeSyntax = "c(t)";
     nsIntRegion layerVisibleRegions[] = {
       nsIntRegion(IntRect(0, 0, 100, 500)),
       nsIntRegion(IntRect(0, 150, 100, 100)),
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegions, nullptr, lm, layers);
-    SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID);
+    SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID);
 
     // Set up the event regions so that the child thebes layer is positioned far
     // away from the scrolling container layer.
     EventRegions regions(nsIntRegion(IntRect(0, 0, 100, 100)));
     root->SetEventRegions(regions);
     regions.mHitRegion = nsIntRegion(IntRect(0, 150, 100, 100));
     layers[1]->SetEventRegions(regions);
 
@@ -78,19 +78,19 @@ protected:
         // x coordinates are uninteresting
         nsIntRegion(IntRect(0,   0, 200, 200)),  // [0, 200]
         nsIntRegion(IntRect(0,   0, 200, 200)),  // [0, 200]
         nsIntRegion(IntRect(0, 100, 200,  50)),  // [100, 150]
         nsIntRegion(IntRect(0, 100, 200, 100))   // [100, 200]
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegions, nullptr, lm, layers);
 
-    SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 200, 200));
-    SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 200, 300));
-    SetScrollableFrameMetrics(layers[2], FrameMetrics::START_SCROLL_ID + 2, CSSRect(0, 0, 200, 100));
+    SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID, CSSRect(0, 0, 200, 200));
+    SetScrollableFrameMetrics(layers[1], ScrollableLayerGuid::START_SCROLL_ID + 1, CSSRect(0, 0, 200, 300));
+    SetScrollableFrameMetrics(layers[2], ScrollableLayerGuid::START_SCROLL_ID + 2, CSSRect(0, 0, 200, 100));
     SetScrollHandoff(layers[2], layers[1]);
     SetScrollHandoff(layers[1], root);
 
     EventRegions regions(nsIntRegion(IntRect(0, 0, 200, 200)));
     root->SetEventRegions(regions);
     regions.mHitRegion = nsIntRegion(IntRect(0, 0, 200, 300));
     layers[1]->SetEventRegions(regions);
     regions.mHitRegion = nsIntRegion(IntRect(0, 100, 200, 100));
@@ -110,18 +110,18 @@ protected:
     // so hits to 2 should go to to the root APZC
     nsIntRegion layerVisibleRegions[] = {
       nsIntRegion(IntRect(0, 0, 100, 100)),
       nsIntRegion(IntRect(0, 0, 100, 100)),
       nsIntRegion(IntRect(0, 0, 100, 100)),
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegions, nullptr, lm, layers);
 
-    SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID);
-    SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1);
+    SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID);
+    SetScrollableFrameMetrics(layers[1], ScrollableLayerGuid::START_SCROLL_ID + 1);
 
     registration = MakeUnique<ScopedLayerTreeRegistration>(manager, LayersId{0}, root, mcc);
     manager->UpdateHitTestingTree(LayersId{0}, root, false, LayersId{0}, 0);
   }
 
   void CreateBug1117712LayerTree() {
     const char* layerTreeSyntax = "c(c(t)t)";
     // LayerID                     0 1 2 3
@@ -140,18 +140,18 @@ protected:
     Matrix4x4 layerTransforms[] = {
       Matrix4x4(),
       Matrix4x4::Translation(50, 0, 0),
       Matrix4x4(),
       Matrix4x4(),
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegions, layerTransforms, lm, layers);
 
-    SetScrollableFrameMetrics(layers[2], FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 10, 10));
-    SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 100, 100));
+    SetScrollableFrameMetrics(layers[2], ScrollableLayerGuid::START_SCROLL_ID, CSSRect(0, 0, 10, 10));
+    SetScrollableFrameMetrics(layers[3], ScrollableLayerGuid::START_SCROLL_ID + 1, CSSRect(0, 0, 100, 100));
     SetScrollHandoff(layers[3], layers[2]);
 
     EventRegions regions(nsIntRegion(IntRect(0, 0, 10, 10)));
     layers[2]->SetEventRegions(regions);
     regions.mHitRegion = nsIntRegion(IntRect(0, 0, 100, 100));
     regions.mDispatchToContentHitRegion = nsIntRegion(IntRect(0, 0, 100, 100));
     layers[3]->SetEventRegions(regions);
 
--- a/gfx/layers/apz/test/gtest/TestHitTesting.cpp
+++ b/gfx/layers/apz/test/gtest/TestHitTesting.cpp
@@ -49,19 +49,19 @@ protected:
     Matrix4x4 transforms[] = {
       Matrix4x4(),
       Matrix4x4(),
       Matrix4x4::Scaling(2, 1, 1),
       Matrix4x4(),
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, transforms, lm, layers);
 
-    SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 200, 200));
-    SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 80, 80));
-    SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 2, CSSRect(0, 0, 80, 80));
+    SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID, CSSRect(0, 0, 200, 200));
+    SetScrollableFrameMetrics(layers[1], ScrollableLayerGuid::START_SCROLL_ID + 1, CSSRect(0, 0, 80, 80));
+    SetScrollableFrameMetrics(layers[3], ScrollableLayerGuid::START_SCROLL_ID + 2, CSSRect(0, 0, 80, 80));
   }
 
   void DisableApzOn(Layer* aLayer) {
     ScrollMetadata m = aLayer->GetScrollMetadata(0);
     m.SetForceDisableApz(true);
     aLayer->SetScrollMetadata(m);
   }
 
@@ -76,34 +76,34 @@ protected:
       nsIntRegion(IntRect(0,200,100,100)),    // thebes(4) in bottom-left
       nsIntRegion(IntRect(200,0,100,400)),    // container(5) along the right 100px of root(0)
       nsIntRegion(IntRect(200,0,100,200)),    // container(6) taking up the top half of parent container(5)
       nsIntRegion(IntRect(200,0,100,200)),    // thebes(7) fully occupying parent container(6)
       nsIntRegion(IntRect(200,200,100,100)),  // thebes(8) in bottom-right (below (6))
       nsIntRegion(IntRect(200,300,100,100)),  // thebes(9) in bottom-right (below (8))
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
-    SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID);
-    SetScrollableFrameMetrics(layers[2], FrameMetrics::START_SCROLL_ID);
-    SetScrollableFrameMetrics(layers[4], FrameMetrics::START_SCROLL_ID + 1);
-    SetScrollableFrameMetrics(layers[6], FrameMetrics::START_SCROLL_ID + 1);
-    SetScrollableFrameMetrics(layers[7], FrameMetrics::START_SCROLL_ID + 2);
-    SetScrollableFrameMetrics(layers[8], FrameMetrics::START_SCROLL_ID + 1);
-    SetScrollableFrameMetrics(layers[9], FrameMetrics::START_SCROLL_ID + 3);
+    SetScrollableFrameMetrics(layers[1], ScrollableLayerGuid::START_SCROLL_ID);
+    SetScrollableFrameMetrics(layers[2], ScrollableLayerGuid::START_SCROLL_ID);
+    SetScrollableFrameMetrics(layers[4], ScrollableLayerGuid::START_SCROLL_ID + 1);
+    SetScrollableFrameMetrics(layers[6], ScrollableLayerGuid::START_SCROLL_ID + 1);
+    SetScrollableFrameMetrics(layers[7], ScrollableLayerGuid::START_SCROLL_ID + 2);
+    SetScrollableFrameMetrics(layers[8], ScrollableLayerGuid::START_SCROLL_ID + 1);
+    SetScrollableFrameMetrics(layers[9], ScrollableLayerGuid::START_SCROLL_ID + 3);
   }
 
   void CreateBug1148350LayerTree() {
     const char* layerTreeSyntax = "c(t)";
     // LayerID                     0 1
     nsIntRegion layerVisibleRegion[] = {
       nsIntRegion(IntRect(0,0,200,200)),
       nsIntRegion(IntRect(0,0,200,200)),
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
-    SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID);
+    SetScrollableFrameMetrics(layers[1], ScrollableLayerGuid::START_SCROLL_ID);
   }
 };
 
 // A simple hit testing test that doesn't involve any transforms on layers.
 TEST_F(APZHitTestingTester, HitTesting1) {
   SCOPED_GFX_VAR(UseWebRender, bool, false);
 
   CreateHitTesting1LayerTree();
@@ -114,41 +114,41 @@ TEST_F(APZHitTestingTester, HitTesting1)
   TestAsyncPanZoomController* nullAPZC = nullptr;
   EXPECT_EQ(nullAPZC, hit.get());
   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);
+  SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID);
   manager->UpdateHitTestingTree(LayersId{0}, root, false, LayersId{0}, paintSequenceNumber++);
   hit = GetTargetAPZC(ScreenPoint(15, 15));
   EXPECT_EQ(ApzcOf(root), hit.get());
   // expect hit point at LayerIntPoint(15, 15)
   EXPECT_EQ(ParentLayerPoint(15, 15), transformToApzc.TransformPoint(ScreenPoint(15, 15)));
   EXPECT_EQ(ScreenPoint(15, 15), transformToGecko.TransformPoint(ParentLayerPoint(15, 15)));
 
   // Now we have a sub APZC with a better fit
-  SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 1);
+  SetScrollableFrameMetrics(layers[3], ScrollableLayerGuid::START_SCROLL_ID + 1);
   manager->UpdateHitTestingTree(LayersId{0}, root, false, LayersId{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(ParentLayerPoint(25, 25), transformToApzc.TransformPoint(ScreenPoint(25, 25)));
   EXPECT_EQ(ScreenPoint(25, 25), transformToGecko.TransformPoint(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);
+  SetScrollableFrameMetrics(layers[4], ScrollableLayerGuid::START_SCROLL_ID + 2);
   manager->UpdateHitTestingTree(LayersId{0}, root, false, LayersId{0}, paintSequenceNumber++);
   hit = GetTargetAPZC(ScreenPoint(15, 15));
   EXPECT_EQ(ApzcOf(layers[4]), hit.get());
   // expect hit point at LayerIntPoint(15, 15)
   EXPECT_EQ(ParentLayerPoint(15, 15), transformToApzc.TransformPoint(ScreenPoint(15, 15)));
   EXPECT_EQ(ScreenPoint(15, 15), transformToGecko.TransformPoint(ParentLayerPoint(15, 15)));
 
   // Hit test ouside the reach of layer[3,4] but inside root
@@ -291,18 +291,18 @@ TEST_F(APZHitTestingTester, HitTesting3)
       nsIntRegion(IntRect(0,0,50,50))
   };
   Matrix4x4 transforms[] = {
       Matrix4x4(),
       Matrix4x4::Scaling(2, 2, 1)
   };
   root = CreateLayerTree(layerTreeSyntax, layerVisibleRegions, transforms, lm, layers);
   // No actual room to scroll
-  SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 200, 200));
-  SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 50, 50));
+  SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID, CSSRect(0, 0, 200, 200));
+  SetScrollableFrameMetrics(layers[1], ScrollableLayerGuid::START_SCROLL_ID + 1, CSSRect(0, 0, 50, 50));
 
   ScopedLayerTreeRegistration registration(manager, LayersId{0}, root, mcc);
 
   manager->UpdateHitTestingTree(LayersId{0}, root, false, LayersId{0}, 0);
 
   RefPtr<AsyncPanZoomController> hit = GetTargetAPZC(ScreenPoint(75, 75));
   EXPECT_EQ(ApzcOf(layers[1]), hit.get());
 }
@@ -574,28 +574,28 @@ TEST_F(APZHitTestingTester, HitTestingRe
   nsIntRegion layerVisibleRegion[] = {
     nsIntRegion(IntRect(0,0,200,200)),
     nsIntRegion(IntRect(0,0,200,200)),
     nsIntRegion(IntRect(0,0,200,100))
   };
   root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
 
   // Add root scroll metadata to the first painted layer.
-  SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID, CSSRect(0,0,200,200));
+  SetScrollableFrameMetrics(layers[1], ScrollableLayerGuid::START_SCROLL_ID, CSSRect(0,0,200,200));
 
   // Add root and subframe scroll metadata to the second painted layer.
   // Give the subframe metadata a scroll clip corresponding to the subframe's
   // composition bounds.
   // Importantly, give the layer a layer clip which leaks outside of the
   // subframe's composition bounds.
   ScrollMetadata rootMetadata = BuildScrollMetadata(
-      FrameMetrics::START_SCROLL_ID, CSSRect(0,0,200,200),
+      ScrollableLayerGuid::START_SCROLL_ID, CSSRect(0,0,200,200),
       ParentLayerRect(0,0,200,200));
   ScrollMetadata subframeMetadata = BuildScrollMetadata(
-      FrameMetrics::START_SCROLL_ID + 1, CSSRect(0,0,200,200),
+      ScrollableLayerGuid::START_SCROLL_ID + 1, CSSRect(0,0,200,200),
       ParentLayerRect(0,0,200,100));
   subframeMetadata.SetScrollClip(Some(LayerClip(ParentLayerIntRect(0,0,200,100))));
   layers[2]->SetScrollMetadata({subframeMetadata, rootMetadata});
   layers[2]->SetClipRect(Some(ParentLayerIntRect(0,0,200,200)));
   SetEventRegionsBasedOnBottommostMetrics(layers[2]);
 
   // Build the hit testing tree.
   ScopedLayerTreeRegistration registration(manager, LayersId{0}, root, mcc);
--- a/gfx/layers/apz/test/gtest/TestScrollHandoff.cpp
+++ b/gfx/layers/apz/test/gtest/TestScrollHandoff.cpp
@@ -15,36 +15,36 @@ protected:
 
   void CreateScrollHandoffLayerTree1() {
     const char* layerTreeSyntax = "c(t)";
     nsIntRegion layerVisibleRegion[] = {
       nsIntRegion(IntRect(0, 0, 100, 100)),
       nsIntRegion(IntRect(0, 50, 100, 50))
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
-    SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 200, 200));
-    SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 100, 100));
+    SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID, CSSRect(0, 0, 200, 200));
+    SetScrollableFrameMetrics(layers[1], ScrollableLayerGuid::START_SCROLL_ID + 1, CSSRect(0, 0, 100, 100));
     SetScrollHandoff(layers[1], root);
     registration = MakeUnique<ScopedLayerTreeRegistration>(manager, LayersId{0}, root, mcc);
     manager->UpdateHitTestingTree(LayersId{0}, root, false, LayersId{0}, 0);
     rootApzc = ApzcOf(root);
     rootApzc->GetFrameMetrics().SetIsRootContent(true);  // make root APZC zoomable
   }
 
   void CreateScrollHandoffLayerTree2() {
     const char* layerTreeSyntax = "c(c(t))";
     nsIntRegion layerVisibleRegion[] = {
       nsIntRegion(IntRect(0, 0, 100, 100)),
       nsIntRegion(IntRect(0, 0, 100, 100)),
       nsIntRegion(IntRect(0, 50, 100, 50))
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
-    SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 200, 200));
-    SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 2, CSSRect(-100, -100, 200, 200));
-    SetScrollableFrameMetrics(layers[2], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 100, 100));
+    SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID, CSSRect(0, 0, 200, 200));
+    SetScrollableFrameMetrics(layers[1], ScrollableLayerGuid::START_SCROLL_ID + 2, CSSRect(-100, -100, 200, 200));
+    SetScrollableFrameMetrics(layers[2], ScrollableLayerGuid::START_SCROLL_ID + 1, CSSRect(0, 0, 100, 100));
     SetScrollHandoff(layers[1], root);
     SetScrollHandoff(layers[2], layers[1]);
     // No ScopedLayerTreeRegistration as that just needs to be done once per test
     // and this is the second layer tree for a particular test.
     MOZ_ASSERT(registration);
     manager->UpdateHitTestingTree(LayersId{0}, root, false, LayersId{0}, 0);
     rootApzc = ApzcOf(root);
   }
@@ -54,21 +54,21 @@ protected:
     nsIntRegion layerVisibleRegion[] = {
       nsIntRegion(IntRect(0, 0, 100, 100)),  // root
       nsIntRegion(IntRect(0, 0, 100, 50)),   // scrolling parent 1
       nsIntRegion(IntRect(0, 0, 100, 50)),   // scrolling child 1
       nsIntRegion(IntRect(0, 50, 100, 50)),  // scrolling parent 2
       nsIntRegion(IntRect(0, 50, 100, 50))   // scrolling child 2
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
-    SetScrollableFrameMetrics(layers[0], FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 100, 100));
-    SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 100, 100));
-    SetScrollableFrameMetrics(layers[2], FrameMetrics::START_SCROLL_ID + 2, CSSRect(0, 0, 100, 100));
-    SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 3, CSSRect(0, 50, 100, 100));
-    SetScrollableFrameMetrics(layers[4], FrameMetrics::START_SCROLL_ID + 4, CSSRect(0, 50, 100, 100));
+    SetScrollableFrameMetrics(layers[0], ScrollableLayerGuid::START_SCROLL_ID, CSSRect(0, 0, 100, 100));
+    SetScrollableFrameMetrics(layers[1], ScrollableLayerGuid::START_SCROLL_ID + 1, CSSRect(0, 0, 100, 100));
+    SetScrollableFrameMetrics(layers[2], ScrollableLayerGuid::START_SCROLL_ID + 2, CSSRect(0, 0, 100, 100));
+    SetScrollableFrameMetrics(layers[3], ScrollableLayerGuid::START_SCROLL_ID + 3, CSSRect(0, 50, 100, 100));
+    SetScrollableFrameMetrics(layers[4], ScrollableLayerGuid::START_SCROLL_ID + 4, CSSRect(0, 50, 100, 100));
     SetScrollHandoff(layers[1], layers[0]);
     SetScrollHandoff(layers[3], layers[0]);
     SetScrollHandoff(layers[2], layers[1]);
     SetScrollHandoff(layers[4], layers[3]);
     registration = MakeUnique<ScopedLayerTreeRegistration>(manager, LayersId{0}, root, mcc);
     manager->UpdateHitTestingTree(LayersId{0}, root, false, LayersId{0}, 0);
   }
 
@@ -76,34 +76,34 @@ protected:
   // horizontally, and a child layer that is only scrollable vertically.
   void CreateScrollHandoffLayerTree4() {
     const char* layerTreeSyntax = "c(t)";
     nsIntRegion layerVisibleRegion[] = {
       nsIntRegion(IntRect(0, 0, 100, 100)),
       nsIntRegion(IntRect(0, 0, 100, 100))
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
-    SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 200, 100));
-    SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 100, 200));
+    SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID, CSSRect(0, 0, 200, 100));
+    SetScrollableFrameMetrics(layers[1], ScrollableLayerGuid::START_SCROLL_ID + 1, CSSRect(0, 0, 100, 200));
     SetScrollHandoff(layers[1], root);
     registration = MakeUnique<ScopedLayerTreeRegistration>(manager, LayersId{0}, root, mcc);
     manager->UpdateHitTestingTree(LayersId{0}, root, false, LayersId{0}, 0);
     rootApzc = ApzcOf(root);
   }
 
   void CreateScrollgrabLayerTree(bool makeParentScrollable = true) {
     const char* layerTreeSyntax = "c(t)";
     nsIntRegion layerVisibleRegion[] = {
       nsIntRegion(IntRect(0, 0, 100, 100)),  // scroll-grabbing parent
       nsIntRegion(IntRect(0, 20, 100, 80))   // child
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
     float parentHeight = makeParentScrollable ? 120 : 100;
-    SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 100, parentHeight));
-    SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 100, 200));
+    SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID, CSSRect(0, 0, 100, parentHeight));
+    SetScrollableFrameMetrics(layers[1], ScrollableLayerGuid::START_SCROLL_ID + 1, CSSRect(0, 0, 100, 200));
     SetScrollHandoff(layers[1], root);
     registration = MakeUnique<ScopedLayerTreeRegistration>(manager, LayersId{0}, root, mcc);
     manager->UpdateHitTestingTree(LayersId{0}, root, false, LayersId{0}, 0);
     rootApzc = ApzcOf(root);
     rootApzc->GetScrollMetadata().SetHasScrollgrab(true);
   }
 
   void TestFlingAcceleration() {
--- a/gfx/layers/apz/test/gtest/TestSnapping.cpp
+++ b/gfx/layers/apz/test/gtest/TestSnapping.cpp
@@ -18,18 +18,18 @@ TEST_F(APZCSnappingTester, Bug1265510)
   SCOPED_GFX_VAR(UseWebRender, bool, false);
 
   const char* layerTreeSyntax = "c(t)";
   nsIntRegion layerVisibleRegion[] = {
     nsIntRegion(IntRect(0, 0, 100, 100)),
     nsIntRegion(IntRect(0, 100, 100, 100))
   };
   root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
-  SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 100, 200));
-  SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 100, 200));
+  SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID, CSSRect(0, 0, 100, 200));
+  SetScrollableFrameMetrics(layers[1], ScrollableLayerGuid::START_SCROLL_ID + 1, CSSRect(0, 0, 100, 200));
   SetScrollHandoff(layers[1], root);
 
   ScrollSnapInfo snap;
   snap.mScrollSnapTypeY = NS_STYLE_SCROLL_SNAP_TYPE_MANDATORY;
   snap.mScrollSnapIntervalY = Some(100 * AppUnitsPerCSSPixel());
 
   ScrollMetadata metadata = root->GetScrollMetadata(0);
   metadata.SetSnapInfo(ScrollSnapInfo(snap));
@@ -70,17 +70,17 @@ TEST_F(APZCSnappingTester, Snap_After_Pi
 {
   SCOPED_GFX_VAR(UseWebRender, bool, false);
 
   const char* layerTreeSyntax = "c";
   nsIntRegion layerVisibleRegion[] = {
     nsIntRegion(IntRect(0, 0, 100, 100)),
   };
   root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
-  SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 100, 200));
+  SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID, CSSRect(0, 0, 100, 200));
 
   // Set up some basic scroll snapping
   ScrollSnapInfo snap;
   snap.mScrollSnapTypeY = NS_STYLE_SCROLL_SNAP_TYPE_MANDATORY;
   snap.mScrollSnapIntervalY = Some(100 * AppUnitsPerCSSPixel());
 
   // Save the scroll snap info on the root APZC.
   // Also mark the root APZC as "root content", since APZC only allows
--- a/gfx/layers/apz/test/gtest/TestTreeManager.cpp
+++ b/gfx/layers/apz/test/gtest/TestTreeManager.cpp
@@ -8,35 +8,35 @@
 #include "APZTestCommon.h"
 #include "InputUtils.h"
 
 TEST_F(APZCTreeManagerTester, ScrollablePaintedLayers) {
   CreateSimpleMultiLayerTree();
   ScopedLayerTreeRegistration registration(manager, LayersId{0}, root, mcc);
 
   // both layers have the same scrollId
-  SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID);
-  SetScrollableFrameMetrics(layers[2], FrameMetrics::START_SCROLL_ID);
+  SetScrollableFrameMetrics(layers[1], ScrollableLayerGuid::START_SCROLL_ID);
+  SetScrollableFrameMetrics(layers[2], ScrollableLayerGuid::START_SCROLL_ID);
   manager->UpdateHitTestingTree(LayersId{0}, root, false, LayersId{0}, 0);
 
   TestAsyncPanZoomController* nullAPZC = nullptr;
   // so they should have the same APZC
   EXPECT_FALSE(layers[0]->HasScrollableFrameMetrics());
   EXPECT_NE(nullAPZC, ApzcOf(layers[1]));
   EXPECT_NE(nullAPZC, ApzcOf(layers[2]));
   EXPECT_EQ(ApzcOf(layers[1]), ApzcOf(layers[2]));
 
   // Change the scrollId of layers[1], and verify the APZC changes
-  SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1);
+  SetScrollableFrameMetrics(layers[1], ScrollableLayerGuid::START_SCROLL_ID + 1);
   manager->UpdateHitTestingTree(LayersId{0}, root, false, LayersId{0}, 0);
   EXPECT_NE(ApzcOf(layers[1]), ApzcOf(layers[2]));
 
   // Change the scrollId of layers[2] to match that of layers[1], ensure we get the same
   // APZC for both again
-  SetScrollableFrameMetrics(layers[2], FrameMetrics::START_SCROLL_ID + 1);
+  SetScrollableFrameMetrics(layers[2], ScrollableLayerGuid::START_SCROLL_ID + 1);
   manager->UpdateHitTestingTree(LayersId{0}, root, false, LayersId{0}, 0);
   EXPECT_EQ(ApzcOf(layers[1]), ApzcOf(layers[2]));
 }
 
 TEST_F(APZCTreeManagerTester, Bug1068268) {
   CreatePotentiallyLeakingTree();
   ScopedLayerTreeRegistration registration(manager, LayersId{0}, root, mcc);
 
--- a/gfx/layers/apz/testutil/APZTestData.h
+++ b/gfx/layers/apz/testutil/APZTestData.h
@@ -5,24 +5,24 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_layers_APZTestData_h
 #define mozilla_layers_APZTestData_h
 
 #include <map>
 
 #include "gfxPrefs.h"
-#include "FrameMetrics.h"
 #include "nsDebug.h"             // for NS_WARNING
 #include "nsTArray.h"
 #include "mozilla/Assertions.h"  // for MOZ_ASSERT
 #include "mozilla/DebugOnly.h"   // for DebugOnly
 #include "mozilla/GfxMessageUtils.h" // for ParamTraits specializations
 #include "mozilla/ToString.h"    // for ToString
 #include "mozilla/gfx/CompositorHitTestInfo.h"
+#include "mozilla/layers/ScrollableLayerGuid.h"
 #include "ipc/IPCMessageUtils.h"
 #include "js/TypeDecls.h"
 
 namespace mozilla {
 namespace layers {
 
 typedef uint32_t SequenceNumber;
 
@@ -40,17 +40,17 @@ typedef uint32_t SequenceNumber;
  * dispatched during testing. This list is only populated on the compositor
  * instance of this class.
  */
 // TODO(botond):
 //  - Improve warnings/asserts.
 //  - Add ability to associate a repaint request triggered during a layers update
 //    with the sequence number of the paint that caused the layers update.
 class APZTestData {
-  typedef FrameMetrics::ViewID ViewID;
+  typedef ScrollableLayerGuid::ViewID ViewID;
   friend struct IPC::ParamTraits<APZTestData>;
   friend struct APZTestDataToJSConverter;
 public:
   void StartNewPaint(SequenceNumber aSequenceNumber) {
     // We should never get more than one paint with the same sequence number.
     MOZ_ASSERT(mPaints.find(aSequenceNumber) == mPaints.end());
     mPaints.insert(DataStore::value_type(aSequenceNumber, Bucket()));
   }
@@ -123,25 +123,25 @@ class APZPaintLogHelper {
 public:
   APZPaintLogHelper(APZTestData* aTestData, SequenceNumber aPaintSequenceNumber)
     : mTestData(aTestData),
       mPaintSequenceNumber(aPaintSequenceNumber) {
     MOZ_ASSERT(!aTestData || gfxPrefs::APZTestLoggingEnabled(), "don't call me");
   }
 
   template <typename Value>
-  void LogTestData(FrameMetrics::ViewID aScrollId,
+  void LogTestData(ScrollableLayerGuid::ViewID aScrollId,
                    const std::string& aKey,
                    const Value& aValue) const {
     if (mTestData) {  // avoid stringifying if mTestData == nullptr
       LogTestData(aScrollId, aKey, ToString(aValue));
     }
   }
 
-  void LogTestData(FrameMetrics::ViewID aScrollId,
+  void LogTestData(ScrollableLayerGuid::ViewID aScrollId,
                    const std::string& aKey,
                    const std::string& aValue) const {
     if (mTestData) {
       mTestData->LogTestDataForPaint(mPaintSequenceNumber, aScrollId, aKey, aValue);
     }
   }
 private:
   APZTestData* mTestData;
--- a/gfx/layers/apz/util/APZCCallbackHelper.cpp
+++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp
@@ -269,17 +269,17 @@ SetPaintRequestTime(nsIContent* aContent
   aContent->SetProperty(nsGkAtoms::paintRequestTime,
                         new TimeStamp(aPaintRequestTime),
                         nsINode::DeleteProperty<TimeStamp>);
 }
 
 void
 APZCCallbackHelper::UpdateRootFrame(const RepaintRequest& aRequest)
 {
-  if (aRequest.GetScrollId() == FrameMetrics::NULL_SCROLL_ID) {
+  if (aRequest.GetScrollId() == ScrollableLayerGuid::NULL_SCROLL_ID) {
     return;
   }
   nsIContent* content = nsLayoutUtils::FindContentFor(aRequest.GetScrollId());
   if (!content) {
     return;
   }
 
   nsCOMPtr<nsIPresShell> shell = GetPresShell(content);
@@ -327,17 +327,17 @@ APZCCallbackHelper::UpdateRootFrame(cons
     displayPortMargins,
     aRequest.CalculateCompositedSizeInCssPixels());
   SetPaintRequestTime(content, aRequest.GetPaintRequestTime());
 }
 
 void
 APZCCallbackHelper::UpdateSubFrame(const RepaintRequest& aRequest)
 {
-  if (aRequest.GetScrollId() == FrameMetrics::NULL_SCROLL_ID) {
+  if (aRequest.GetScrollId() == ScrollableLayerGuid::NULL_SCROLL_ID) {
     return;
   }
   nsIContent* content = nsLayoutUtils::FindContentFor(aRequest.GetScrollId());
   if (!content) {
     return;
   }
 
   MOZ_ASSERT(aRequest.GetUseDisplayPortMargins());
@@ -352,17 +352,17 @@ APZCCallbackHelper::UpdateSubFrame(const
       aRequest.CalculateCompositedSizeInCssPixels());
   }
   SetPaintRequestTime(content, aRequest.GetPaintRequestTime());
 }
 
 bool
 APZCCallbackHelper::GetOrCreateScrollIdentifiers(nsIContent* aContent,
                                                  uint32_t* aPresShellIdOut,
-                                                 FrameMetrics::ViewID* aViewIdOut)
+                                                 ScrollableLayerGuid::ViewID* aViewIdOut)
 {
     if (!aContent) {
       return false;
     }
     *aViewIdOut = nsLayoutUtils::FindOrCreateIDFor(aContent);
     if (nsCOMPtr<nsIPresShell> shell = GetPresShell(aContent)) {
       *aPresShellIdOut = shell->GetPresShellId();
       return true;
@@ -386,17 +386,17 @@ APZCCallbackHelper::InitializeRootDispla
 
   MOZ_ASSERT(aPresShell->GetDocument());
   nsIContent* content = aPresShell->GetDocument()->GetDocumentElement();
   if (!content) {
     return;
   }
 
   uint32_t presShellId;
-  FrameMetrics::ViewID viewId;
+  ScrollableLayerGuid::ViewID viewId;
   if (APZCCallbackHelper::GetOrCreateScrollIdentifiers(content, &presShellId, &viewId)) {
     nsPresContext* pc = aPresShell->GetPresContext();
     // This code is only correct for root content or toplevel documents.
     MOZ_ASSERT(!pc || pc->IsRootContentDocument() || !pc->GetParentPresContext());
     nsIFrame* frame = aPresShell->GetRootScrollFrame();
     if (!frame) {
       frame = aPresShell->GetRootFrame();
     }
@@ -467,17 +467,17 @@ GetRootDocumentPresShell(nsIContent* aCo
     return context->PresShell();
 }
 
 CSSPoint
 APZCCallbackHelper::ApplyCallbackTransform(const CSSPoint& aInput,
                                            const ScrollableLayerGuid& aGuid)
 {
     CSSPoint input = aInput;
-    if (aGuid.mScrollId == FrameMetrics::NULL_SCROLL_ID) {
+    if (aGuid.mScrollId == ScrollableLayerGuid::NULL_SCROLL_ID) {
         return input;
     }
     nsCOMPtr<nsIContent> content = nsLayoutUtils::FindContentFor(aGuid.mScrollId);
     if (!content) {
         return input;
     }
 
     // First, scale inversely by the root content document's pres shell
@@ -672,17 +672,17 @@ UpdateRootFrameForTouchTargetDocument(ns
 // Return whether or not a displayport was set.
 static bool
 PrepareForSetTargetAPZCNotification(nsIWidget* aWidget,
                                     const ScrollableLayerGuid& aGuid,
                                     nsIFrame* aRootFrame,
                                     const LayoutDeviceIntPoint& aRefPoint,
                                     nsTArray<ScrollableLayerGuid>* aTargets)
 {
-  ScrollableLayerGuid guid(aGuid.mLayersId, 0, FrameMetrics::NULL_SCROLL_ID);
+  ScrollableLayerGuid guid(aGuid.mLayersId, 0, ScrollableLayerGuid::NULL_SCROLL_ID);
   nsPoint point =
     nsLayoutUtils::GetEventCoordinatesRelativeTo(aWidget, aRefPoint, aRootFrame);
   uint32_t flags = 0;
   if (gfxPrefs::APZAllowZooming()) {
     // If zooming is enabled, we need IGNORE_ROOT_SCROLL_FRAME for correct
     // hit testing. Otherwise, don't use it because it interferes with
     // hit testing for some purposes such as scrollbar dragging (this will
     // need to be fixed before enabling zooming by default on desktop).
@@ -891,17 +891,17 @@ APZCCallbackHelper::SendSetAllowedTouchB
                 rootFrame, aEvent.mTouches[i]->mRefPoint));
       }
       aCallback(aInputBlockId, std::move(flags));
     }
   }
 }
 
 void
-APZCCallbackHelper::NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId, const nsString& aEvent)
+APZCCallbackHelper::NotifyMozMouseScrollEvent(const ScrollableLayerGuid::ViewID& aScrollId, const nsString& aEvent)
 {
   nsCOMPtr<nsIContent> targetContent = nsLayoutUtils::FindContentFor(aScrollId);
   if (!targetContent) {
     return;
   }
   nsCOMPtr<nsIDocument> ownerDoc = targetContent->OwnerDoc();
   if (!ownerDoc) {
     return;
@@ -937,38 +937,38 @@ APZCCallbackHelper::NotifyFlushComplete(
 APZCCallbackHelper::IsScrollInProgress(nsIScrollableFrame* aFrame)
 {
   return aFrame->IsProcessingAsyncScroll()
          || nsLayoutUtils::CanScrollOriginClobberApz(aFrame->LastScrollOrigin())
          || aFrame->LastSmoothScrollOrigin();
 }
 
 /* static */ void
-APZCCallbackHelper::NotifyAsyncScrollbarDragRejected(const FrameMetrics::ViewID& aScrollId)
+APZCCallbackHelper::NotifyAsyncScrollbarDragRejected(const ScrollableLayerGuid::ViewID& aScrollId)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (nsIScrollableFrame* scrollFrame = nsLayoutUtils::FindScrollableFrameFor(aScrollId)) {
     scrollFrame->AsyncScrollbarDragRejected();
   }
 }
 
 /* static */ void
-APZCCallbackHelper::NotifyAsyncAutoscrollRejected(const FrameMetrics::ViewID& aScrollId)
+APZCCallbackHelper::NotifyAsyncAutoscrollRejected(const ScrollableLayerGuid::ViewID& aScrollId)
 {
   MOZ_ASSERT(NS_IsMainThread());
   nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
   MOZ_ASSERT(observerService);
 
   nsAutoString data;
   data.AppendInt(aScrollId);
   observerService->NotifyObservers(nullptr, "autoscroll-rejected-by-apz", data.get());
 }
 
 /* static */ void
-APZCCallbackHelper::CancelAutoscroll(const FrameMetrics::ViewID& aScrollId)
+APZCCallbackHelper::CancelAutoscroll(const ScrollableLayerGuid::ViewID& aScrollId)
 {
   MOZ_ASSERT(NS_IsMainThread());
   nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
   MOZ_ASSERT(observerService);
 
   nsAutoString data;
   data.AppendInt(aScrollId);
   observerService->NotifyObservers(nullptr, "apz:cancel-autoscroll", data.get());
--- a/gfx/layers/apz/util/APZCCallbackHelper.h
+++ b/gfx/layers/apz/util/APZCCallbackHelper.h
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_layers_APZCCallbackHelper_h
 #define mozilla_layers_APZCCallbackHelper_h
 
-#include "FrameMetrics.h"
 #include "InputData.h"
 #include "mozilla/EventForwards.h"
 #include "mozilla/layers/APZUtils.h"
 #include "mozilla/layers/RepaintRequest.h"
 #include "nsIDOMWindowUtils.h"
 #include "nsRefreshDriver.h"
 
 #include <functional>
@@ -52,41 +51,40 @@ private:
 /* This class contains some helper methods that facilitate implementing the
    GeckoContentController callback interface required by the AsyncPanZoomController.
    Since different platforms need to implement this interface in similar-but-
    not-quite-the-same ways, this utility class provides some helpful methods
    to hold code that can be shared across the different platform implementations.
  */
 class APZCCallbackHelper
 {
-    typedef mozilla::layers::FrameMetrics FrameMetrics;
     typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid;
 
 public:
-    /* Applies the scroll and zoom parameters from the given FrameMetrics object
+    /* Applies the scroll and zoom parameters from the given RepaintRequest object
        to the root frame for the given metrics' scrollId. If tiled thebes layers
        are enabled, this will align the displayport to tile boundaries. Setting
        the scroll position can cause some small adjustments to be made to the
        actual scroll position. */
     static void UpdateRootFrame(const RepaintRequest& aRequest);
 
-    /* Applies the scroll parameters from the given FrameMetrics object to the
+    /* Applies the scroll parameters from the given RepaintRequest object to the
        subframe corresponding to given metrics' scrollId. If tiled thebes
        layers are enabled, this will align the displayport to tile boundaries.
        Setting the scroll position can cause some small adjustments to be made
        to the actual scroll position. */
     static void UpdateSubFrame(const RepaintRequest& aRequest);
 
     /* Get the presShellId and view ID for the given content element.
      * If the view ID does not exist, one is created.
      * The pres shell ID should generally already exist; if it doesn't for some
      * reason, false is returned. */
     static bool GetOrCreateScrollIdentifiers(nsIContent* aContent,
                                              uint32_t* aPresShellIdOut,
-                                             FrameMetrics::ViewID* aViewIdOut);
+                                             ScrollableLayerGuid::ViewID* aViewIdOut);
 
     /* Initialize a zero-margin displayport on the root document element of the
        given presShell. */
     static void InitializeRootDisplayport(nsIPresShell* aPresShell);
 
     /* Get the pres context associated with the document enclosing |aContent|. */
     static nsPresContext* GetPresContextForContent(nsIContent* aContent);
 
@@ -178,25 +176,25 @@ public:
      * and send that information to the provided callback. */
     static void SendSetAllowedTouchBehaviorNotification(nsIWidget* aWidget,
                                                         nsIDocument* aDocument,
                                                         const WidgetTouchEvent& aEvent,
                                                         uint64_t aInputBlockId,
                                                         const SetAllowedTouchBehaviorCallback& aCallback);
 
     /* Notify content of a mouse scroll testing event. */
-    static void NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId, const nsString& aEvent);
+    static void NotifyMozMouseScrollEvent(const ScrollableLayerGuid::ViewID& aScrollId, const nsString& aEvent);
 
     /* Notify content that the repaint flush is complete. */
     static void NotifyFlushComplete(nsIPresShell* aShell);
 
-    static void NotifyAsyncScrollbarDragRejected(const FrameMetrics::ViewID& aScrollId);
-    static void NotifyAsyncAutoscrollRejected(const FrameMetrics::ViewID& aScrollId);
+    static void NotifyAsyncScrollbarDragRejected(const ScrollableLayerGuid::ViewID& aScrollId);
+    static void NotifyAsyncAutoscrollRejected(const ScrollableLayerGuid::ViewID& aScrollId);
 
-    static void CancelAutoscroll(const FrameMetrics::ViewID& aScrollId);
+    static void CancelAutoscroll(const ScrollableLayerGuid::ViewID& aScrollId);
 
     static ScreenMargin
     AdjustDisplayPortForScrollDelta(const RepaintRequest& aRequest,
                                     const CSSPoint& aActualScrollOffset);
 
     /*
      * Check if the scrollable frame is currently in the middle of an async
      * or smooth scroll. We want to discard certain scroll input if this is
--- a/gfx/layers/apz/util/APZEventState.h
+++ b/gfx/layers/apz/util/APZEventState.h
@@ -4,20 +4,20 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_layers_APZEventState_h
 #define mozilla_layers_APZEventState_h
 
 #include <stdint.h>
 
-#include "FrameMetrics.h"     // for ScrollableLayerGuid
 #include "Units.h"
 #include "mozilla/EventForwards.h"
 #include "mozilla/layers/GeckoContentController.h"  // for APZStateChange
+#include "mozilla/layers/ScrollableLayerGuid.h"     // for ScrollableLayerGuid
 #include "mozilla/RefPtr.h"
 #include "nsCOMPtr.h"
 #include "nsISupportsImpl.h"  // for NS_INLINE_DECL_REFCOUNTING
 #include "nsIWeakReferenceUtils.h"  // for nsWeakPtr
 
 #include <functional>
 
 template <class> class nsCOMPtr;
@@ -37,17 +37,17 @@ typedef std::function<void(const Scrolla
         ContentReceivedInputBlockCallback;
 
 /**
  * A content-side component that keeps track of state for handling APZ
  * gestures and sending APZ notifications.
  */
 class APZEventState {
   typedef GeckoContentController::APZStateChange APZStateChange;
-  typedef FrameMetrics::ViewID ViewID;
+  typedef ScrollableLayerGuid::ViewID ViewID;
 public:
   APZEventState(nsIWidget* aWidget,
                 ContentReceivedInputBlockCallback&& aCallback);
 
   NS_INLINE_DECL_REFCOUNTING(APZEventState);
 
   void ProcessSingleTap(const CSSPoint& aPoint,
                         const CSSToLayoutDeviceScale& aScale,
--- a/gfx/layers/apz/util/ChromeProcessController.cpp
+++ b/gfx/layers/apz/util/ChromeProcessController.cpp
@@ -115,17 +115,17 @@ ChromeProcessController::GetRootDocument
 {
   if (nsIPresShell* presShell = GetPresShell()) {
     return presShell->GetDocument();
   }
   return nullptr;
 }
 
 nsIDocument*
-ChromeProcessController::GetRootContentDocument(const FrameMetrics::ViewID& aScrollId) const
+ChromeProcessController::GetRootContentDocument(const ScrollableLayerGuid::ViewID& aScrollId) const
 {
   nsIContent* content = nsLayoutUtils::FindContentFor(aScrollId);
   if (!content) {
     return nullptr;
   }
   nsIPresShell* presShell = APZCCallbackHelper::GetRootContentDocumentPresShellForContent(content);
   if (presShell) {
     return presShell->GetDocument();
@@ -150,17 +150,17 @@ ChromeProcessController::HandleDoubleTap
   // resolution of the document and so we must remove it before calculating
   // the zoomToRect.
   nsIPresShell* presShell = document->GetShell();
   const float resolution = presShell->ScaleToResolution() ? presShell->GetResolution () : 1.0f;
   CSSPoint point(aPoint.x / resolution, aPoint.y / resolution);
   CSSRect zoomToRect = CalculateRectToZoomTo(document, point);
 
   uint32_t presShellId;
-  FrameMetrics::ViewID viewId;
+  ScrollableLayerGuid::ViewID viewId;
   if (APZCCallbackHelper::GetOrCreateScrollIdentifiers(
       document->GetDocumentElement(), &presShellId, &viewId)) {
     APZThreadUtils::RunOnControllerThread(
       NewRunnableMethod<ScrollableLayerGuid, CSSRect, uint32_t>(
         "IAPZCTreeManager::ZoomToRect",
         mAPZCTreeManager,
         &IAPZCTreeManager::ZoomToRect,
         ScrollableLayerGuid(aGuid.mLayersId, presShellId, viewId),
@@ -273,20 +273,20 @@ ChromeProcessController::NotifyAPZStateC
   if (!mAPZEventState) {
     return;
   }
 
   mAPZEventState->ProcessAPZStateChange(aGuid.mScrollId, aChange, aArg);
 }
 
 void
-ChromeProcessController::NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId, const nsString& aEvent)
+ChromeProcessController::NotifyMozMouseScrollEvent(const ScrollableLayerGuid::ViewID& aScrollId, const nsString& aEvent)
 {
   if (MessageLoop::current() != mUILoop) {
-    mUILoop->PostTask(NewRunnableMethod<FrameMetrics::ViewID, nsString>(
+    mUILoop->PostTask(NewRunnableMethod<ScrollableLayerGuid::ViewID, nsString>(
       "layers::ChromeProcessController::NotifyMozMouseScrollEvent",
       this,
       &ChromeProcessController::NotifyMozMouseScrollEvent,
       aScrollId,
       aEvent));
     return;
   }
 
@@ -297,35 +297,35 @@ void
 ChromeProcessController::NotifyFlushComplete()
 {
   MOZ_ASSERT(IsRepaintThread());
 
   APZCCallbackHelper::NotifyFlushComplete(GetPresShell());
 }
 
 void
-ChromeProcessController::NotifyAsyncScrollbarDragRejected(const FrameMetrics::ViewID& aScrollId)
+ChromeProcessController::NotifyAsyncScrollbarDragRejected(const ScrollableLayerGuid::ViewID& aScrollId)
 {
   if (MessageLoop::current() != mUILoop) {
-    mUILoop->PostTask(NewRunnableMethod<FrameMetrics::ViewID>(
+    mUILoop->PostTask(NewRunnableMethod<ScrollableLayerGuid::ViewID>(
       "layers::ChromeProcessController::NotifyAsyncScrollbarDragRejected",
       this,
       &ChromeProcessController::NotifyAsyncScrollbarDragRejected,
       aScrollId));
     return;
   }
 
   APZCCallbackHelper::NotifyAsyncScrollbarDragRejected(aScrollId);
 }
 
 void
-ChromeProcessController::NotifyAsyncAutoscrollRejected(const FrameMetrics::ViewID& aScrollId)
+ChromeProcessController::NotifyAsyncAutoscrollRejected(const ScrollableLayerGuid::ViewID& aScrollId)
 {
   if (MessageLoop::current() != mUILoop) {
-    mUILoop->PostTask(NewRunnableMethod<FrameMetrics::ViewID>(
+    mUILoop->PostTask(NewRunnableMethod<ScrollableLayerGuid::ViewID>(
       "layers::ChromeProcessController::NotifyAsyncAutoscrollRejected",
       this,
       &ChromeProcessController::NotifyAsyncAutoscrollRejected,
       aScrollId));
     return;
   }
 
   APZCCallbackHelper::NotifyAsyncAutoscrollRejected(aScrollId);
--- a/gfx/layers/apz/util/ChromeProcessController.h
+++ b/gfx/layers/apz/util/ChromeProcessController.h
@@ -57,32 +57,32 @@ public:
                          uint64_t aInputBlockId) override;
   virtual void NotifyPinchGesture(PinchGestureInput::PinchGestureType aType,
                                   const ScrollableLayerGuid& aGuid,
                                   LayoutDeviceCoord aSpanChange,
                                   Modifiers aModifiers) override;
   virtual void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
                                     APZStateChange aChange,
                                     int aArg) override;
-  virtual void NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId,
+  virtual void NotifyMozMouseScrollEvent(const ScrollableLayerGuid::ViewID& aScrollId,
                                          const nsString& aEvent) override;
   virtual void NotifyFlushComplete() override;
-  virtual void NotifyAsyncScrollbarDragRejected(const FrameMetrics::ViewID& aScrollId) override;
-  virtual void NotifyAsyncAutoscrollRejected(const FrameMetrics::ViewID& aScrollId) override;
+  virtual void NotifyAsyncScrollbarDragRejected(const ScrollableLayerGuid::ViewID& aScrollId) override;
+  virtual void NotifyAsyncAutoscrollRejected(const ScrollableLayerGuid::ViewID& aScrollId) override;
   virtual void CancelAutoscroll(const ScrollableLayerGuid& aGuid) override;
 private:
   nsCOMPtr<nsIWidget> mWidget;
   RefPtr<APZEventState> mAPZEventState;
   RefPtr<IAPZCTreeManager> mAPZCTreeManager;
   MessageLoop* mUILoop;
 
   void InitializeRoot();
   nsIPresShell* GetPresShell() const;
   nsIDocument* GetRootDocument() const;
-  nsIDocument* GetRootContentDocument(const FrameMetrics::ViewID& aScrollId) const;
+  nsIDocument* GetRootContentDocument(const ScrollableLayerGuid::ViewID& aScrollId) const;
   void HandleDoubleTap(const mozilla::CSSPoint& aPoint, Modifiers aModifiers,
                        const ScrollableLayerGuid& aGuid);
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif /* mozilla_layers_ChromeProcessController_h */
--- a/gfx/layers/apz/util/ContentProcessController.cpp
+++ b/gfx/layers/apz/util/ContentProcessController.cpp
@@ -61,17 +61,17 @@ ContentProcessController::NotifyAPZState
 {
   if (mBrowser) {
     mBrowser->NotifyAPZStateChange(aGuid.mScrollId, aChange, aArg);
   }
 }
 
 void
 ContentProcessController::NotifyMozMouseScrollEvent(
-                                  const FrameMetrics::ViewID& aScrollId,
+                                  const ScrollableLayerGuid::ViewID& aScrollId,
                                   const nsString& aEvent)
 {
   if (mBrowser) {
     APZCCallbackHelper::NotifyMozMouseScrollEvent(aScrollId, aEvent);
   }
 }
 
 void
@@ -82,23 +82,23 @@ ContentProcessController::NotifyFlushCom
     if (nsCOMPtr<nsIDocument> doc = mBrowser->GetDocument()) {
       shell = doc->GetShell();
     }
     APZCCallbackHelper::NotifyFlushComplete(shell.get());
   }
 }
 
 void
-ContentProcessController::NotifyAsyncScrollbarDragRejected(const FrameMetrics::ViewID& aScrollId)
+ContentProcessController::NotifyAsyncScrollbarDragRejected(const ScrollableLayerGuid::ViewID& aScrollId)
 {
   APZCCallbackHelper::NotifyAsyncScrollbarDragRejected(aScrollId);
 }
 
 void
-ContentProcessController::NotifyAsyncAutoscrollRejected(const FrameMetrics::ViewID& aScrollId)
+ContentProcessController::NotifyAsyncAutoscrollRejected(const ScrollableLayerGuid::ViewID& aScrollId)
 {
   APZCCallbackHelper::NotifyAsyncAutoscrollRejected(aScrollId);
 }
 
 void
 ContentProcessController::CancelAutoscroll(const ScrollableLayerGuid& aGuid)
 {
   // This should never get called
--- a/gfx/layers/apz/util/ContentProcessController.h
+++ b/gfx/layers/apz/util/ContentProcessController.h
@@ -52,24 +52,24 @@ public:
                           const ScrollableLayerGuid& aGuid,
                           LayoutDeviceCoord aSpanChange,
                           Modifiers aModifiers) override;
 
   void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
                             APZStateChange aChange,
                             int aArg) override;
 
-  void NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId,
+  void NotifyMozMouseScrollEvent(const ScrollableLayerGuid::ViewID& aScrollId,
                                  const nsString& aEvent) override;
 
   void NotifyFlushComplete() override;
 
-  void NotifyAsyncScrollbarDragRejected(const FrameMetrics::ViewID& aScrollId) override;
+  void NotifyAsyncScrollbarDragRejected(const ScrollableLayerGuid::ViewID& aScrollId) override;
 
-  void NotifyAsyncAutoscrollRejected(const FrameMetrics::ViewID& aScrollId) override;
+  void NotifyAsyncAutoscrollRejected(const ScrollableLayerGuid::ViewID& aScrollId) override;
 
   void CancelAutoscroll(const ScrollableLayerGuid& aGuid) override;
 
   void PostDelayedTask(already_AddRefed<Runnable> aRunnable, int aDelayMs) override;
 
   bool IsRepaintThread() override;
 
   void DispatchToRepaintThread(already_AddRefed<Runnable> aTask) override;
--- a/gfx/layers/apz/util/InputAPZContext.h
+++ b/gfx/layers/apz/util/InputAPZContext.h
@@ -2,18 +2,18 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_layers_InputAPZContext_h
 #define mozilla_layers_InputAPZContext_h
 
-#include "FrameMetrics.h"
 #include "mozilla/EventForwards.h"
+#include "mozilla/layers/ScrollableLayerGuid.h"
 
 namespace mozilla {
 namespace layers {
 
 // InputAPZContext is used to communicate various pieces of information
 // around the codebase without having to plumb it through lots of functions
 // and codepaths. Conceptually it is attached to a WidgetInputEvent that is
 // relevant to APZ.
--- a/gfx/layers/client/ClientLayerManager.h
+++ b/gfx/layers/client/ClientLayerManager.h
@@ -197,34 +197,34 @@ public:
                             const mozilla::TimeStamp& aCompositeStart,
                             const mozilla::TimeStamp& aCompositeEnd) override;
 
   virtual bool AreComponentAlphaLayersEnabled() override;
 
   // Log APZ test data for the current paint. We supply the paint sequence
   // number ourselves, and take care of calling APZTestData::StartNewPaint()
   // when a new paint is started.
-  void LogTestDataForCurrentPaint(FrameMetrics::ViewID aScrollId,
+  void LogTestDataForCurrentPaint(ScrollableLayerGuid::ViewID aScrollId,
                                   const std::string& aKey,
                                   const std::string& aValue)
   {
     MOZ_ASSERT(gfxPrefs::APZTestLoggingEnabled(), "don't call me");
     mApzTestData.LogTestDataForPaint(mPaintSequenceNumber, aScrollId, aKey, aValue);
   }
 
   // Log APZ test data for a repaint request. The sequence number must be
   // passed in from outside, and APZTestData::StartNewRepaintRequest() needs
   // to be called from the outside as well when a new repaint request is started.
   void StartNewRepaintRequest(SequenceNumber aSequenceNumber);
 
   // TODO(botond): When we start using this and write a wrapper similar to
   // nsLayoutUtils::LogTestDataForPaint(), make sure that wrapper checks
   // gfxPrefs::APZTestLoggingEnabled().
   void LogTestDataForRepaintRequest(SequenceNumber aSequenceNumber,
-                                    FrameMetrics::ViewID aScrollId,
+                                    ScrollableLayerGuid::ViewID aScrollId,
                                     const std::string& aKey,
                                     const std::string& aValue)
   {
     MOZ_ASSERT(gfxPrefs::APZTestLoggingEnabled(), "don't call me");
     mApzTestData.LogTestDataForRepaintRequest(aSequenceNumber, aScrollId, aKey, aValue);
   }
 
   // Get the content-side APZ test data for reading. For writing, use the
--- a/gfx/layers/client/ClientTiledPaintedLayer.cpp
+++ b/gfx/layers/client/ClientTiledPaintedLayer.cpp
@@ -107,17 +107,17 @@ ClientTiledPaintedLayer::GetAncestorLaye
                                            bool* aOutHasTransformAnimation)
 {
   LayerMetricsWrapper scrollAncestor;
   LayerMetricsWrapper displayPortAncestor;
   bool hasTransformAnimation = false;
   for (LayerMetricsWrapper ancestor(this, LayerMetricsWrapper::StartAt::BOTTOM); ancestor; ancestor = ancestor.GetParent()) {
     hasTransformAnimation |= ancestor.HasTransformAnimation();
     const FrameMetrics& metrics = ancestor.Metrics();
-    if (!scrollAncestor && metrics.GetScrollId() != FrameMetrics::NULL_SCROLL_ID) {
+    if (!scrollAncestor && metrics.GetScrollId() != ScrollableLayerGuid::NULL_SCROLL_ID) {
       scrollAncestor = ancestor;
     }
     if (!metrics.GetDisplayPort().IsEmpty()) {
       displayPortAncestor = ancestor;
       // Any layer that has a displayport must be scrollable, so we can break
       // here.
       break;
     }
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -356,36 +356,36 @@ IntervalOverlap(gfxFloat aTranslation, g
 }
 
 /**
  * Finds the metrics on |aLayer| with scroll id |aScrollId|, and returns a
  * LayerMetricsWrapper representing the (layer, metrics) pair, or the null
  * LayerMetricsWrapper if no matching metrics could be found.
  */
 static LayerMetricsWrapper
-FindMetricsWithScrollId(Layer* aLayer, FrameMetrics::ViewID aScrollId)
+FindMetricsWithScrollId(Layer* aLayer, ScrollableLayerGuid::ViewID aScrollId)
 {
   for (uint64_t i = 0; i < aLayer->GetScrollMetadataCount(); ++i) {
     if (aLayer->GetFrameMetrics(i).GetScrollId() == aScrollId) {
       return LayerMetricsWrapper(aLayer, i);
     }
   }
   return LayerMetricsWrapper();
 }
 
 /**
  * Checks whether the (layer, metrics) pair (aTransformedLayer, aTransformedMetrics)
  * is on the path from |aFixedLayer| to the metrics with scroll id
  * |aFixedWithRespectTo|, inclusive.
  */
 static bool
 AsyncTransformShouldBeUnapplied(Layer* aFixedLayer,
-                                FrameMetrics::ViewID aFixedWithRespectTo,
+                                ScrollableLayerGuid::ViewID aFixedWithRespectTo,
                                 Layer* aTransformedLayer,
-                                FrameMetrics::ViewID aTransformedMetrics)
+                                ScrollableLayerGuid::ViewID aTransformedMetrics)
 {
   LayerMetricsWrapper transformed = FindMetricsWithScrollId(aTransformedLayer, aTransformedMetrics);
   if (!transformed.IsValid()) {
     return false;
   }
   // It's important to start at the bottom, because the fixed layer itself
   // could have the transformed metrics, and they can be at the bottom.
   LayerMetricsWrapper current(aFixedLayer, LayerMetricsWrapper::StartAt::BOTTOM);
@@ -412,48 +412,48 @@ AsyncTransformShouldBeUnapplied(Layer* a
       break;
     }
   }
   return false;
 }
 
 // If |aLayer| is fixed or sticky, returns the scroll id of the scroll frame
 // that it's fixed or sticky to. Otherwise, returns Nothing().
-static Maybe<FrameMetrics::ViewID>
+static Maybe<ScrollableLayerGuid::ViewID>
 IsFixedOrSticky(Layer* aLayer)
 {
   bool isRootOfFixedSubtree = aLayer->GetIsFixedPosition() &&
     !aLayer->GetParent()->GetIsFixedPosition();
   if (isRootOfFixedSubtree) {
     return Some(aLayer->GetFixedPositionScrollContainerId());
   }
   if (aLayer->GetIsStickyPosition()) {
     return Some(aLayer->GetStickyScrollContainerId());
   }
   return Nothing();
 }
 
 void
 AsyncCompositionManager::AlignFixedAndStickyLayers(Layer* aTransformedSubtreeRoot,
                                                    Layer* aStartTraversalAt,
-                                                   FrameMetrics::ViewID aTransformScrollId,
+                                                   ScrollableLayerGuid::ViewID aTransformScrollId,
                                                    const LayerToParentLayerMatrix4x4& aPreviousTransformForRoot,
                                                    const LayerToParentLayerMatrix4x4& aCurrentTransformForRoot,
                                                    const ScreenMargin& aFixedLayerMargins,
                                                    ClipPartsCache* aClipPartsCache)
 {
   // We're going to be inverting |aCurrentTransformForRoot|.
   // If it's singular, there's nothing we can do.
   if (aCurrentTransformForRoot.IsSingular()) {
     return;
   }
 
   Layer* layer = aStartTraversalAt;
   bool needsAsyncTransformUnapplied = false;
-  if (Maybe<FrameMetrics::ViewID> fixedTo = IsFixedOrSticky(layer)) {
+  if (Maybe<ScrollableLayerGuid::ViewID> fixedTo = IsFixedOrSticky(layer)) {
     needsAsyncTransformUnapplied = AsyncTransformShouldBeUnapplied(layer,
         *fixedTo, aTransformedSubtreeRoot, aTransformScrollId);
   }
 
   // We want to process all the fixed and sticky descendants of
   // aTransformedSubtreeRoot. Once we do encounter such a descendant, we don't
   // need to recurse any deeper because the adjustment to the fixed or sticky
   // layer will apply to its subtree.
@@ -850,17 +850,17 @@ ExpandRootClipRect(Layer* aLayer, const 
     rect.Deflate(ViewAs<ParentLayerPixel>(aFixedLayerMargins,
       PixelCastJustification::ScreenIsParentLayerForRoot));
     aLayer->AsHostLayer()->SetShadowClipRect(Some(RoundedOut(rect)));
   }
 }
 
 #ifdef MOZ_WIDGET_ANDROID
 static void
-MoveScrollbarForLayerMargin(Layer* aRoot, FrameMetrics::ViewID aRootScrollId,
+MoveScrollbarForLayerMargin(Layer* aRoot, ScrollableLayerGuid::ViewID aRootScrollId,
                             const ScreenMargin& aFixedLayerMargins)
 {
   // See bug 1223928 comment 9 - once we can detect the RCD with just the
   // isRootContent flag on the metrics, we can probably move this code into
   // ApplyAsyncTransformToScrollbar rather than having it as a separate
   // adjustment on the layer tree.
   Layer* scrollbar = BreadthFirstSearch<ReverseIterator>(aRoot,
     [aRootScrollId](Layer* aNode) {
--- a/gfx/layers/composite/AsyncCompositionManager.h
+++ b/gfx/layers/composite/AsyncCompositionManager.h
@@ -166,17 +166,17 @@ private:
    * |aClipPartsCache| optionally maps layers to separate fixed and scrolled
    * clips, so we can only adjust the fixed portion.
    * This function has a recursive implementation; aStartTraversalAt specifies
    * where to start the current recursion of the traversal. For the initial
    * call, it should be the same as aTrasnformedSubtreeRoot.
    */
   void AlignFixedAndStickyLayers(Layer* aTransformedSubtreeRoot,
                                  Layer* aStartTraversalAt,
-                                 FrameMetrics::ViewID aTransformScrollId,
+                                 ScrollableLayerGuid::ViewID aTransformScrollId,
                                  const LayerToParentLayerMatrix4x4& aPreviousTransformForRoot,
                                  const LayerToParentLayerMatrix4x4& aCurrentTransformForRoot,
                                  const ScreenMargin& aFixedLayerMargins,
                                  ClipPartsCache* aClipPartsCache);
 
   /**
    * DRAWING PHASE ONLY
    *
@@ -228,17 +228,17 @@ private:
 
 #ifdef MOZ_WIDGET_ANDROID
 public:
   void SetFixedLayerMargins(ScreenIntCoord aTop, ScreenIntCoord aBottom);
 private:
   // The following two fields are only needed on Fennec with C++ APZ, because
   // then we need to reposition the gecko scrollbar to deal with the
   // dynamic toolbar shifting content around.
-  FrameMetrics::ViewID mRootScrollableId;
+  ScrollableLayerGuid::ViewID mRootScrollableId;
   ScreenMargin mFixedLayerMargins;
 #endif
 };
 
 class MOZ_STACK_CLASS AutoResolveRefLayers {
 public:
   explicit AutoResolveRefLayers(AsyncCompositionManager* aManager,
                                 CompositorBridgeParent* aCompositor = nullptr,
--- a/gfx/layers/ipc/APZCTreeManagerChild.cpp
+++ b/gfx/layers/ipc/APZCTreeManagerChild.cpp
@@ -181,17 +181,17 @@ APZCTreeManagerChild::RecvNotifyPinchGes
   if (mCompositorSession &&
       mCompositorSession->GetWidget()) {
     APZCCallbackHelper::NotifyPinchGesture(aType, aSpanChange, aModifiers, mCompositorSession->GetWidget());
   }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
-APZCTreeManagerChild::RecvCancelAutoscroll(const FrameMetrics::ViewID& aScrollId)
+APZCTreeManagerChild::RecvCancelAutoscroll(const ScrollableLayerGuid::ViewID& aScrollId)
 {
   // This will only get sent from the GPU process to the parent process, so
   // this function should never get called in the content process.
   MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(NS_IsMainThread());
 
   APZCCallbackHelper::CancelAutoscroll(aScrollId);
   return IPC_OK();
--- a/gfx/layers/ipc/APZCTreeManagerChild.h
+++ b/gfx/layers/ipc/APZCTreeManagerChild.h
@@ -86,17 +86,17 @@ protected:
                                         const ScrollableLayerGuid& aGuid,
                                         const uint64_t& aInputBlockId) override;
 
   mozilla::ipc::IPCResult RecvNotifyPinchGesture(const PinchGestureType& aType,
                                                  const ScrollableLayerGuid& aGuid,
                                                  const LayoutDeviceCoord& aSpanChange,
                                                  const Modifiers& aModifiers) override;
 
-  mozilla::ipc::IPCResult RecvCancelAutoscroll(const FrameMetrics::ViewID& aScrollId) override;
+  mozilla::ipc::IPCResult RecvCancelAutoscroll(const ScrollableLayerGuid::ViewID& aScrollId) override;
 
   virtual ~APZCTreeManagerChild();
 
 private:
   MOZ_NON_OWNING_REF RemoteCompositorSession* mCompositorSession;
   RefPtr<APZInputBridgeChild> mInputBridge;
 };
 
--- a/gfx/layers/ipc/CompositorBridgeChild.cpp
+++ b/gfx/layers/ipc/CompositorBridgeChild.cpp
@@ -221,17 +221,17 @@ CompositorBridgeChild::ShutDown()
 {
   if (sCompositorBridge) {
     sCompositorBridge->Destroy();
     SpinEventLoopUntil([&]() { return !sCompositorBridge; });
   }
 }
 
 bool
-CompositorBridgeChild::LookupCompositorFrameMetrics(const FrameMetrics::ViewID aId,
+CompositorBridgeChild::LookupCompositorFrameMetrics(const ScrollableLayerGuid::ViewID aId,
                                                     FrameMetrics& aFrame)
 {
   SharedFrameMetricsData* data = mFrameMetricsTable.Get(aId);
   if (data) {
     data->CopyFrameMetrics(&aFrame);
     return true;
   }
   return false;
@@ -643,17 +643,17 @@ CompositorBridgeChild::SharedFrameMetric
   const FrameMetrics* frame =
     static_cast<const FrameMetrics*>(mBuffer->memory());
   MOZ_ASSERT(frame);
   mMutex->Lock();
   *aFrame = *frame;
   mMutex->Unlock();
 }
 
-FrameMetrics::ViewID
+ScrollableLayerGuid::ViewID
 CompositorBridgeChild::SharedFrameMetricsData::GetViewID()
 {
   const FrameMetrics* frame =
     static_cast<const FrameMetrics*>(mBuffer->memory());
   MOZ_ASSERT(frame);
   // Not locking to read of mScrollId since it should not change after being
   // initially set.
   return frame->GetScrollId();
--- a/gfx/layers/ipc/CompositorBridgeChild.h
+++ b/gfx/layers/ipc/CompositorBridgeChild.h
@@ -67,20 +67,20 @@ public:
   void InitForWidget(uint64_t aProcessToken,
                      LayerManager* aLayerManager,
                      uint32_t aNamespace);
 
   void Destroy();
 
   /**
    * Lookup the FrameMetrics shared by the compositor process with the
-   * associated FrameMetrics::ViewID. The returned FrameMetrics is used
+   * associated ScrollableLayerGuid::ViewID. The returned FrameMetrics is used
    * in progressive paint calculations.
    */
-  bool LookupCompositorFrameMetrics(const FrameMetrics::ViewID aId, FrameMetrics&);
+  bool LookupCompositorFrameMetrics(const ScrollableLayerGuid::ViewID aId, FrameMetrics&);
 
   static CompositorBridgeChild* Get();
 
   static bool ChildProcessHasCompositorBridge();
 
   // Returns whether the compositor is in the GPU process (false if in the UI
   // process). This may only be called on the main thread.
   static bool CompositorIsInGPUProcess();
@@ -296,17 +296,17 @@ private:
         const mozilla::ipc::SharedMemoryBasic::Handle& metrics,
         const CrossProcessMutexHandle& handle,
         const LayersId& aLayersId,
         const uint32_t& aAPZCId);
 
     ~SharedFrameMetricsData();
 
     void CopyFrameMetrics(FrameMetrics* aFrame);
-    FrameMetrics::ViewID GetViewID();
+    ScrollableLayerGuid::ViewID GetViewID();
     LayersId GetLayersId() const;
     uint32_t GetAPZCId();
 
   private:
     // Pointer to the class that allows access to the shared memory that contains
     // the shared FrameMetrics
     RefPtr<mozilla::ipc::SharedMemoryBasic> mBuffer;
     CrossProcessMutex* mMutex;
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -224,23 +224,23 @@ CompositorBridgeParentBase::StartSharing
   if (!mCanSend) {
     return false;
   }
   return PCompositorBridgeParent::SendSharedCompositorFrameMetrics(
     aHandle, aMutexHandle, aLayersId, aApzcId);
 }
 
 bool
-CompositorBridgeParentBase::StopSharingMetrics(FrameMetrics::ViewID aScrollId,
+CompositorBridgeParentBase::StopSharingMetrics(ScrollableLayerGuid::ViewID aScrollId,
                                                uint32_t aApzcId)
 {
   if (!CompositorThreadHolder::IsInCompositorThread()) {
     MOZ_ASSERT(CompositorLoop());
     CompositorLoop()->PostTask(
-      NewRunnableMethod<FrameMetrics::ViewID, uint32_t>(
+      NewRunnableMethod<ScrollableLayerGuid::ViewID, uint32_t>(
         "layers::CompositorBridgeParent::StopSharingMetrics",
         this,
         &CompositorBridgeParentBase::StopSharingMetrics,
         aScrollId, aApzcId));
     return true;
   }
 
   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
@@ -1464,29 +1464,29 @@ CompositorBridgeParent::RecvGetFrameUnif
 {
   mCompositionManager->GetFrameUniformity(aOutData);
   return IPC_OK();
 }
 
 void
 CompositorBridgeParent::SetTestAsyncScrollOffset(
     const LayersId& aLayersId,
-    const FrameMetrics::ViewID& aScrollId,
+    const ScrollableLayerGuid::ViewID& aScrollId,
     const CSSPoint& aPoint)
 {
   if (mApzUpdater) {
     MOZ_ASSERT(aLayersId.IsValid());
     mApzUpdater->SetTestAsyncScrollOffset(aLayersId, aScrollId, aPoint);
   }
 }
 
 void
 CompositorBridgeParent::SetTestAsyncZoom(
     const LayersId& aLayersId,
-    const FrameMetrics::ViewID& aScrollId,
+    const ScrollableLayerGuid::ViewID& aScrollId,
     const LayerToParentLayerScale& aZoom)
 {
   if (mApzUpdater) {
     MOZ_ASSERT(aLayersId.IsValid());
     mApzUpdater->SetTestAsyncZoom(aLayersId, aScrollId, aZoom);
   }
 }
 
--- a/gfx/layers/ipc/CompositorBridgeParent.h
+++ b/gfx/layers/ipc/CompositorBridgeParent.h
@@ -112,20 +112,20 @@ public:
   virtual void ScheduleComposite(LayerTransactionParent* aLayerTree) { }
   virtual bool SetTestSampleTime(const LayersId& aId,
                                  const TimeStamp& aTime) { return true; }
   virtual void LeaveTestMode(const LayersId& aId) { }
   enum class TransformsToSkip : uint8_t { NoneOfThem = 0, APZ = 1 };
   virtual void ApplyAsyncProperties(LayerTransactionParent* aLayerTree,
                                     TransformsToSkip aSkip) = 0;
   virtual void SetTestAsyncScrollOffset(const LayersId& aLayersId,
-                                        const FrameMetrics::ViewID& aScrollId,
+                                        const ScrollableLayerGuid::ViewID& aScrollId,
                                         const CSSPoint& aPoint) = 0;
   virtual void SetTestAsyncZoom(const LayersId& aLayersId,
-                                const FrameMetrics::ViewID& aScrollId,
+                                const ScrollableLayerGuid::ViewID& aScrollId,
                                 const LayerToParentLayerScale& aZoom) = 0;
   virtual void FlushApzRepaints(const LayersId& aLayersId) = 0;
   virtual void GetAPZTestData(const LayersId& aLayersId,
                               APZTestData* aOutData) { }
   virtual void SetConfirmedTargetAPZC(const LayersId& aLayersId,
                                       const uint64_t& aInputBlockId,
                                       const nsTArray<ScrollableLayerGuid>& aTargets) = 0;
   virtual void UpdatePaintTime(LayerTransactionParent* aLayerTree, const TimeDuration& aPaintTime) {}
@@ -159,17 +159,17 @@ public:
   // MetricsSharingController
   NS_IMETHOD_(MozExternalRefCountType) AddRef() override { return HostIPCAllocator::AddRef(); }
   NS_IMETHOD_(MozExternalRefCountType) Release() override { return HostIPCAllocator::Release(); }
   base::ProcessId RemotePid() override;
   bool StartSharingMetrics(mozilla::ipc::SharedMemoryBasic::Handle aHandle,
                            CrossProcessMutexHandle aMutexHandle,
                            LayersId aLayersId,
                            uint32_t aApzcId) override;
-  bool StopSharingMetrics(FrameMetrics::ViewID aScrollId,
+  bool StopSharingMetrics(ScrollableLayerGuid::ViewID aScrollId,
                           uint32_t aApzcId) override;
 
   virtual bool IsRemote() const {
     return false;
   }
 
   virtual void ForceComposeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect = nullptr) {
     MOZ_CRASH();
@@ -250,20 +250,20 @@ public:
   void ScheduleComposite(LayerTransactionParent* aLayerTree) override;
   bool SetTestSampleTime(const LayersId& aId,
                          const TimeStamp& aTime) override;
   void LeaveTestMode(const LayersId& aId) override;
   void ApplyAsyncProperties(LayerTransactionParent* aLayerTree,
                             TransformsToSkip aSkip) override;
   CompositorAnimationStorage* GetAnimationStorage();
   void SetTestAsyncScrollOffset(const LayersId& aLayersId,
-                                const FrameMetrics::ViewID& aScrollId,
+                                const ScrollableLayerGuid::ViewID& aScrollId,
                                 const CSSPoint& aPoint) override;
   void SetTestAsyncZoom(const LayersId& aLayersId,
-                        const FrameMetrics::ViewID& aScrollId,
+                        const ScrollableLayerGuid::ViewID& aScrollId,
                         const LayerToParentLayerScale& aZoom) override;
   void FlushApzRepaints(const LayersId& aLayersId) override;
   void GetAPZTestData(const LayersId& aLayersId,
                       APZTestData* aOutData) override;
   void SetConfirmedTargetAPZC(const LayersId& aLayersId,
                               const uint64_t& aInputBlockId,
                               const nsTArray<ScrollableLayerGuid>& aTargets) override;
   AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aLayerTree) override { return mCompositionManager; }
--- a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
@@ -471,34 +471,34 @@ CrossProcessCompositorBridgeParent::Appl
 
   MOZ_ASSERT(state->mParent);
   state->mParent->ApplyAsyncProperties(aLayerTree, aSkip);
 }
 
 void
 CrossProcessCompositorBridgeParent::SetTestAsyncScrollOffset(
     const LayersId& aLayersId,
-    const FrameMetrics::ViewID& aScrollId,
+    const ScrollableLayerGuid::ViewID& aScrollId,
     const CSSPoint& aPoint)
 {
   MOZ_ASSERT(aLayersId.IsValid());
   const CompositorBridgeParent::LayerTreeState* state =
     CompositorBridgeParent::GetIndirectShadowTree(aLayersId);
   if (!state) {
     return;
   }
 
   MOZ_ASSERT(state->mParent);
   state->mParent->SetTestAsyncScrollOffset(aLayersId, aScrollId, aPoint);
 }
 
 void
 CrossProcessCompositorBridgeParent::SetTestAsyncZoom(
     const LayersId& aLayersId,
-    const FrameMetrics::ViewID& aScrollId,
+    const ScrollableLayerGuid::ViewID& aScrollId,
     const LayerToParentLayerScale& aZoom)
 {
   MOZ_ASSERT(aLayersId.IsValid());
   const CompositorBridgeParent::LayerTreeState* state =
     CompositorBridgeParent::GetIndirectShadowTree(aLayersId);
   if (!state) {
     return;
   }
--- a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.h
+++ b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.h
@@ -85,20 +85,20 @@ public:
   void ScheduleComposite(LayerTransactionParent* aLayerTree) override;
   void NotifyClearCachedResources(LayerTransactionParent* aLayerTree) override;
   bool SetTestSampleTime(const LayersId& aId,
                          const TimeStamp& aTime) override;
   void LeaveTestMode(const LayersId& aId) override;
   void ApplyAsyncProperties(LayerTransactionParent* aLayerTree,
                             TransformsToSkip aSkip) override;
   void SetTestAsyncScrollOffset(const LayersId& aLayersId,
-                                const FrameMetrics::ViewID& aScrollId,
+                                const ScrollableLayerGuid::ViewID& aScrollId,
                                 const CSSPoint& aPoint) override;
   void SetTestAsyncZoom(const LayersId& aLayersId,
-                        const FrameMetrics::ViewID& aScrollId,
+                        const ScrollableLayerGuid::ViewID& aScrollId,
                         const LayerToParentLayerScale& aZoom) override;
   void FlushApzRepaints(const LayersId& aLayersId) override;
   void GetAPZTestData(const LayersId& aLayersId,
                       APZTestData* aOutData) override;
   void SetConfirmedTargetAPZC(const LayersId& aLayersId,
                               const uint64_t& aInputBlockId,
                               const nsTArray<ScrollableLayerGuid>& aTargets) override;
 
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -763,29 +763,29 @@ LayerTransactionParent::RecvGetTransform
   }
 
   *aTransform = transform;
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
-LayerTransactionParent::RecvSetAsyncScrollOffset(const FrameMetrics::ViewID& aScrollID,
+LayerTransactionParent::RecvSetAsyncScrollOffset(const ScrollableLayerGuid::ViewID& aScrollID,
                                                  const float& aX, const float& aY)
 {
   if (mDestroyed || !mLayerManager || mLayerManager->IsDestroyed()) {
     return IPC_FAIL_NO_REASON(this);
   }
 
   mCompositorBridge->SetTestAsyncScrollOffset(GetId(), aScrollID, CSSPoint(aX, aY));
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
-LayerTransactionParent::RecvSetAsyncZoom(const FrameMetrics::ViewID& aScrollID,
+LayerTransactionParent::RecvSetAsyncZoom(const ScrollableLayerGuid::ViewID& aScrollID,
                                          const float& aValue)
 {
   if (mDestroyed || !mLayerManager || mLayerManager->IsDestroyed()) {
     return IPC_FAIL_NO_REASON(this);
   }
 
   mCompositorBridge->SetTestAsyncZoom(GetId(), aScrollID, LayerToParentLayerScale(aValue));
   return IPC_OK();
--- a/gfx/layers/ipc/LayerTransactionParent.h
+++ b/gfx/layers/ipc/LayerTransactionParent.h
@@ -124,19 +124,19 @@ protected:
   mozilla::ipc::IPCResult RecvClearCachedResources() override;
   mozilla::ipc::IPCResult RecvScheduleComposite() override;
   mozilla::ipc::IPCResult RecvSetTestSampleTime(const TimeStamp& aTime) override;
   mozilla::ipc::IPCResult RecvLeaveTestMode() override;
   mozilla::ipc::IPCResult RecvGetAnimationValue(const uint64_t& aCompositorAnimationsId,
                                                 OMTAValue* aValue) override;
   mozilla::ipc::IPCResult RecvGetTransform(const LayerHandle& aHandle,
                                            MaybeTransform* aTransform) override;
-  mozilla::ipc::IPCResult RecvSetAsyncScrollOffset(const FrameMetrics::ViewID& aId,
+  mozilla::ipc::IPCResult RecvSetAsyncScrollOffset(const ScrollableLayerGuid::ViewID& aId,
                                                    const float& aX, const float& aY) override;
-  mozilla::ipc::IPCResult RecvSetAsyncZoom(const FrameMetrics::ViewID& aId,
+  mozilla::ipc::IPCResult RecvSetAsyncZoom(const ScrollableLayerGuid::ViewID& aId,
                                            const float& aValue) override;
   mozilla::ipc::IPCResult RecvFlushApzRepaints() override;
   mozilla::ipc::IPCResult RecvGetAPZTestData(APZTestData* aOutData) override;
   mozilla::ipc::IPCResult RecvRequestProperty(const nsString& aProperty, float* aValue) override;
   mozilla::ipc::IPCResult RecvSetConfirmedTargetAPZC(const uint64_t& aBlockId,
                                                      nsTArray<ScrollableLayerGuid>&& aTargets) override;
   mozilla::ipc::IPCResult RecvRecordPaintTimes(const PaintTiming& aTiming) override;
   mozilla::ipc::IPCResult RecvGetTextureFactoryIdentifier(TextureFactoryIdentifier* aIdentifier) override;
--- a/gfx/layers/ipc/LayersMessages.ipdlh
+++ b/gfx/layers/ipc/LayersMessages.ipdlh
@@ -38,19 +38,18 @@ using mozilla::LayerIntRegion from "Unit
 using mozilla::ParentLayerIntRect from "Units.h";
 using mozilla::LayoutDeviceIntRect from "Units.h";
 using mozilla::layers::ScaleMode from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::EventRegions from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::EventRegionsOverride from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::DiagnosticTypes from "mozilla/layers/CompositorTypes.h";
 using mozilla::layers::FocusTarget from "mozilla/layers/FocusTarget.h";
 using struct mozilla::layers::ScrollMetadata from "FrameMetrics.h";
-using mozilla::layers::FrameMetrics::ViewID from "FrameMetrics.h";
+using mozilla::layers::ScrollableLayerGuid::ViewID from "mozilla/layers/ScrollableLayerGuid.h";
 using mozilla::layers::LayersBackend from "mozilla/layers/LayersTypes.h";
-using mozilla::layers::MaybeLayerClip from "FrameMetrics.h";
 using mozilla::layers::LayerHandle from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::CompositableHandle from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::SimpleLayerAttributes from "mozilla/layers/LayerAttributes.h";
 using mozilla::CrossProcessSemaphoreHandle from "mozilla/ipc/CrossProcessSemaphore.h";
 using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
 using mozilla::layers::LayersId from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::TransactionId from "mozilla/layers/LayersTypes.h";
 
--- a/gfx/layers/ipc/PAPZ.ipdl
+++ b/gfx/layers/ipc/PAPZ.ipdl
@@ -7,19 +7,19 @@
 
 include "mozilla/GfxMessageUtils.h";
 include "mozilla/layers/LayersMessageUtils.h";
 
 include protocol PCompositorBridge;
 
 using CSSRect from "Units.h";
 using struct mozilla::layers::RepaintRequest from "mozilla/layers/RepaintRequest.h";
-using struct mozilla::layers::ScrollableLayerGuid from "FrameMetrics.h";
-using mozilla::layers::FrameMetrics::ViewID from "FrameMetrics.h";
-using mozilla::layers::MaybeZoomConstraints from "FrameMetrics.h";
+using struct mozilla::layers::ScrollableLayerGuid from "mozilla/layers/ScrollableLayerGuid.h";
+using mozilla::layers::ScrollableLayerGuid::ViewID from "mozilla/layers/ScrollableLayerGuid.h";
+using mozilla::layers::MaybeZoomConstraints from "mozilla/layers/ZoomConstraints.h";
 using mozilla::layers::GeckoContentController::APZStateChange from "mozilla/layers/GeckoContentController.h";
 using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h";
 using mozilla::dom::ContentParentId from "mozilla/dom/ipc/IdType.h";
 using mozilla::layers::AsyncDragMetrics from "mozilla/layers/AsyncDragMetrics.h";
 using class nsRegion from "nsRegion.h";
 
 namespace mozilla {
 namespace layers {
--- a/gfx/layers/ipc/PAPZCTreeManager.ipdl
+++ b/gfx/layers/ipc/PAPZCTreeManager.ipdl
@@ -8,19 +8,19 @@ include "mozilla/layers/LayersMessageUti
 include "ipc/nsGUIEventIPC.h";
 
 include protocol PCompositorBridge;
 
 using CSSRect from "Units.h";
 using LayoutDeviceCoord from "Units.h";
 using mozilla::LayoutDevicePoint from "Units.h";
 using ScreenPoint from "Units.h";
-using struct mozilla::layers::ScrollableLayerGuid from "FrameMetrics.h";
-using mozilla::layers::MaybeZoomConstraints from "FrameMetrics.h";
-using mozilla::layers::FrameMetrics::ViewID from "FrameMetrics.h";
+using mozilla::layers::MaybeZoomConstraints from "mozilla/layers/ZoomConstraints.h";
+using struct mozilla::layers::ScrollableLayerGuid from "mozilla/layers/ScrollableLayerGuid.h";
+using mozilla::layers::ScrollableLayerGuid::ViewID from "mozilla/layers/ScrollableLayerGuid.h";
 using mozilla::layers::TouchBehaviorFlags from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::AsyncDragMetrics from "mozilla/layers/AsyncDragMetrics.h";
 using mozilla::layers::GeckoContentController::TapType from "mozilla/layers/GeckoContentController.h";
 using class mozilla::layers::KeyboardMap from "mozilla/layers/KeyboardMap.h";
 
 using mozilla::Modifiers from "mozilla/EventForwards.h";
 using mozilla::PinchGestureInput::PinchGestureType from "InputData.h";
 
--- a/gfx/layers/ipc/PAPZInputBridge.ipdl
+++ b/gfx/layers/ipc/PAPZInputBridge.ipdl
@@ -1,15 +1,15 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 using LayoutDeviceIntPoint from "Units.h";
-using struct mozilla::layers::ScrollableLayerGuid from "FrameMetrics.h";
+using struct mozilla::layers::ScrollableLayerGuid from "mozilla/layers/ScrollableLayerGuid.h";
 
 using nsEventStatus from "mozilla/EventForwards.h";
 using EventMessage from "mozilla/EventForwards.h";
 using class mozilla::MultiTouchInput from "InputData.h";
 using class mozilla::MouseInput from "InputData.h";
 using class mozilla::PanGestureInput from "InputData.h";
 using class mozilla::PinchGestureInput from "InputData.h";
 using class mozilla::TapGestureInput from "InputData.h";
--- a/gfx/layers/ipc/PCompositorBridge.ipdl
+++ b/gfx/layers/ipc/PCompositorBridge.ipdl
@@ -18,20 +18,19 @@ include protocol PTexture;
 include protocol PWebRenderBridge;
 include "mozilla/GfxMessageUtils.h";
 include "mozilla/layers/LayersMessageUtils.h";
 include "mozilla/layers/WebRenderMessageUtils.h";
 
 using struct mozilla::null_t from "ipc/IPCMessageUtils.h";
 using struct mozilla::layers::LayersId from "mozilla/layers/LayersTypes.h";
 using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/CompositorTypes.h";
-using struct mozilla::layers::FrameMetrics from "FrameMetrics.h";
-using mozilla::layers::FrameMetrics::ViewID from "FrameMetrics.h";
-using mozilla::layers::MaybeZoomConstraints from "FrameMetrics.h";
-using struct mozilla::layers::ScrollableLayerGuid from "FrameMetrics.h";
+using struct mozilla::layers::ScrollableLayerGuid from "mozilla/layers/ScrollableLayerGuid.h";
+using mozilla::layers::ScrollableLayerGuid::ViewID from "mozilla/layers/ScrollableLayerGuid.h";
+using mozilla::layers::MaybeZoomConstraints from "mozilla/layers/ZoomConstraints.h";
 using mozilla::layers::LayersBackend from "mozilla/layers/LayersTypes.h";
 using mozilla::CrossProcessMutexHandle from "mozilla/ipc/CrossProcessMutex.h";
 using mozilla::ipc::SharedMemoryBasic::Handle from "mozilla/ipc/SharedMemoryBasic.h";
 using mozilla::CSSIntRegion from "Units.h";
 using mozilla::LayoutDeviceIntPoint from "Units.h";
 using mozilla::LayoutDeviceIntRegion from "Units.h";
 using mozilla::LayoutDeviceIntSize from "Units.h";
 using class mozilla::TimeStamp from "mozilla/TimeStamp.h";
--- a/gfx/layers/ipc/PLayerTransaction.ipdl
+++ b/gfx/layers/ipc/PLayerTransaction.ipdl
@@ -13,18 +13,18 @@ include protocol PTexture;
 
 include "mozilla/GfxMessageUtils.h";
 include "mozilla/layers/LayersMessageUtils.h";
 
 using struct mozilla::layers::TextureInfo from "mozilla/layers/CompositorTypes.h";
 using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
 using struct mozilla::null_t from "ipc/IPCMessageUtils.h";
 using class mozilla::layers::APZTestData from "mozilla/layers/APZTestData.h";
-using mozilla::layers::FrameMetrics::ViewID from "FrameMetrics.h";
-using struct mozilla::layers::ScrollableLayerGuid from "FrameMetrics.h";
+using mozilla::layers::ScrollableLayerGuid::ViewID from "mozilla/layers/ScrollableLayerGuid.h";
+using struct mozilla::layers::ScrollableLayerGuid from "mozilla/layers/ScrollableLayerGuid.h";
 using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/CompositorTypes.h";
 using mozilla::layers::LayersBackend from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::LayerHandle from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::CompositableHandle from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::LayersObserverEpoch from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::TransactionId from "mozilla/layers/LayersTypes.h";
 
 /**
--- a/gfx/layers/ipc/PTexture.ipdl
+++ b/gfx/layers/ipc/PTexture.ipdl
@@ -8,17 +8,16 @@
 include LayersSurfaces;
 include protocol PLayerTransaction;
 include protocol PCompositorBridge;
 include protocol PImageBridge;
 include protocol PVideoBridge;
 include "mozilla/GfxMessageUtils.h";
 include "mozilla/layers/LayersMessageUtils.h";
 
-using struct mozilla::layers::FrameMetrics from "FrameMetrics.h";
 using mozilla::layers::TextureFlags from "mozilla/layers/CompositorTypes.h";
 
 namespace mozilla {
 namespace layers {
 
 /**
  * PTexture is the IPDL glue between a TextureClient and a TextureHost.
  */
--- a/gfx/layers/ipc/PWebRenderBridge.ipdl
+++ b/gfx/layers/ipc/PWebRenderBridge.ipdl
@@ -11,17 +11,17 @@ include "mozilla/GfxMessageUtils.h";
 include "mozilla/layers/WebRenderMessageUtils.h";
 
 include WebRenderMessages;
 include protocol PCompositorBridge;
 include protocol PTexture;
 
 using mozilla::layers::APZTestData from "mozilla/layers/APZTestData.h";
 using mozilla::layers::ScrollUpdatesMap from "FrameMetrics.h";
-using struct mozilla::layers::ScrollableLayerGuid from "FrameMetrics.h";
+using struct mozilla::layers::ScrollableLayerGuid from "mozilla/layers/ScrollableLayerGuid.h";
 using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/CompositorTypes.h";
 using struct mozilla::layers::TextureInfo from "mozilla/layers/CompositorTypes.h";
 using mozilla::layers::CompositableHandle from "mozilla/layers/LayersTypes.h";
 using mozilla::wr::BuiltDisplayListDescriptor from "mozilla/webrender/webrender_ffi.h";
 using mozilla::wr::IdNamespace from "mozilla/webrender/WebRenderTypes.h";
 using mozilla::wr::MaybeIdNamespace from "mozilla/webrender/WebRenderTypes.h";
 using mozilla::layers::WebRenderScrollData from "mozilla/layers/WebRenderScrollData.h";
 using mozilla::layers::FocusTarget from "mozilla/layers/FocusTarget.h";
--- a/gfx/layers/ipc/RemoteContentController.cpp
+++ b/gfx/layers/ipc/RemoteContentController.cpp
@@ -269,23 +269,23 @@ RemoteContentController::UpdateOverscrol
     return;
   }
   if (mCanSend) {
     Unused << SendUpdateOverscrollOffset(aX, aY, aIsRootContent);
   }
 }
 
 void
-RemoteContentController::NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId,
+RemoteContentController::NotifyMozMouseScrollEvent(const ScrollableLayerGuid::ViewID& aScrollId,
                                                    const nsString& aEvent)
 {
   if (MessageLoop::current() != mCompositorThread) {
     // We have to send messages from the compositor thread
     mCompositorThread->PostTask(
-      NewRunnableMethod<FrameMetrics::ViewID, nsString>(
+      NewRunnableMethod<ScrollableLayerGuid::ViewID, nsString>(
         "layers::RemoteContentController::NotifyMozMouseScrollEvent",
         this,
         &RemoteContentController::NotifyMozMouseScrollEvent,
         aScrollId,
         aEvent));
     return;
   }
 
@@ -300,39 +300,39 @@ RemoteContentController::NotifyFlushComp
   MOZ_ASSERT(IsRepaintThread());
 
   if (mCanSend) {
     Unused << SendNotifyFlushComplete();
   }
 }
 
 void
-RemoteContentController::NotifyAsyncScrollbarDragRejected(const FrameMetrics::ViewID& aScrollId)
+RemoteContentController::NotifyAsyncScrollbarDragRejected(const ScrollableLayerGuid::ViewID& aScrollId)
 {
   if (MessageLoop::current() != mCompositorThread) {
     // We have to send messages from the compositor thread
-    mCompositorThread->PostTask(NewRunnableMethod<FrameMetrics::ViewID>(
+    mCompositorThread->PostTask(NewRunnableMethod<ScrollableLayerGuid::ViewID>(
       "layers::RemoteContentController::NotifyAsyncScrollbarDragRejected",
       this,
       &RemoteContentController::NotifyAsyncScrollbarDragRejected,
       aScrollId));
     return;
   }
 
   if (mCanSend) {
     Unused << SendNotifyAsyncScrollbarDragRejected(aScrollId);
   }
 }
 
 void
-RemoteContentController::NotifyAsyncAutoscrollRejected(const FrameMetrics::ViewID& aScrollId)
+RemoteContentController::NotifyAsyncAutoscrollRejected(const ScrollableLayerGuid::ViewID& aScrollId)
 {
   if (MessageLoop::current() != mCompositorThread) {
     // We have to send messages from the compositor thread
-    mCompositorThread->PostTask(NewRunnableMethod<FrameMetrics::ViewID>(
+    mCompositorThread->PostTask(NewRunnableMethod<ScrollableLayerGuid::ViewID>(
       "layers::RemoteContentController::NotifyAsyncAutoscrollRejected",
       this,
       &RemoteContentController::NotifyAsyncAutoscrollRejected,
       aScrollId));
     return;
   }
 
   if (mCanSend) {
--- a/gfx/layers/ipc/RemoteContentController.h
+++ b/gfx/layers/ipc/RemoteContentController.h
@@ -61,24 +61,24 @@ public:
   virtual void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
                                     APZStateChange aChange,
                                     int aArg) override;
 
   virtual void UpdateOverscrollVelocity(float aX, float aY, bool aIsRootContent) override;
 
   virtual void UpdateOverscrollOffset(float aX, float aY, bool aIsRootContent) override;
 
-  virtual void NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId,
+  virtual void NotifyMozMouseScrollEvent(const ScrollableLayerGuid::ViewID& aScrollId,
                                          const nsString& aEvent) override;
 
   virtual void NotifyFlushComplete() override;
 
-  virtual void NotifyAsyncScrollbarDragRejected(const FrameMetrics::ViewID& aScrollId) override;
+  virtual void NotifyAsyncScrollbarDragRejected(const ScrollableLayerGuid::ViewID& aScrollId) override;
 
-  virtual void NotifyAsyncAutoscrollRejected(const FrameMetrics::ViewID& aScrollId) override;
+  virtual void NotifyAsyncAutoscrollRejected(const ScrollableLayerGuid::ViewID& aScrollId) override;
 
   virtual void CancelAutoscroll(const ScrollableLayerGuid& aScrollId) override;
 
   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 
   virtual void Destroy() override;
 
 private:
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -224,16 +224,17 @@ EXPORTS.mozilla.layers += [
     'opengl/TextureClientOGL.h',
     'opengl/TextureHostOGL.h',
     'PaintThread.h',
     'PersistentBufferProvider.h',
     'ProfilerScreenshots.h',
     'RenderTrace.h',
     'RepaintRequest.h',
     'RotatedBuffer.h',
+    'ScrollableLayerGuid.h',
     'ShareableCanvasRenderer.h',
     'SourceSurfaceSharedData.h',
     'SourceSurfaceVolatileData.h',
     'SyncObject.h',
     'TextureSourceProvider.h',
     'TextureWrapperImage.h',
     'TransactionIdAllocator.h',
     'UpdateImageHelper.h',
@@ -250,16 +251,17 @@ EXPORTS.mozilla.layers += [
     'wr/WebRenderLayerManager.h',
     'wr/WebRenderLayersLogging.h',
     'wr/WebRenderMessageUtils.h',
     'wr/WebRenderScrollData.h',
     'wr/WebRenderScrollDataWrapper.h',
     'wr/WebRenderTextureHost.h',
     'wr/WebRenderTextureHostWrapper.h',
     'wr/WebRenderUserData.h',
+    'ZoomConstraints.h',
 ]
 
 if CONFIG['MOZ_X11']:
     EXPORTS.mozilla.layers += [
         'basic/TextureClientX11.h',
         'basic/X11TextureSourceBasic.h',
         'composite/X11TextureHost.h',
         'ipc/ShadowLayerUtilsX11.h',
--- a/gfx/layers/wr/ClipManager.cpp
+++ b/gfx/layers/wr/ClipManager.cpp
@@ -275,31 +275,31 @@ ClipManager::GetScrollLayer(const Active
     }
 
     // If this ASR doesn't have a scroll ID, then we should check its ancestor.
     // There may not be one defined because the ASR may not be scrollable or we
     // failed to get the scroll metadata.
   }
 
   Maybe<wr::WrClipId> scrollId =
-    mBuilder->GetScrollIdForDefinedScrollLayer(FrameMetrics::NULL_SCROLL_ID);
+    mBuilder->GetScrollIdForDefinedScrollLayer(ScrollableLayerGuid::NULL_SCROLL_ID);
   MOZ_ASSERT(scrollId.isSome());
   return scrollId;
 }
 
 Maybe<wr::WrClipId>
 ClipManager::DefineScrollLayers(const ActiveScrolledRoot* aASR,
                                 nsDisplayItem* aItem,
                                 const StackingContextHelper& aSc)
 {
   if (!aASR) {
     // Recursion base case
     return Nothing();
   }
-  FrameMetrics::ViewID viewId = aASR->GetViewId();
+  ScrollableLayerGuid::ViewID viewId = aASR->GetViewId();
   Maybe<wr::WrClipId> scrollId = mBuilder->GetScrollIdForDefinedScrollLayer(viewId);
   if (scrollId) {
     // If we've already defined this scroll layer before, we can early-exit
     return scrollId;
   }
   // Recurse to define the ancestors
   Maybe<wr::WrClipId> ancestorScrollId = DefineScrollLayers(aASR->mParent, aItem, aSc);
 
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -1555,29 +1555,29 @@ WebRenderBridgeParent::RecvGetAnimationV
     AdvanceAnimations();
   }
 
   *aValue = mAnimStorage->GetOMTAValue(aCompositorAnimationsId);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
-WebRenderBridgeParent::RecvSetAsyncScrollOffset(const FrameMetrics::ViewID& aScrollId,
+WebRenderBridgeParent::RecvSetAsyncScrollOffset(const ScrollableLayerGuid::ViewID& aScrollId,
                                                 const float& aX,
                                                 const float& aY)
 {
   if (mDestroyed) {
     return IPC_OK();
   }
   mCompositorBridge->SetTestAsyncScrollOffset(GetLayersId(), aScrollId, CSSPoint(aX, aY));
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
-WebRenderBridgeParent::RecvSetAsyncZoom(const FrameMetrics::ViewID& aScrollId,
+WebRenderBridgeParent::RecvSetAsyncZoom(const ScrollableLayerGuid::ViewID& aScrollId,
                                         const float& aZoom)
 {
   if (mDestroyed) {
     return IPC_OK();
   }
   mCompositorBridge->SetTestAsyncZoom(GetLayersId(), aScrollId, LayerToParentLayerScale(aZoom));
   return IPC_OK();
 }
--- a/gfx/layers/wr/WebRenderBridgeParent.h
+++ b/gfx/layers/wr/WebRenderBridgeParent.h
@@ -125,20 +125,20 @@ public:
 
   mozilla::ipc::IPCResult RecvSetConfirmedTargetAPZC(const uint64_t& aBlockId,
                                                      nsTArray<ScrollableLayerGuid>&& aTargets) override;
 
   mozilla::ipc::IPCResult RecvSetTestSampleTime(const TimeStamp& aTime) override;
   mozilla::ipc::IPCResult RecvLeaveTestMode() override;
   mozilla::ipc::IPCResult RecvGetAnimationValue(const uint64_t& aCompositorAnimationsId,
                                                 OMTAValue* aValue) override;
-  mozilla::ipc::IPCResult RecvSetAsyncScrollOffset(const FrameMetrics::ViewID& aScrollId,
+  mozilla::ipc::IPCResult RecvSetAsyncScrollOffset(const ScrollableLayerGuid::ViewID& aScrollId,
                                                    const float& aX,
                                                    const float& aY) override;
-  mozilla::ipc::IPCResult RecvSetAsyncZoom(const FrameMetrics::ViewID& aScrollId,
+  mozilla::ipc::IPCResult RecvSetAsyncZoom(const ScrollableLayerGuid::ViewID& aScrollId,
                                            const float& aZoom) override;
   mozilla::ipc::IPCResult RecvFlushApzRepaints() override;
   mozilla::ipc::IPCResult RecvGetAPZTestData(APZTestData* data) override;
 
   void ActorDestroy(ActorDestroyReason aWhy) override;
 
   void Pause();
   bool Resume();
--- a/gfx/layers/wr/WebRenderCommandBuilder.cpp
+++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp
@@ -330,26 +330,26 @@ struct DIGroup
   //    and we don't need to heap allocate the BlobItemData's
   nsTHashtable<nsPtrHashKey<BlobItemData>> mDisplayItems;
 
   IntRect mInvalidRect;
   nsRect mGroupBounds;
   LayerIntRect mPaintRect;
   int32_t mAppUnitsPerDevPixel;
   gfx::Size mScale;
-  FrameMetrics::ViewID mScrollId;
+  ScrollableLayerGuid::ViewID mScrollId;
   LayerPoint mResidualOffset;
   LayerIntRect mLayerBounds;
   Maybe<wr::ImageKey> mKey;
   std::vector<RefPtr<SourceSurface>> mExternalSurfaces;
   std::vector<RefPtr<ScaledFont>> mFonts;
 
   DIGroup()
     : mAppUnitsPerDevPixel(0)
-    , mScrollId(FrameMetrics::NULL_SCROLL_ID)
+    , mScrollId(ScrollableLayerGuid::NULL_SCROLL_ID)
   {
   }
 
   void InvalidateRect(const IntRect& aRect)
   {
     // Empty rects get dropped
     mInvalidRect = mInvalidRect.Union(aRect);
   }
@@ -1229,17 +1229,17 @@ WebRenderCommandBuilder::DoGroupingForDi
     if (group.mResidualOffset != residualOffset) {
       GP(" Residual Offset %f %f -> %f %f\n", group.mResidualOffset.x, group.mResidualOffset.y, residualOffset.x, residualOffset.y);
     }
 
     group.ClearItems();
     group.ClearImageKey(mManager);
   }
 
-  FrameMetrics::ViewID scrollId = FrameMetrics::NULL_SCROLL_ID;
+  ScrollableLayerGuid::ViewID scrollId = ScrollableLayerGuid::NULL_SCROLL_ID;
   if (const ActiveScrolledRoot* asr = aWrappingItem->GetActiveScrolledRoot()) {
     scrollId = asr->GetViewId();
   }
 
   g.mAppUnitsPerDevPixel = appUnitsPerDevPixel;
   group.mResidualOffset = residualOffset;
   group.mGroupBounds = groupBounds;
   group.mAppUnitsPerDevPixel = appUnitsPerDevPixel;
@@ -1319,17 +1319,17 @@ WebRenderCommandBuilder::BuildWebRenderC
     }
     CreateWebRenderCommandsFromDisplayList(aDisplayList, nullptr, aDisplayListBuilder,
                                            pageRootSc, aBuilder, aResourceUpdates);
   }
 
   // Make a "root" layer data that has everything else as descendants
   mLayerScrollData.emplace_back();
   mLayerScrollData.back().InitializeRoot(mLayerScrollData.size() - 1);
-  auto callback = [&aScrollData](FrameMetrics::ViewID aScrollId) -> bool {
+  auto callback = [&aScrollData](ScrollableLayerGuid::ViewID aScrollId) -> bool {
     return aScrollData.HasMetadataFor(aScrollId).isSome();
   };
   if (Maybe<ScrollMetadata> rootMetadata = nsLayoutUtils::GetRootMetadata(
         aDisplayListBuilder, mManager, ContainerLayerParameters(), callback)) {
     mLayerScrollData.back().AppendScrollMetadata(aScrollData, rootMetadata.ref());
   }
   // Append the WebRenderLayerScrollData items into WebRenderScrollData
   // in reverse order, from topmost to bottommost. This is in keeping with
--- a/gfx/layers/wr/WebRenderLayerManager.h
+++ b/gfx/layers/wr/WebRenderLayerManager.h
@@ -143,17 +143,17 @@ public:
   // list.
   void AddActiveCompositorAnimationId(uint64_t aId);
   void AddCompositorAnimationsIdForDiscard(uint64_t aId);
   void DiscardCompositorAnimations();
 
   WebRenderBridgeChild* WrBridge() const { return mWrChild; }
 
   // See equivalent function in ClientLayerManager
-  void LogTestDataForCurrentPaint(FrameMetrics::ViewID aScrollId,
+  void LogTestDataForCurrentPaint(ScrollableLayerGuid::ViewID aScrollId,
                                   const std::string& aKey,
                                   const std::string& aValue) {
     MOZ_ASSERT(gfxPrefs::APZTestLoggingEnabled(), "don't call me");
     mApzTestData.LogTestDataForPaint(mPaintSequenceNumber, aScrollId, aKey, aValue);
   }
   // See equivalent function in ClientLayerManager
   const APZTestData& GetAPZTestData() const
   { return mApzTestData; }
--- a/gfx/layers/wr/WebRenderScrollData.cpp
+++ b/gfx/layers/wr/WebRenderScrollData.cpp
@@ -18,17 +18,17 @@
 namespace mozilla {
 namespace layers {
 
 WebRenderLayerScrollData::WebRenderLayerScrollData()
   : mDescendantCount(-1)
   , mTransformIsPerspective(false)
   , mEventRegionsOverride(EventRegionsOverride::NoOverride)
   , mScrollbarAnimationId(0)
-  , mFixedPosScrollContainerId(FrameMetrics::NULL_SCROLL_ID)
+  , mFixedPosScrollContainerId(ScrollableLayerGuid::NULL_SCROLL_ID)
 {
 }
 
 WebRenderLayerScrollData::~WebRenderLayerScrollData()
 {
 }
 
 void
@@ -56,17 +56,17 @@ WebRenderLayerScrollData::Initialize(Web
     // If the item's ASR is an ancestor of the stop-at ASR, then we don't need
     // any more metrics information because we'll end up duplicating what the
     // ancestor WebRenderLayerScrollData already has.
     asr = nullptr;
   }
 
   while (asr && asr != aStopAtAsr) {
     MOZ_ASSERT(aOwner.GetManager());
-    FrameMetrics::ViewID scrollId = asr->GetViewId();
+    ScrollableLayerGuid::ViewID scrollId = asr->GetViewId();
     if (Maybe<size_t> index = aOwner.HasMetadataFor(scrollId)) {
       mScrollIds.AppendElement(index.ref());
     } else {
       Maybe<ScrollMetadata> metadata = asr->mScrollableFrame->ComputeScrollMetadata(
           aOwner.GetManager(), aItem->ReferenceFrame(),
           Nothing(), nullptr);
       asr->mScrollableFrame->NotifyApzTransaction();
       if (metadata) {
@@ -176,17 +176,17 @@ WebRenderLayerManager*
 WebRenderScrollData::GetManager() const
 {
   return mManager;
 }
 
 size_t
 WebRenderScrollData::AddMetadata(const ScrollMetadata& aMetadata)
 {
-  FrameMetrics::ViewID scrollId = aMetadata.GetMetrics().GetScrollId();
+  ScrollableLayerGuid::ViewID scrollId = aMetadata.GetMetrics().GetScrollId();
   auto insertResult = mScrollIdMap.insert(std::make_pair(scrollId, 0));
   if (insertResult.second) {
     // Insertion took place, therefore it's a scrollId we hadn't seen before
     insertResult.first->second = mScrollMetadatas.Length();
     mScrollMetadatas.AppendElement(aMetadata);
   } // else we didn't insert, because it already existed
   return insertResult.first->second;
 }
@@ -216,17 +216,17 @@ WebRenderScrollData::GetLayerData(size_t
 const ScrollMetadata&
 WebRenderScrollData::GetScrollMetadata(size_t aIndex) const
 {
   MOZ_ASSERT(aIndex < mScrollMetadatas.Length());
   return mScrollMetadatas[aIndex];
 }
 
 Maybe<size_t>
-WebRenderScrollData::HasMetadataFor(const FrameMetrics::ViewID& aScrollId) const
+WebRenderScrollData::HasMetadataFor(const ScrollableLayerGuid::ViewID& aScrollId) const
 {
   auto it = mScrollIdMap.find(aScrollId);
   return (it == mScrollIdMap.end() ? Nothing() : Some(it->second));
 }
 
 void
 WebRenderScrollData::SetFocusTarget(const FocusTarget& aFocusTarget)
 {
@@ -279,16 +279,16 @@ WebRenderScrollData::Dump() const
   }
 }
 
 bool
 WebRenderScrollData::RepopulateMap()
 {
   MOZ_ASSERT(mScrollIdMap.empty());
   for (size_t i = 0; i < mScrollMetadatas.Length(); i++) {
-    FrameMetrics::ViewID scrollId = mScrollMetadatas[i].GetMetrics().GetScrollId();
+    ScrollableLayerGuid::ViewID scrollId = mScrollMetadatas[i].GetMetrics().GetScrollId();
     mScrollIdMap.emplace(scrollId, i);
   }
   return true;
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/wr/WebRenderScrollData.h
+++ b/gfx/layers/wr/WebRenderScrollData.h
@@ -79,18 +79,18 @@ public:
   void SetReferentId(LayersId aReferentId) { mReferentId = Some(aReferentId); }
   Maybe<LayersId> GetReferentId() const { return mReferentId; }
 
   void SetScrollbarData(const ScrollbarData& aData) { mScrollbarData = aData; }
   const ScrollbarData& GetScrollbarData() const { return mScrollbarData; }
   void SetScrollbarAnimationId(const uint64_t& aId) { mScrollbarAnimationId = aId; }
   const uint64_t& GetScrollbarAnimationId() const { return mScrollbarAnimationId; }
 
-  void SetFixedPositionScrollContainerId(FrameMetrics::ViewID aId) { mFixedPosScrollContainerId = aId; }
-  FrameMetrics::ViewID GetFixedPositionScrollContainerId() const { return mFixedPosScrollContainerId; }
+  void SetFixedPositionScrollContainerId(ScrollableLayerGuid::ViewID aId) { mFixedPosScrollContainerId = aId; }
+  ScrollableLayerGuid::ViewID GetFixedPositionScrollContainerId() const { return mFixedPosScrollContainerId; }
 
   void Dump(const WebRenderScrollData& aOwner) const;
 
   friend struct IPC::ParamTraits<WebRenderLayerScrollData>;
 
 private:
   // The number of descendants this layer has (not including the layer itself).
   // This is needed to reconstruct the depth-first layer tree traversal
@@ -111,17 +111,17 @@ private:
   gfx::Matrix4x4 mTransform;
   bool mTransformIsPerspective;
   EventRegions mEventRegions;
   LayerIntRegion mVisibleRegion;
   Maybe<LayersId> mReferentId;
   EventRegionsOverride mEventRegionsOverride;
   ScrollbarData mScrollbarData;
   uint64_t mScrollbarAnimationId;
-  FrameMetrics::ViewID mFixedPosScrollContainerId;
+  ScrollableLayerGuid::ViewID mFixedPosScrollContainerId;
 };
 
 // Data needed by APZ, for the whole layer tree. One instance of this class
 // is created for each transaction sent over PWebRenderBridge. It is populated
 // with information from the WebRender layer tree on the client side and the
 // information is used by APZ on the parent side.
 class WebRenderScrollData
 {
@@ -141,17 +141,17 @@ public:
 
   size_t GetLayerCount() const;
 
   // Return a pointer to the scroll data at the given index. Use with caution,
   // as the pointer may be invalidated if this WebRenderScrollData is mutated.
   const WebRenderLayerScrollData* GetLayerData(size_t aIndex) const;
 
   const ScrollMetadata& GetScrollMetadata(size_t aIndex) const;
-  Maybe<size_t> HasMetadataFor(const FrameMetrics::ViewID& aScrollId) const;
+  Maybe<size_t> HasMetadataFor(const ScrollableLayerGuid::ViewID& aScrollId) const;
 
   const FocusTarget& GetFocusTarget() const { return mFocusTarget; }
   void SetFocusTarget(const FocusTarget& aFocusTarget);
 
   void SetIsFirstPaint();
   bool IsFirstPaint() const;
   void SetPaintSequenceNumber(uint32_t aPaintSequenceNumber);
   uint32_t GetPaintSequenceNumber() const;
@@ -175,17 +175,17 @@ private:
   WebRenderLayerManager* MOZ_NON_OWNING_REF mManager;
 
   // Internal data structure used to maintain uniqueness of mScrollMetadatas.
   // This is not serialized/deserialized over IPC, but it is rebuilt on the
   // parent side when mScrollMetadatas is deserialized. So it should always be
   // valid on both the child and parent.
   // The key into this map is the scrollId of a ScrollMetadata, and the value is
   // an index into the mScrollMetadatas array.
-  std::map<FrameMetrics::ViewID, size_t> mScrollIdMap;
+  std::map<ScrollableLayerGuid::ViewID, size_t> mScrollIdMap;
 
   // A list of all the unique ScrollMetadata objects from the layer tree. Each
   // ScrollMetadata in this list must have a unique scroll id.
   nsTArray<ScrollMetadata> mScrollMetadatas;
 
   // A list of per-layer scroll data objects, generated via a depth-first,
   // pre-order, last-to-first traversal of the layer tree (i.e. a recursive
   // traversal where a node N first pushes itself, followed by its children in
--- a/gfx/layers/wr/WebRenderScrollDataWrapper.h
+++ b/gfx/layers/wr/WebRenderScrollDataWrapper.h
@@ -305,17 +305,17 @@ public:
   }
 
   uint64_t GetScrollbarAnimationId() const
   {
     MOZ_ASSERT(IsValid());
     return mLayer->GetScrollbarAnimationId();
   }
 
-  FrameMetrics::ViewID GetFixedPositionScrollContainerId() const
+  ScrollableLayerGuid::ViewID GetFixedPositionScrollContainerId() const
   {
     MOZ_ASSERT(IsValid());
     return mLayer->GetFixedPositionScrollContainerId();
   }
 
   bool IsBackfaceHidden() const
   {
     // This is only used by APZCTM hit testing, and WR does its own
--- a/gfx/tests/gtest/TestLayers.cpp
+++ b/gfx/tests/gtest/TestLayers.cpp
@@ -390,96 +390,96 @@ TEST_F(LayerMetricsWrapperTester, Simple
   wrapper = wrapper.GetParent();
   ASSERT_EQ(layers[1].get(), wrapper.GetLayer());
   ASSERT_TRUE(layer5 == wrapper.GetLastChild());
   LayerMetricsWrapper rootWrapper(root);
   ASSERT_TRUE(rootWrapper == wrapper.GetParent());
 }
 
 static ScrollMetadata
-MakeMetadata(FrameMetrics::ViewID aId) {
+MakeMetadata(ScrollableLayerGuid::ViewID aId) {
   ScrollMetadata metadata;
   metadata.GetMetrics().SetScrollId(aId);
   return metadata;
 }
 
 TEST_F(LayerMetricsWrapperTester, MultiFramemetricsTree) {
   nsTArray<RefPtr<Layer> > layers;
   RefPtr<LayerManager> lm;
   RefPtr<Layer> root = CreateLayerTree("c(c(c(tt)c(t)))", nullptr, nullptr, lm, layers);
 
   nsTArray<ScrollMetadata> metadata;
-  metadata.InsertElementAt(0, MakeMetadata(FrameMetrics::START_SCROLL_ID + 0)); // topmost of root layer
-  metadata.InsertElementAt(0, MakeMetadata(FrameMetrics::NULL_SCROLL_ID));
-  metadata.InsertElementAt(0, MakeMetadata(FrameMetrics::START_SCROLL_ID + 1));
-  metadata.InsertElementAt(0, MakeMetadata(FrameMetrics::START_SCROLL_ID + 2));
-  metadata.InsertElementAt(0, MakeMetadata(FrameMetrics::NULL_SCROLL_ID));
-  metadata.InsertElementAt(0, MakeMetadata(FrameMetrics::NULL_SCROLL_ID));      // bottom of root layer
+  metadata.InsertElementAt(0, MakeMetadata(ScrollableLayerGuid::START_SCROLL_ID + 0)); // topmost of root layer
+  metadata.InsertElementAt(0, MakeMetadata(ScrollableLayerGuid::NULL_SCROLL_ID));
+  metadata.InsertElementAt(0, MakeMetadata(ScrollableLayerGuid::START_SCROLL_ID + 1));
+  metadata.InsertElementAt(0, MakeMetadata(ScrollableLayerGuid::START_SCROLL_ID + 2));
+  metadata.InsertElementAt(0, MakeMetadata(ScrollableLayerGuid::NULL_SCROLL_ID));
+  metadata.InsertElementAt(0, MakeMetadata(ScrollableLayerGuid::NULL_SCROLL_ID));      // bottom of root layer
   root->SetScrollMetadata(metadata);
 
   metadata.Clear();
-  metadata.InsertElementAt(0, MakeMetadata(FrameMetrics::START_SCROLL_ID + 3));
+  metadata.InsertElementAt(0, MakeMetadata(ScrollableLayerGuid::START_SCROLL_ID + 3));
   layers[1]->SetScrollMetadata(metadata);
 
   metadata.Clear();
-  metadata.InsertElementAt(0, MakeMetadata(FrameMetrics::NULL_SCROLL_ID));
-  metadata.InsertElementAt(0, MakeMetadata(FrameMetrics::START_SCROLL_ID + 4));
+  metadata.InsertElementAt(0, MakeMetadata(ScrollableLayerGuid::NULL_SCROLL_ID));
+  metadata.InsertElementAt(0, MakeMetadata(ScrollableLayerGuid::START_SCROLL_ID + 4));
   layers[2]->SetScrollMetadata(metadata);
 
   metadata.Clear();
-  metadata.InsertElementAt(0, MakeMetadata(FrameMetrics::START_SCROLL_ID + 5));
+  metadata.InsertElementAt(0, MakeMetadata(ScrollableLayerGuid::START_SCROLL_ID + 5));
   layers[4]->SetScrollMetadata(metadata);
 
   metadata.Clear();
-  metadata.InsertElementAt(0, MakeMetadata(FrameMetrics::START_SCROLL_ID + 6));
+  metadata.InsertElementAt(0, MakeMetadata(ScrollableLayerGuid::START_SCROLL_ID + 6));
   layers[5]->SetScrollMetadata(metadata);
 
   LayerMetricsWrapper wrapper(root, LayerMetricsWrapper::StartAt::TOP);
   nsTArray<Layer*> expectedLayers;
   expectedLayers.AppendElement(layers[0].get());
   expectedLayers.AppendElement(layers[0].get());
   expectedLayers.AppendElement(layers[0].get());
   expectedLayers.AppendElement(layers[0].get());
   expectedLayers.AppendElement(layers[0].get());
   expectedLayers.AppendElement(layers[0].get());
   expectedLayers.AppendElement(layers[1].get());
   expectedLayers.AppendElement(layers[2].get());
   expectedLayers.AppendElement(layers[2].get());
   expectedLayers.AppendElement(layers[3].get());
-  nsTArray<FrameMetrics::ViewID> expectedIds;
-  expectedIds.AppendElement(FrameMetrics::START_SCROLL_ID + 0);
-  expectedIds.AppendElement(FrameMetrics::NULL_SCROLL_ID);
-  expectedIds.AppendElement(FrameMetrics::START_SCROLL_ID + 1);
-  expectedIds.AppendElement(FrameMetrics::START_SCROLL_ID + 2);
-  expectedIds.AppendElement(FrameMetrics::NULL_SCROLL_ID);
-  expectedIds.AppendElement(FrameMetrics::NULL_SCROLL_ID);
-  expectedIds.AppendElement(FrameMetrics::START_SCROLL_ID + 3);
-  expectedIds.AppendElement(FrameMetrics::NULL_SCROLL_ID);
-  expectedIds.AppendElement(FrameMetrics::START_SCROLL_ID + 4);
-  expectedIds.AppendElement(FrameMetrics::NULL_SCROLL_ID);
+  nsTArray<ScrollableLayerGuid::ViewID> expectedIds;
+  expectedIds.AppendElement(ScrollableLayerGuid::START_SCROLL_ID + 0);
+  expectedIds.AppendElement(ScrollableLayerGuid::NULL_SCROLL_ID);
+  expectedIds.AppendElement(ScrollableLayerGuid::START_SCROLL_ID + 1);
+  expectedIds.AppendElement(ScrollableLayerGuid::START_SCROLL_ID + 2);
+  expectedIds.AppendElement(ScrollableLayerGuid::NULL_SCROLL_ID);
+  expectedIds.AppendElement(ScrollableLayerGuid::NULL_SCROLL_ID);
+  expectedIds.AppendElement(ScrollableLayerGuid::START_SCROLL_ID + 3);
+  expectedIds.AppendElement(ScrollableLayerGuid::NULL_SCROLL_ID);
+  expectedIds.AppendElement(ScrollableLayerGuid::START_SCROLL_ID + 4);
+  expectedIds.AppendElement(ScrollableLayerGuid::NULL_SCROLL_ID);
   for (int i = 0; i < 10; i++) {
     ASSERT_EQ(expectedLayers[i], wrapper.GetLayer());
     ASSERT_EQ(expectedIds[i], wrapper.Metrics().GetScrollId());
     wrapper = wrapper.GetFirstChild();
   }
   ASSERT_FALSE(wrapper.IsValid());
 
   wrapper = LayerMetricsWrapper(root, LayerMetricsWrapper::StartAt::BOTTOM);
   for (int i = 5; i < 10; i++) {
     ASSERT_EQ(expectedLayers[i], wrapper.GetLayer());
     ASSERT_EQ(expectedIds[i], wrapper.Metrics().GetScrollId());
     wrapper = wrapper.GetFirstChild();
   }
   ASSERT_FALSE(wrapper.IsValid());
 
   wrapper = LayerMetricsWrapper(layers[4], LayerMetricsWrapper::StartAt::BOTTOM);
-  ASSERT_EQ(FrameMetrics::START_SCROLL_ID + 5, wrapper.Metrics().GetScrollId());
+  ASSERT_EQ(ScrollableLayerGuid::START_SCROLL_ID + 5, wrapper.Metrics().GetScrollId());
   wrapper = wrapper.GetParent();
-  ASSERT_EQ(FrameMetrics::START_SCROLL_ID + 4, wrapper.Metrics().GetScrollId());
+  ASSERT_EQ(ScrollableLayerGuid::START_SCROLL_ID + 4, wrapper.Metrics().GetScrollId());
   ASSERT_EQ(layers[2].get(), wrapper.GetLayer());
   ASSERT_FALSE(wrapper.GetNextSibling().IsValid());
   wrapper = wrapper.GetParent();
-  ASSERT_EQ(FrameMetrics::NULL_SCROLL_ID, wrapper.Metrics().GetScrollId());
+  ASSERT_EQ(ScrollableLayerGuid::NULL_SCROLL_ID, wrapper.Metrics().GetScrollId());
   ASSERT_EQ(layers[2].get(), wrapper.GetLayer());
   wrapper = wrapper.GetNextSibling();
-  ASSERT_EQ(FrameMetrics::START_SCROLL_ID + 6, wrapper.Metrics().GetScrollId());
+  ASSERT_EQ(ScrollableLayerGuid::START_SCROLL_ID + 6, wrapper.Metrics().GetScrollId());
   ASSERT_EQ(layers[5].get(), wrapper.GetLayer());
 }
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -79,17 +79,16 @@
 #include "gfxFontMissingGlyphs.h"
 
 #include "nsExceptionHandler.h"
 #include "nsUnicodeRange.h"
 #include "nsServiceManagerUtils.h"
 #include "nsTArray.h"
 #include "nsIObserverService.h"
 #include "nsIScreenManager.h"
-#include "FrameMetrics.h"
 #include "MainThreadUtils.h"
 
 #include "nsWeakReference.h"
 
 #include "cairo.h"
 #include "qcms.h"
 
 #include "imgITools.h"
--- a/gfx/webrender_bindings/WebRenderAPI.cpp
+++ b/gfx/webrender_bindings/WebRenderAPI.cpp
@@ -244,17 +244,17 @@ TransactionBuilder::SetWindowParameters(
   wrDocRect.origin.y = aDocumentRect.y;
   wrDocRect.size.width = aDocumentRect.width;
   wrDocRect.size.height = aDocumentRect.height;
   wr_transaction_set_window_parameters(mTxn, &wrWindowSize, &wrDocRect);
 }
 
 void
 TransactionBuilder::UpdateScrollPosition(const wr::WrPipelineId& aPipelineId,
-                                         const layers::FrameMetrics::ViewID& aScrollId,
+                                         const layers::ScrollableLayerGuid::ViewID& aScrollId,
                                          const wr::LayoutPoint& aScrollPosition)
 {
   wr_transaction_scroll_layer(mTxn, aPipelineId, aScrollId, aScrollPosition);
 }
 
 TransactionWrapper::TransactionWrapper(Transaction* aTxn)
   : mTxn(aTxn)
 {
@@ -266,17 +266,17 @@ TransactionWrapper::AppendTransformPrope
   wr_transaction_append_transform_properties(
       mTxn,
       aTransformArray.IsEmpty() ? nullptr : aTransformArray.Elements(),
       aTransformArray.Length());
 }
 
 void
 TransactionWrapper::UpdateScrollPosition(const wr::WrPipelineId& aPipelineId,
-                                         const layers::FrameMetrics::ViewID& aScrollId,
+                                         const layers::ScrollableLayerGuid::ViewID& aScrollId,
                                          const wr::LayoutPoint& aScrollPosition)
 {
   wr_transaction_scroll_layer(mTxn, aPipelineId, aScrollId, aScrollPosition);
 }
 
 void
 TransactionWrapper::UpdatePinchZoom(float aZoom)
 {
@@ -378,17 +378,17 @@ void
 WebRenderAPI::SendTransaction(TransactionBuilder& aTxn)
 {
   wr_api_send_transaction(mDocHandle, aTxn.Raw(), aTxn.UseSceneBuilderThread());
 }
 
 bool
 WebRenderAPI::HitTest(const wr::WorldPoint& aPoint,
                       wr::WrPipelineId& aOutPipelineId,
-                      layers::FrameMetrics::ViewID& aOutScrollId,
+                      layers::ScrollableLayerGuid::ViewID& aOutScrollId,
                       gfx::CompositorHitTestInfo& aOutHitInfo)
 {
   static_assert(DoesCompositorHitTestInfoFitIntoBits<16>(),
                 "CompositorHitTestFlags MAX value has to be less than number of bits in uint16_t");
 
   uint16_t serialized = static_cast<uint16_t>(aOutHitInfo.serialize());
   const bool result = wr_api_hit_test(mDocHandle, aPoint,
     &aOutPipelineId, &aOutScrollId, &serialized);
@@ -955,32 +955,32 @@ DisplayListBuilder::DefineStickyFrame(co
       aLeftMargin ? Stringify(*aLeftMargin).c_str() : "none",
       Stringify(aVerticalBounds).c_str(),
       Stringify(aHorizontalBounds).c_str(),
       Stringify(aAppliedOffset).c_str());
   return wr::WrClipId { id };
 }
 
 Maybe<wr::WrClipId>
-DisplayListBuilder::GetScrollIdForDefinedScrollLayer(layers::FrameMetrics::ViewID aViewId) const
+DisplayListBuilder::GetScrollIdForDefinedScrollLayer(layers::ScrollableLayerGuid::ViewID aViewId) const
 {
-  if (aViewId == layers::FrameMetrics::NULL_SCROLL_ID) {
+  if (aViewId == layers::ScrollableLayerGuid::NULL_SCROLL_ID) {
     return Some(wr::WrClipId::RootScrollNode());
   }
 
   auto it = mScrollIds.find(aViewId);
   if (it == mScrollIds.end()) {
     return Nothing();
   }
 
   return Some(it->second);
 }
 
 wr::WrClipId
-DisplayListBuilder::DefineScrollLayer(const layers::FrameMetrics::ViewID& aViewId,
+DisplayListBuilder::DefineScrollLayer(const layers::ScrollableLayerGuid::ViewID& aViewId,
                                       const Maybe<wr::WrClipId>& aParentId,
                                       const wr::LayoutRect& aContentRect,
                                       const wr::LayoutRect& aClipRect)
 {
   auto it = mScrollIds.find(aViewId);
   if (it != mScrollIds.end()) {
     return it->second;
   }
@@ -1332,26 +1332,26 @@ DisplayListBuilder::PushBoxShadow(const 
                                   const wr::BoxShadowClipMode& aClipMode)
 {
   wr_dp_push_box_shadow(mWrState, aRect, MergeClipLeaf(aClip),
                         aIsBackfaceVisible, aBoxBounds, aOffset, aColor,
                         aBlurRadius, aSpreadRadius, aBorderRadius,
                         aClipMode);
 }
 
-Maybe<layers::FrameMetrics::ViewID>
+Maybe<layers::ScrollableLayerGuid::ViewID>
 DisplayListBuilder::GetContainingFixedPosScrollTarget(const ActiveScrolledRoot* aAsr)
 {
   return mActiveFixedPosTracker
       ? mActiveFixedPosTracker->GetScrollTargetForASR(aAsr)
       : Nothing();
 }
 
 void
-DisplayListBuilder::SetHitTestInfo(const layers::FrameMetrics::ViewID& aScrollId,
+DisplayListBuilder::SetHitTestInfo(const layers::ScrollableLayerGuid::ViewID& aScrollId,
                                    gfx::CompositorHitTestInfo aHitInfo)
 {
   static_assert(DoesCompositorHitTestInfoFitIntoBits<16>(),
                 "CompositorHitTestFlags MAX value has to be less than number of bits in uint16_t");
 
   wr_set_item_tag(mWrState, aScrollId, static_cast<uint16_t>(aHitInfo.serialize()));
 }
 
@@ -1359,31 +1359,31 @@ void
 DisplayListBuilder::ClearHitTestInfo()
 {
   wr_clear_item_tag(mWrState);
 }
 
 DisplayListBuilder::FixedPosScrollTargetTracker::FixedPosScrollTargetTracker(
     DisplayListBuilder& aBuilder,
     const ActiveScrolledRoot* aAsr,
-    layers::FrameMetrics::ViewID aScrollId)
+    layers::ScrollableLayerGuid::ViewID aScrollId)
   : mParentTracker(aBuilder.mActiveFixedPosTracker)
   , mBuilder(aBuilder)
   , mAsr(aAsr)
   , mScrollId(aScrollId)
 {
   aBuilder.mActiveFixedPosTracker = this;
 }
 
 DisplayListBuilder::FixedPosScrollTargetTracker::~FixedPosScrollTargetTracker()
 {
   mBuilder.mActiveFixedPosTracker = mParentTracker;
 }
 
-Maybe<layers::FrameMetrics::ViewID>
+Maybe<layers::ScrollableLayerGuid::ViewID>
 DisplayListBuilder::FixedPosScrollTargetTracker::GetScrollTargetForASR(const ActiveScrolledRoot* aAsr)
 {
   return aAsr == mAsr ? Some(mScrollId) : Nothing();
 }
 
 } // namespace wr
 } // namespace mozilla
 
--- a/gfx/webrender_bindings/WebRenderAPI.h
+++ b/gfx/webrender_bindings/WebRenderAPI.h
@@ -8,21 +8,21 @@
 #define MOZILLA_LAYERS_WEBRENDERAPI_H
 
 #include <vector>
 #include <unordered_map>
 #include <unordered_set>
 
 #include "mozilla/AlreadyAddRefed.h"
 #include "mozilla/gfx/CompositorHitTestInfo.h"
+#include "mozilla/layers/ScrollableLayerGuid.h"
 #include "mozilla/layers/SyncObject.h"
 #include "mozilla/Range.h"
 #include "mozilla/webrender/webrender_ffi.h"
 #include "mozilla/webrender/WebRenderTypes.h"
-#include "FrameMetrics.h"
 #include "GLTypes.h"
 #include "Units.h"
 
 namespace mozilla {
 
 struct ActiveScrolledRoot;
 
 namespace widget {
@@ -93,17 +93,17 @@ public:
 
   void UpdateDynamicProperties(const nsTArray<wr::WrOpacityProperty>& aOpacityArray,
                                const nsTArray<wr::WrTransformProperty>& aTransformArray);
 
   void SetWindowParameters(const LayoutDeviceIntSize& aWindowSize,
                            const LayoutDeviceIntRect& aDocRect);
 
   void UpdateScrollPosition(const wr::WrPipelineId& aPipelineId,
-                            const layers::FrameMetrics::ViewID& aScrollId,
+                            const layers::ScrollableLayerGuid::ViewID& aScrollId,
                             const wr::LayoutPoint& aScrollPosition);
 
   bool IsEmpty() const;
 
   void AddImage(wr::ImageKey aKey,
                 const ImageDescriptor& aDescriptor,
                 wr::Vec<uint8_t>& aBytes);
 
@@ -175,17 +175,17 @@ protected:
 
 class TransactionWrapper
 {
 public:
   explicit TransactionWrapper(Transaction* aTxn);
 
   void AppendTransformProperties(const nsTArray<wr::WrTransformProperty>& aTransformArray);
   void UpdateScrollPosition(const wr::WrPipelineId& aPipelineId,
-                            const layers::FrameMetrics::ViewID& aScrollId,
+                            const layers::ScrollableLayerGuid::ViewID& aScrollId,
                             const wr::LayoutPoint& aScrollPosition);
   void UpdatePinchZoom(float aZoom);
 private:
   Transaction* mTxn;
 };
 
 class WebRenderAPI
 {
@@ -201,17 +201,17 @@ public:
   already_AddRefed<WebRenderAPI> CreateDocument(LayoutDeviceIntSize aSize, int8_t aLayerIndex);
 
   already_AddRefed<WebRenderAPI> Clone();
 
   wr::WindowId GetId() const { return mId; }
 
   bool HitTest(const wr::WorldPoint& aPoint,
                wr::WrPipelineId& aOutPipelineId,
-               layers::FrameMetrics::ViewID& aOutScrollId,
+               layers::ScrollableLayerGuid::ViewID& aOutScrollId,
                gfx::CompositorHitTestInfo& aOutHitInfo);
 
   void SendTransaction(TransactionBuilder& aTxn);
 
   void SetFrameStartTime(const TimeStamp& aTime);
 
   void RunOnRenderThread(UniquePtr<RendererEvent> aEvent);
 
@@ -344,18 +344,18 @@ public:
                                  const float* aTopMargin,
                                  const float* aRightMargin,
                                  const float* aBottomMargin,
                                  const float* aLeftMargin,
                                  const StickyOffsetBounds& aVerticalBounds,
                                  const StickyOffsetBounds& aHorizontalBounds,
                                  const wr::LayoutVector2D& aAppliedOffset);
 
-  Maybe<wr::WrClipId> GetScrollIdForDefinedScrollLayer(layers::FrameMetrics::ViewID aViewId) const;
-  wr::WrClipId DefineScrollLayer(const layers::FrameMetrics::ViewID& aViewId,
+  Maybe<wr::WrClipId> GetScrollIdForDefinedScrollLayer(layers::ScrollableLayerGuid::ViewID aViewId) const;
+  wr::WrClipId DefineScrollLayer(const layers::ScrollableLayerGuid::ViewID& aViewId,
                                  const Maybe<wr::WrClipId>& aParentId,
                                  const wr::LayoutRect& aContentRect, // TODO: We should work with strongly typed rects
                                  const wr::LayoutRect& aClipRect);
 
   void PushClipAndScrollInfo(const wr::WrClipId* aScrollId,
                              const wr::WrClipChainId* aClipChainId,
                              const Maybe<wr::LayoutRect>& aClipChainLeaf);
   void PopClipAndScrollInfo(const wr::WrClipId* aScrollId);
@@ -512,61 +512,61 @@ public:
                      const float& aBlurRadius,
                      const float& aSpreadRadius,
                      const wr::BorderRadius& aBorderRadius,
                      const wr::BoxShadowClipMode& aClipMode);
 
   // Checks to see if the innermost enclosing fixed pos item has the same
   // ASR. If so, it returns the scroll target for that fixed-pos item.
   // Otherwise, it returns Nothing().
-  Maybe<layers::FrameMetrics::ViewID> GetContainingFixedPosScrollTarget(const ActiveScrolledRoot* aAsr);
+  Maybe<layers::ScrollableLayerGuid::ViewID> GetContainingFixedPosScrollTarget(const ActiveScrolledRoot* aAsr);
 
   // Set the hit-test info to be used for all display items until the next call
   // to SetHitTestInfo or ClearHitTestInfo.
-  void SetHitTestInfo(const layers::FrameMetrics::ViewID& aScrollId,
+  void SetHitTestInfo(const layers::ScrollableLayerGuid::ViewID& aScrollId,
                       gfx::CompositorHitTestInfo aHitInfo);
   // Clears the hit-test info so that subsequent display items will not have it.
   void ClearHitTestInfo();
 
   // Try to avoid using this when possible.
   wr::WrState* Raw() { return mWrState; }
 
   // A chain of RAII objects, each holding a (ASR, ViewID) tuple of data. The
   // topmost object is pointed to by the mActiveFixedPosTracker pointer in
   // the wr::DisplayListBuilder.
   class MOZ_RAII FixedPosScrollTargetTracker {
   public:
     FixedPosScrollTargetTracker(DisplayListBuilder& aBuilder,
                                 const ActiveScrolledRoot* aAsr,
-                                layers::FrameMetrics::ViewID aScrollId);
+                                layers::ScrollableLayerGuid::ViewID aScrollId);
     ~FixedPosScrollTargetTracker();
-    Maybe<layers::FrameMetrics::ViewID> GetScrollTargetForASR(const ActiveScrolledRoot* aAsr);
+    Maybe<layers::ScrollableLayerGuid::ViewID> GetScrollTargetForASR(const ActiveScrolledRoot* aAsr);
 
   private:
     FixedPosScrollTargetTracker* mParentTracker;
     DisplayListBuilder& mBuilder;
     const ActiveScrolledRoot* mAsr;
-    layers::FrameMetrics::ViewID mScrollId;
+    layers::ScrollableLayerGuid::ViewID mScrollId;
   };
 
 protected:
   wr::LayoutRect MergeClipLeaf(const wr::LayoutRect& aClip)
   {
     if (mClipChainLeaf) {
       return wr::IntersectLayoutRect(*mClipChainLeaf, aClip);
     }
     return aClip;
   }
 
   wr::WrState* mWrState;
 
   // Track each scroll id that we encountered. We use this structure to
   // ensure that we don't define a particular scroll layer multiple times,
   // as that results in undefined behaviour in WR.
-  std::unordered_map<layers::FrameMetrics::ViewID, wr::WrClipId> mScrollIds;
+  std::unordered_map<layers::ScrollableLayerGuid::ViewID, wr::WrClipId> mScrollIds;
 
   // Contains the current leaf of the clip chain to be merged with the
   // display item's clip rect when pushing an item. May be set to Nothing() if
   // there is no clip rect to merge with.
   Maybe<wr::LayoutRect> mClipChainLeaf;
 
   FixedPosScrollTargetTracker* mActiveFixedPosTracker;
 
--- a/gfx/webrender_bindings/WebRenderTypes.h
+++ b/gfx/webrender_bindings/WebRenderTypes.h
@@ -2,24 +2,24 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GFX_WEBRENDERTYPES_H
 #define GFX_WEBRENDERTYPES_H
 
-#include "FrameMetrics.h"
 #include "ImageTypes.h"
 #include "mozilla/webrender/webrender_ffi.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/gfx/Matrix.h"
 #include "mozilla/gfx/Types.h"
 #include "mozilla/gfx/Tools.h"
 #include "mozilla/gfx/Rect.h"
+#include "mozilla/layers/LayersTypes.h"
 #include "mozilla/PodOperations.h"
 #include "mozilla/Range.h"
 #include "mozilla/Variant.h"
 #include "Units.h"
 #include "nsStyleConsts.h"
 
 namespace mozilla {
 
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -204,17 +204,17 @@ using namespace mozilla::tasktracer;
 using namespace mozilla;
 using namespace mozilla::css;
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
 using namespace mozilla::layers;
 using namespace mozilla::gfx;
 using namespace mozilla::layout;
 using PaintFrameFlags = nsLayoutUtils::PaintFrameFlags;
-typedef FrameMetrics::ViewID ViewID;
+typedef ScrollableLayerGuid::ViewID ViewID;
 
 CapturingContentInfo nsIPresShell::gCaptureInfo =
   { false /* mAllowed */, false /* mPointerLock */, false /* mRetargetToElement */,
     false /* mPreventDrag */ };
 nsIContent* nsIPresShell::gKeyDownTarget;
 
 // RangePaintInfo is used to paint ranges to offscreen buffers
 struct RangePaintInfo {
--- a/layout/base/ZoomConstraintsClient.cpp
+++ b/layout/base/ZoomConstraintsClient.cpp
@@ -2,20 +2,21 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ZoomConstraintsClient.h"
 
 #include <inttypes.h>
-#include "FrameMetrics.h"
 #include "gfxPrefs.h"
 #include "LayersLogging.h"
 #include "mozilla/layers/APZCCallbackHelper.h"
+#include "mozilla/layers/ScrollableLayerGuid.h"
+#include "mozilla/layers/ZoomConstraints.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/PresShell.h"
 #include "mozilla/dom/Event.h"
 #include "nsDocument.h"
 #include "nsIFrame.h"
 #include "nsLayoutUtils.h"
 #include "nsPoint.h"
 #include "nsView.h"
@@ -196,17 +197,17 @@ void
 ZoomConstraintsClient::RefreshZoomConstraints()
 {
   nsIWidget* widget = GetWidget(mPresShell);
   if (!widget) {
     return;
   }
 
   uint32_t presShellId = 0;
-  FrameMetrics::ViewID viewId = FrameMetrics::NULL_SCROLL_ID;
+  ScrollableLayerGuid::ViewID viewId = ScrollableLayerGuid::NULL_SCROLL_ID;
   bool scrollIdentifiersValid = APZCCallbackHelper::GetOrCreateScrollIdentifiers(
         mDocument->GetDocumentElement(),
         &presShellId, &viewId);
   if (!scrollIdentifiersValid) {
     return;
   }
 
   LayoutDeviceIntSize screenSize;
--- a/layout/base/ZoomConstraintsClient.h
+++ b/layout/base/ZoomConstraintsClient.h
@@ -2,17 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef ZoomConstraintsClient_h_
 #define ZoomConstraintsClient_h_
 
-#include "FrameMetrics.h"
+#include "mozilla/layers/ScrollableLayerGuid.h"
 #include "mozilla/Maybe.h"
 #include "nsIDOMEventListener.h"
 #include "nsIObserver.h"
 
 class nsIDocument;
 class nsIPresShell;
 
 namespace mozilla {
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -171,17 +171,17 @@ using mozilla::dom::HTMLMediaElement_Bin
 // idle time and the next Tick.
 #define DEFAULT_IDLE_PERIOD_TIME_LIMIT 1.0f
 
 #ifdef DEBUG
 // TODO: remove, see bug 598468.
 bool nsLayoutUtils::gPreventAssertInCompareTreePosition = false;
 #endif // DEBUG
 
-typedef FrameMetrics::ViewID ViewID;
+typedef ScrollableLayerGuid::ViewID ViewID;
 typedef nsStyleTransformMatrix::TransformReferenceBox TransformReferenceBox;
 
 /* static */ uint32_t nsLayoutUtils::sFontSizeInflationEmPerLine;
 /* static */ uint32_t nsLayoutUtils::sFontSizeInflationMinTwips;
 /* static */ uint32_t nsLayoutUtils::sFontSizeInflationLineThreshold;
 /* static */ int32_t  nsLayoutUtils::sFontSizeInflationMappingIntercept;
 /* static */ uint32_t nsLayoutUtils::sFontSizeInflationMaxRatio;
 /* static */ bool nsLayoutUtils::sFontSizeInflationForceEnabled;
@@ -190,17 +190,17 @@ typedef nsStyleTransformMatrix::Transfor
 /* static */ uint32_t nsLayoutUtils::sZoomMaxPercent;
 /* static */ uint32_t nsLayoutUtils::sZoomMinPercent;
 /* static */ bool nsLayoutUtils::sInvalidationDebuggingIsEnabled;
 /* static */ bool nsLayoutUtils::sInterruptibleReflowEnabled;
 /* static */ bool nsLayoutUtils::sSVGTransformBoxEnabled;
 /* static */ uint32_t nsLayoutUtils::sIdlePeriodDeadlineLimit;
 /* static */ uint32_t nsLayoutUtils::sQuiescentFramesBeforeIdlePeriod;
 
-static ViewID sScrollIdCounter = FrameMetrics::START_SCROLL_ID;
+static ViewID sScrollIdCounter = ScrollableLayerGuid::START_SCROLL_ID;
 
 typedef nsDataHashtable<nsUint64HashKey, nsIContent*> ContentMap;
 static ContentMap* sContentMap = nullptr;
 static ContentMap& GetContentMap() {
   if (!sContentMap) {
     sContentMap = new ContentMap();
   }
   return *sContentMap;
@@ -611,17 +611,17 @@ nsLayoutUtils::FindOrCreateIDFor(nsICont
   }
 
   return scrollId;
 }
 
 nsIContent*
 nsLayoutUtils::FindContentFor(ViewID aId)
 {
-  MOZ_ASSERT(aId != FrameMetrics::NULL_SCROLL_ID,
+  MOZ_ASSERT(aId != ScrollableLayerGuid::NULL_SCROLL_ID,
              "Cannot find a content element in map for null IDs.");
   nsIContent* content;
   bool exists = GetContentMap().Get(aId, &content);
 
   if (exists) {
     return content;
   } else {
     return nullptr;
@@ -658,29 +658,29 @@ nsLayoutUtils::FindScrollableFrameFor(Vi
   nsIFrame* scrollFrame = GetScrollFrameFromContent(content);
   return scrollFrame ? scrollFrame->GetScrollTargetFrame() : nullptr;
 }
 
 ViewID
 nsLayoutUtils::FindIDForScrollableFrame(nsIScrollableFrame* aScrollable)
 {
   if (!aScrollable) {
-    return FrameMetrics::NULL_SCROLL_ID;
+    return ScrollableLayerGuid::NULL_SCROLL_ID;
   }
 
   nsIFrame* scrollFrame = do_QueryFrame(aScrollable);
   nsIContent* scrollContent = scrollFrame->GetContent();
 
-  FrameMetrics::ViewID scrollId;
+  ScrollableLayerGuid::ViewID scrollId;
   if (scrollContent &&
       nsLayoutUtils::FindIDFor(scrollContent, &scrollId)) {
     return scrollId;
   }
 
-  return FrameMetrics::NULL_SCROLL_ID;
+  return ScrollableLayerGuid::NULL_SCROLL_ID;
 }
 
 static nsRect
 ApplyRectMultiplier(nsRect aRect, float aMultiplier)
 {
   if (aMultiplier == 1.0f) {
     return aRect;
   }
@@ -1904,20 +1904,20 @@ nsLayoutUtils::SetFixedPositionLayerData
       sides |= eSideBitsTop;
     }
   }
 
   ViewID id = ScrollIdForRootScrollFrame(aPresContext);
   aLayer->SetFixedPositionData(id, anchor, sides);
 }
 
-FrameMetrics::ViewID
+ScrollableLayerGuid::ViewID
 nsLayoutUtils::ScrollIdForRootScrollFrame(nsPresContext* aPresContext)
 {
-  ViewID id = FrameMetrics::NULL_SCROLL_ID;
+  ViewID id = ScrollableLayerGuid::NULL_SCROLL_ID;
   if (nsIFrame* rootScrollFrame = aPresContext->PresShell()->GetRootScrollFrame()) {
     if (nsIContent* content = rootScrollFrame->GetContent()) {
       id = FindOrCreateIDFor(content);
     }
   }
   return id;
 }
 
@@ -3751,17 +3751,17 @@ nsLayoutUtils::PaintFrame(gfxContext* aR
     TimeStamp dlStart = TimeStamp::Now();
 
     {
       // If a scrollable container layer is created in nsDisplayList::PaintForFrame,
       // it will be the scroll parent for display items that are built in the
       // BuildDisplayListForStackingContext call below. We need to set the scroll
       // parent on the display list builder while we build those items, so that they
       // can pick up their scroll parent's id.
-      ViewID id = FrameMetrics::NULL_SCROLL_ID;
+      ViewID id = ScrollableLayerGuid::NULL_SCROLL_ID;
       if (ignoreViewportScrolling && presContext->IsRootContentDocument()) {
         if (nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame()) {
           if (nsIContent* content = rootScrollFrame->GetContent()) {
             id = nsLayoutUtils::FindOrCreateIDFor(content);
           }
         }
       }
       else if (presShell->GetDocument() && presShell->GetDocument()->IsRootDisplayDocument()
@@ -9259,17 +9259,17 @@ nsLayoutUtils::ComputeScrollMetadata(nsI
   nsPresContext* presContext = aForFrame->PresContext();
   int32_t auPerDevPixel = presContext->AppUnitsPerDevPixel();
 
   nsIPresShell* presShell = presContext->GetPresShell();
   ScrollMetadata metadata;
   FrameMetrics& metrics = metadata.GetMetrics();
   metrics.SetViewport(CSSRect::FromAppUnits(aViewport));
 
-  ViewID scrollId = FrameMetrics::NULL_SCROLL_ID;
+  ViewID scrollId = ScrollableLayerGuid::NULL_SCROLL_ID;
   if (aContent) {
     if (void* paintRequestTime = aContent->GetProperty(nsGkAtoms::paintRequestTime)) {
       metrics.SetPaintRequestTime(*static_cast<TimeStamp*>(paintRequestTime));
       aContent->DeleteProperty(nsGkAtoms::paintRequestTime);
     }
     scrollId = nsLayoutUtils::FindOrCreateIDFor(aContent);
     nsRect dp;
     if (nsLayoutUtils::GetDisplayPort(aContent, &dp)) {
@@ -9361,26 +9361,26 @@ nsLayoutUtils::ComputeScrollMetadata(nsI
     metadata.SetOverscrollBehavior(OverscrollBehaviorInfo::FromStyleConstants(
         scrollStyles.mOverscrollBehaviorX,
         scrollStyles.mOverscrollBehaviorY));
   }
 
   // If we have the scrollparent being the same as the scroll id, the
   // compositor-side code could get into an infinite loop while building the
   // overscroll handoff chain.
-  MOZ_ASSERT(aScrollParentId == FrameMetrics::NULL_SCROLL_ID || scrollId != aScrollParentId);
+  MOZ_ASSERT(aScrollParentId == ScrollableLayerGuid::NULL_SCROLL_ID || scrollId != aScrollParentId);
   metrics.SetScrollId(scrollId);
   metrics.SetIsRootContent(aIsRootContent);
   metadata.SetScrollParentId(aScrollParentId);
 
   nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
   bool isRootScrollFrame = aScrollFrame == rootScrollFrame;
   nsIDocument* document = presShell->GetDocument();
 
-  if (scrollId != FrameMetrics::NULL_SCROLL_ID && !presContext->GetParentPresContext()) {
+  if (scrollId != ScrollableLayerGuid::NULL_SCROLL_ID && !presContext->GetParentPresContext()) {
     if ((aScrollFrame && isRootScrollFrame)) {
       metadata.SetIsLayersIdRoot(true);
     } else {
       MOZ_ASSERT(document, "A non-root-scroll frame must be in a document");
       if (aContent == document->GetDocumentElement()) {
         metadata.SetIsLayersIdRoot(true);
       }
     }
@@ -9591,17 +9591,17 @@ nsLayoutUtils::GetRootMetadata(nsDisplay
 
   if (addMetrics || ensureMetricsForRootId) {
     bool isRootContent = presContext->IsRootContentDocument();
 
     nsRect viewport(aBuilder->ToReferenceFrame(frame), frame->GetSize());
     return Some(nsLayoutUtils::ComputeScrollMetadata(frame,
                            rootScrollFrame, content,
                            aBuilder->FindReferenceFrameFor(frame),
-                           aLayerManager, FrameMetrics::NULL_SCROLL_ID, viewport, Nothing(),
+                           aLayerManager, ScrollableLayerGuid::NULL_SCROLL_ID, viewport, Nothing(),
                            isRootContent, Some(aContainerParameters)));
   }
 
   return Nothing();
 }
 
 /* static */ bool
 nsLayoutUtils::ContainsMetricsWithId(const Layer* aLayer, const ViewID& aScrollId)
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -12,19 +12,19 @@
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/TypedEnumBits.h"
 #include "nsBoundingMetrics.h"
 #include "nsChangeHint.h"
 #include "nsFrameList.h"
 #include "mozilla/layout/FrameChildList.h"
+#include "mozilla/layers/ScrollableLayerGuid.h"
 #include "nsThreadUtils.h"
 #include "nsIPrincipal.h"
-#include "FrameMetrics.h"
 #include "nsIWidget.h"
 #include "nsCSSPropertyID.h"
 #include "nsStyleCoord.h"
 #include "nsStyleConsts.h"
 #include "nsGkAtoms.h"
 #include "imgIContainer.h"
 #include "mozilla/gfx/2D.h"
 #include "Units.h"
@@ -87,16 +87,18 @@ class InspectorFontFace;
 class OffscreenCanvas;
 class Selection;
 } // namespace dom
 namespace gfx {
 struct RectCornerRadii;
 enum class ShapedTextFlags : uint16_t;
 } // namespace gfx
 namespace layers {
+struct FrameMetrics;
+struct ScrollMetadata;
 class Image;
 class StackingContextHelper;
 class Layer;
 } // namespace layers
 } // namespace mozilla
 
 namespace mozilla {
 
@@ -172,17 +174,17 @@ class nsLayoutUtils
   typedef mozilla::gfx::Matrix4x4Flagged Matrix4x4Flagged;
   typedef mozilla::gfx::RectCornerRadii RectCornerRadii;
   typedef mozilla::gfx::StrokeOptions StrokeOptions;
   typedef mozilla::image::ImgDrawResult ImgDrawResult;
 
 public:
   typedef mozilla::layers::FrameMetrics FrameMetrics;
   typedef mozilla::layers::ScrollMetadata ScrollMetadata;
-  typedef FrameMetrics::ViewID ViewID;
+  typedef mozilla::layers::ScrollableLayerGuid::ViewID ViewID;
   typedef mozilla::CSSPoint CSSPoint;
   typedef mozilla::CSSSize CSSSize;
   typedef mozilla::CSSIntSize CSSIntSize;
   typedef mozilla::CSSRect CSSRect;
   typedef mozilla::ScreenMargin ScreenMargin;
   typedef mozilla::LayoutDeviceIntSize LayoutDeviceIntSize;
   typedef mozilla::LayoutDeviceRect LayoutDeviceRect;
   typedef mozilla::StyleGeometryBox StyleGeometryBox;
@@ -587,17 +589,17 @@ public:
                                         const nsIFrame* aFixedPosFrame,
                                         nsPresContext* aPresContext,
                                         const ContainerLayerParameters& aContainerParameters);
 
   /**
    * Get the scroll id for the root scrollframe of the presshell of the given
    * prescontext. Returns NULL_SCROLL_ID if it couldn't be found.
    */
-  static FrameMetrics::ViewID ScrollIdForRootScrollFrame(nsPresContext* aPresContext);
+  static ViewID ScrollIdForRootScrollFrame(nsPresContext* aPresContext);
 
   /**
    * Return true if aPresContext's viewport has a displayport.
    */
   static bool ViewportHasDisplayPort(nsPresContext* aPresContext);
 
   /**
    * Return true if aFrame is a fixed-pos frame and is a child of a viewport
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -11484,17 +11484,17 @@ nsIFrame::GetCompositorHitTestInfo(nsDis
       }
     }
   }
 
   const Maybe<ScrollDirection> scrollDirection = aBuilder->GetCurrentScrollbarDirection();
   if (scrollDirection.isSome()) {
     if (GetContent()->IsXULElement(nsGkAtoms::thumb)) {
       const bool thumbGetsLayer = aBuilder->GetCurrentScrollbarTarget() !=
-          layers::FrameMetrics::NULL_SCROLL_ID;
+          layers::ScrollableLayerGuid::NULL_SCROLL_ID;
       if (thumbGetsLayer) {
         result += CompositorHitTestFlags::eScrollbarThumb;
       } else {
         result += CompositorHitTestFlags::eDispatchToContent;
       }
     }
 
     if (*scrollDirection == ScrollDirection::eVertical) {
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -2122,17 +2122,17 @@ ScrollFrameHelper::ScrollFrameHelper(nsC
   , mDestination(0, 0)
   , mRestorePos(-1, -1)
   , mLastPos(-1, -1)
   , mApzScrollPos(0, 0)
   , mScrollPosForLayerPixelAlignment(-1, -1)
   , mLastUpdateFramesPos(-1, -1)
   , mHadDisplayPortAtLastFrameUpdate(false)
   , mDisplayPortAtLastFrameUpdate()
-  , mScrollParentID(mozilla::layers::FrameMetrics::NULL_SCROLL_ID)
+  , mScrollParentID(mozilla::layers::ScrollableLayerGuid::NULL_SCROLL_ID)
   , mNeverHasVerticalScrollbar(false)
   , mNeverHasHorizontalScrollbar(false)
   , mHasVerticalScrollbar(false)
   , mHasHorizontalScrollbar(false)
   , mFrameIsUpdatingScrollbar(false)
   , mDidHistoryRestore(false)
   , mIsRoot(aIsRoot)
   , mClipAllDescendants(aIsRoot)
@@ -3009,17 +3009,17 @@ ScrollFrameHelper::ScrollToImpl(nsPoint 
       if (!apzDisabled && !HasPluginFrames()) {
         if (LastScrollOrigin() == nsGkAtoms::apz) {
           schedulePaint = false;
           PAINT_SKIP_LOG("Skipping due to APZ scroll\n");
         } else if (mScrollableByAPZ) {
           nsIWidget* widget = presContext->GetNearestWidget();
           LayerManager* manager = widget ? widget->GetLayerManager() : nullptr;
           if (manager) {
-            mozilla::layers::FrameMetrics::ViewID id;
+            mozilla::layers::ScrollableLayerGuid::ViewID id;
             bool success = nsLayoutUtils::FindIDFor(content, &id);
             MOZ_ASSERT(success); // we have a displayport, we better have an ID
 
             // Schedule an empty transaction to carry over the scroll offset update,
             // instead of a full transaction. This empty transaction might still get
             // squashed into a full transaction if something happens to trigger one.
             success = manager->SetPendingScrollUpdateForNextTransaction(id,
                 {
@@ -3210,19 +3210,19 @@ ScrollFrameHelper::AppendScrollPartsTo(n
   }
   if (scrollParts.IsEmpty()) {
     return;
   }
 
   // We can't check will-change budget during display list building phase.
   // This means that we will build scroll bar layers for out of budget
   // will-change: scroll position.
-  const mozilla::layers::FrameMetrics::ViewID scrollTargetId = IsMaybeScrollingActive()
+  const mozilla::layers::ScrollableLayerGuid::ViewID scrollTargetId = IsMaybeScrollingActive()
     ? nsLayoutUtils::FindOrCreateIDFor(mScrolledFrame->GetContent())
-    : mozilla::layers::FrameMetrics::NULL_SCROLL_ID;
+    : mozilla::layers::ScrollableLayerGuid::NULL_SCROLL_ID;
 
   scrollParts.Sort(HoveredStateComparator());
 
   DisplayListClipState::AutoSaveRestore clipState(aBuilder);
   // Don't let scrollparts extent outside our frame's border-box, if these are
   // viewport scrollbars. They would create layerization problems. This wouldn't
   // normally be an issue but themes can add overflow areas to scrollbar parts.
   if (mIsRoot) {
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -43,16 +43,17 @@ class ScrollbarActivity;
 } // namespace layout
 
 class ScrollFrameHelper : public nsIReflowCallback {
 public:
   typedef nsIFrame::Sides Sides;
   typedef mozilla::CSSIntPoint CSSIntPoint;
   typedef mozilla::layout::ScrollbarActivity ScrollbarActivity;
   typedef mozilla::layers::FrameMetrics FrameMetrics;
+  typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid;
   typedef mozilla::layers::ScrollSnapInfo ScrollSnapInfo;
   typedef mozilla::layers::Layer Layer;
   typedef mozilla::layers::LayerManager LayerManager;
 
   class AsyncScroll;
   class AsyncSmoothMSDScroll;
 
   ScrollFrameHelper(nsContainerFrame* aOuter, bool aIsRoot);
@@ -568,17 +569,17 @@ public:
 
   // The scroll position where we last updated frame visibility.
   nsPoint mLastUpdateFramesPos;
   bool mHadDisplayPortAtLastFrameUpdate;
   nsRect mDisplayPortAtLastFrameUpdate;
 
   nsRect mPrevScrolledRect;
 
-  FrameMetrics::ViewID mScrollParentID;
+  ScrollableLayerGuid::ViewID mScrollParentID;
 
   // Timer to remove the displayport some time after scrolling has stopped
   nsCOMPtr<nsITimer> mDisplayPortExpiryTimer;
 
   bool mNeverHasVerticalScrollbar:1;
   bool mNeverHasHorizontalScrollbar:1;
   bool mHasVerticalScrollbar:1;
   bool mHasHorizontalScrollbar:1;
--- a/layout/generic/nsIScrollableFrame.h
+++ b/layout/generic/nsIScrollableFrame.h
@@ -30,31 +30,31 @@ class nsIFrame;
 class nsPresContext;
 class nsIContent;
 class nsAtom;
 class nsDisplayListBuilder;
 
 namespace mozilla {
 struct ContainerLayerParameters;
 namespace layers {
+struct ScrollMetadata;
 class Layer;
 class LayerManager;
 } // namespace layers
 } // namespace mozilla
 
 /**
  * Interface for frames that are scrollable. This interface exposes
  * APIs for examining scroll state, observing changes to scroll state,
  * and triggering scrolling.
  */
 class nsIScrollableFrame : public nsIScrollbarMediator {
 public:
   typedef mozilla::CSSIntPoint CSSIntPoint;
   typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
-  typedef mozilla::layers::FrameMetrics FrameMetrics;
   typedef mozilla::layers::ScrollSnapInfo ScrollSnapInfo;
 
   NS_DECL_QUERYFRAME_TARGET(nsIScrollableFrame)
 
   /**
    * Get the frame for the content that we are scrolling within
    * this scrollable frame.
    */
--- a/layout/ipc/RenderFrameParent.cpp
+++ b/layout/ipc/RenderFrameParent.cpp
@@ -37,17 +37,17 @@
 
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
 using namespace mozilla::layers;
 
 namespace mozilla {
 namespace layout {
 
-typedef FrameMetrics::ViewID ViewID;
+typedef ScrollableLayerGuid::ViewID ViewID;
 
 /**
  * Gets the layer-pixel offset of aContainerFrame's content rect top-left
  * from the nearest display item reference frame (which we assume will be inducing
  * a ContainerLayer).
  */
 static LayoutDeviceIntPoint
 GetContentRectLayerOffset(nsIFrame* aContainerFrame, nsDisplayListBuilder* aBuilder)
--- a/layout/ipc/RenderFrameParent.h
+++ b/layout/ipc/RenderFrameParent.h
@@ -43,17 +43,17 @@ class RenderFrameParent final : public P
   typedef mozilla::layers::LayerManager LayerManager;
   typedef mozilla::layers::LayersId LayersId;
   typedef mozilla::layers::TargetConfig TargetConfig;
   typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
   typedef mozilla::layers::TextureFactoryIdentifier TextureFactoryIdentifier;
   typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid;
   typedef mozilla::layers::TouchBehaviorFlags TouchBehaviorFlags;
   typedef mozilla::layers::ZoomConstraints ZoomConstraints;
-  typedef FrameMetrics::ViewID ViewID;
+  typedef ScrollableLayerGuid::ViewID ViewID;
 
 public:
 
 
   /**
    * Select the desired scrolling behavior.  If ASYNC_PAN_ZOOM is
    * chosen, then RenderFrameParent will watch input events and use
    * them to asynchronously pan and zoom.
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -101,17 +101,17 @@
 #endif
 
 using namespace mozilla;
 using namespace mozilla::layers;
 using namespace mozilla::dom;
 using namespace mozilla::layout;
 using namespace mozilla::gfx;
 
-typedef FrameMetrics::ViewID ViewID;
+typedef ScrollableLayerGuid::ViewID ViewID;
 typedef nsStyleTransformMatrix::TransformReferenceBox TransformReferenceBox;
 
 #ifdef DEBUG
 static bool
 SpammyLayoutWarningsEnabled()
 {
   static bool sValue = false;
   static bool sValueInitialized = false;
@@ -1025,18 +1025,18 @@ nsDisplayListBuilder::nsDisplayListBuild
   , mCurrentAGR(mRootAGR)
   , mUsedAGRBudget(0)
   , mDirtyRect(-1, -1, -1, -1)
   , mGlassDisplayItem(nullptr)
   , mScrollInfoItemsForHoisting(nullptr)
   , mFirstClipChainToDestroy(nullptr)
   , mActiveScrolledRootForRootScrollframe(nullptr)
   , mMode(aMode)
-  , mCurrentScrollParentId(FrameMetrics::NULL_SCROLL_ID)
-  , mCurrentScrollbarTarget(FrameMetrics::NULL_SCROLL_ID)
+  , mCurrentScrollParentId(ScrollableLayerGuid::NULL_SCROLL_ID)
+  , mCurrentScrollbarTarget(ScrollableLayerGuid::NULL_SCROLL_ID)
   , mSVGEffectsBuildingDepth(0)
   , mFilterASR(nullptr)
   , mContainsBlendMode(false)
   , mIsBuildingScrollbar(false)
   , mCurrentScrollbarWillHaveLayer(false)
   , mBuildCaret(aBuildCaret)
   , mRetainingDisplayList(aRetainingDisplayList)
   , mPartialUpdate(false)
@@ -2603,17 +2603,17 @@ nsDisplayList::BuildLayers(nsDisplayList
       return nullptr;
     }
     // Root is being scaled up by the X/Y resolution. Scale it back down.
     root->SetPostScale(1.0f / containerParameters.mXScale,
                        1.0f / containerParameters.mYScale);
     root->SetScaleToResolution(presShell->ScaleToResolution(),
                                containerParameters.mXScale);
 
-    auto callback = [root](FrameMetrics::ViewID aScrollId) -> bool {
+    auto callback = [root](ScrollableLayerGuid::ViewID aScrollId) -> bool {
       return nsLayoutUtils::ContainsMetricsWithId(root, aScrollId);
     };
     if (Maybe<ScrollMetadata> rootMetadata = nsLayoutUtils::GetRootMetadata(
           aBuilder, root->Manager(), containerParameters, callback)) {
       root->SetScrollMetadata(rootMetadata.value());
     }
 
       // NS_WARNING is debug-only, so don't even bother checking the conditions
@@ -5347,28 +5347,28 @@ nsDisplayCompositorHitTestInfo::CreateWe
     return true;
   }
 
   // XXX: eventually this scrollId computation and the SetHitTestInfo
   // call will get moved out into the WR display item iteration code so that
   // we don't need to do it as often, and so that we can do it for other
   // display item types as well (reducing the need for as many instances of
   // this display item).
-  FrameMetrics::ViewID scrollId =
-    mScrollTarget.valueOrFrom([&]() -> FrameMetrics::ViewID {
+  ScrollableLayerGuid::ViewID scrollId =
+    mScrollTarget.valueOrFrom([&]() -> ScrollableLayerGuid::ViewID {
       const ActiveScrolledRoot* asr = GetActiveScrolledRoot();
-      Maybe<FrameMetrics::ViewID> fixedTarget =
+      Maybe<ScrollableLayerGuid::ViewID> fixedTarget =
         aBuilder.GetContainingFixedPosScrollTarget(asr);
       if (fixedTarget) {
         return *fixedTarget;
       }
       if (asr) {
         return asr->GetViewId();
       }
-      return FrameMetrics::NULL_SCROLL_ID;
+      return ScrollableLayerGuid::NULL_SCROLL_ID;
     });
 
   // Insert a transparent rectangle with the hit-test info
   aBuilder.SetHitTestInfo(scrollId, HitTestFlags());
 
   const LayoutDeviceRect devRect =
     LayoutDeviceRect::FromAppUnits(HitTestArea(), mAppUnitsPerDevPixel);
 
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -37,16 +37,17 @@
 #include "ImgDrawResult.h"
 #include "mozilla/EffectCompositor.h"
 #include "mozilla/EnumeratedArray.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/gfx/UserData.h"
 #include "mozilla/layers/LayerAttributes.h"
+#include "mozilla/layers/ScrollableLayerGuid.h"
 #include "nsCSSRenderingBorders.h"
 #include "nsPresArena.h"
 #include "nsAutoLayoutPhase.h"
 #include "nsDisplayItemTypes.h"
 #include "RetainedDisplayListHelpers.h"
 
 #include <stdint.h>
 #include "nsTHashtable.h"
@@ -65,16 +66,17 @@ class nsDisplayCompositorHitTestInfo;
 class nsDisplayScrollInfoLayer;
 class nsCaret;
 enum class nsDisplayOwnLayerFlags;
 
 namespace mozilla {
 class FrameLayerBuilder;
 struct MotionPathData;
 namespace layers {
+struct FrameMetrics;
 class Layer;
 class ImageLayer;
 class ImageContainer;
 class StackingContextHelper;
 class WebRenderCommand;
 class WebRenderScrollData;
 class WebRenderLayerScrollData;
 } // namespace layers
@@ -320,17 +322,17 @@ struct ActiveScrolledRoot
 
   // Call this when inserting an ancestor.
   void IncrementDepth() { mDepth++; }
 
   /**
    * Find the view ID (or generate a new one) for the content element
    * corresponding to the ASR.
    */
-  mozilla::layers::FrameMetrics::ViewID GetViewId() const
+  mozilla::layers::ScrollableLayerGuid::ViewID GetViewId() const
   {
     if (!mViewId.isSome()) {
       nsIContent* content = mScrollableFrame->GetScrolledFrame()->GetContent();
       mViewId = Some(nsLayoutUtils::FindOrCreateIDFor(content));
     }
     return *mViewId;
   }
 
@@ -368,17 +370,17 @@ private:
   static uint32_t Depth(const ActiveScrolledRoot* aActiveScrolledRoot)
   {
     return aActiveScrolledRoot ? aActiveScrolledRoot->mDepth : 0;
   }
 
   // This field is lazily populated in GetViewId(). We don't want to do the
   // work of populating if webrender is disabled, because it is often not
   // needed.
-  mutable Maybe<mozilla::layers::FrameMetrics::ViewID> mViewId;
+  mutable Maybe<mozilla::layers::ScrollableLayerGuid::ViewID> mViewId;
 
   uint32_t mDepth;
   bool mRetained;
 };
 }
 
 enum class nsDisplayListBuilderMode : uint8_t
 {
@@ -468,17 +470,18 @@ public:
   typedef mozilla::DisplayItemClipChain DisplayItemClipChain;
   typedef mozilla::DisplayItemClipChainHasher DisplayItemClipChainHasher;
   typedef mozilla::DisplayItemClipChainEqualer DisplayItemClipChainEqualer;
   typedef mozilla::DisplayListClipState DisplayListClipState;
   typedef mozilla::ActiveScrolledRoot ActiveScrolledRoot;
   typedef nsIWidget::ThemeGeometry ThemeGeometry;
   typedef mozilla::layers::Layer Layer;
   typedef mozilla::layers::FrameMetrics FrameMetrics;
-  typedef mozilla::layers::FrameMetrics::ViewID ViewID;
+  typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid;
+  typedef mozilla::layers::ScrollableLayerGuid::ViewID ViewID;
   typedef mozilla::gfx::CompositorHitTestInfo CompositorHitTestInfo;
   typedef mozilla::gfx::Matrix4x4 Matrix4x4;
   typedef mozilla::Maybe<mozilla::layers::ScrollDirection> MaybeScrollDirection;
 
   /**
    * @param aReferenceFrame the frame at the root of the subtree; its origin
    * is the origin of the reference coordinate system for this display list
    * @param aMode encodes what the builder is being used for.
@@ -1489,17 +1492,17 @@ public:
       aBuilder->mCurrentScrollbarDirection = aScrollbarDirection;
       aBuilder->mCurrentScrollbarWillHaveLayer = aWillHaveLayer;
     }
 
     ~AutoCurrentScrollbarInfoSetter()
     {
       // No need to restore old values because scrollbars cannot be nested.
       mBuilder->mIsBuildingScrollbar = false;
-      mBuilder->mCurrentScrollbarTarget = FrameMetrics::NULL_SCROLL_ID;
+      mBuilder->mCurrentScrollbarTarget = ScrollableLayerGuid::NULL_SCROLL_ID;
       mBuilder->mCurrentScrollbarDirection.reset();
       mBuilder->mCurrentScrollbarWillHaveLayer = false;
     }
 
   private:
     nsDisplayListBuilder* mBuilder;
   };
 
@@ -2242,17 +2245,17 @@ class nsDisplayItem : public nsDisplayIt
 {
 public:
   typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
   typedef mozilla::DisplayItemClip DisplayItemClip;
   typedef mozilla::DisplayItemClipChain DisplayItemClipChain;
   typedef mozilla::ActiveScrolledRoot ActiveScrolledRoot;
   typedef mozilla::layers::FrameMetrics FrameMetrics;
   typedef mozilla::layers::ScrollMetadata ScrollMetadata;
-  typedef mozilla::layers::FrameMetrics::ViewID ViewID;
+  typedef mozilla::layers::ScrollableLayerGuid::ViewID ViewID;
   typedef mozilla::layers::Layer Layer;
   typedef mozilla::layers::LayerManager LayerManager;
   typedef mozilla::layers::StackingContextHelper StackingContextHelper;
   typedef mozilla::layers::WebRenderCommand WebRenderCommand;
   typedef mozilla::layers::WebRenderParentCommand WebRenderParentCommand;
   typedef mozilla::LayerState LayerState;
   typedef mozilla::image::imgDrawingParams imgDrawingParams;
   typedef mozilla::image::ImgDrawResult ImgDrawResult;
@@ -5420,17 +5423,17 @@ public:
 
   nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override
   {
     *aSnap = false;
     return nsRect();
   }
 
 private:
-  mozilla::Maybe<mozilla::layers::FrameMetrics::ViewID> mScrollTarget;
+  mozilla::Maybe<mozilla::layers::ScrollableLayerGuid::ViewID> mScrollTarget;
   uint32_t mIndex;
   mozilla::Maybe<int32_t> mOverrideZIndex;
   int32_t mAppUnitsPerDevPixel;
 };
 
 /**
  * A class that lets you wrap a display list as a display item.
  *
--- a/layout/xul/nsSliderFrame.cpp
+++ b/layout/xul/nsSliderFrame.cpp
@@ -314,19 +314,19 @@ nsSliderFrame::BuildDisplayListForChildr
 
     // If this scrollbar is the scrollbar of an actively scrolled scroll frame,
     // layerize the scrollbar thumb, wrap it in its own ContainerLayer and
     // attach scrolling information to it.
     // We do this here and not in the thumb's nsBoxFrame::BuildDisplayList so
     // that the event region that gets created for the thumb is included in
     // the nsDisplayOwnLayer contents.
 
-    const mozilla::layers::FrameMetrics::ViewID scrollTargetId =
+    const mozilla::layers::ScrollableLayerGuid::ViewID scrollTargetId =
       aBuilder->GetCurrentScrollbarTarget();
-    const bool thumbGetsLayer = (scrollTargetId != layers::FrameMetrics::NULL_SCROLL_ID);
+    const bool thumbGetsLayer = (scrollTargetId != layers::ScrollableLayerGuid::NULL_SCROLL_ID);
 
     if (thumbGetsLayer) {
       const Maybe<ScrollDirection> scrollDirection = aBuilder->GetCurrentScrollbarDirection();
       MOZ_ASSERT(scrollDirection.isSome());
       const bool isHorizontal = *scrollDirection == ScrollDirection::eHorizontal;
       const float appUnitsPerCss = float(AppUnitsPerCSSPixel());
       const CSSCoord thumbLength = NSAppUnitsToFloatPixels(
           isHorizontal ? thumbRect.width : thumbRect.height, appUnitsPerCss);
@@ -1036,19 +1036,19 @@ nsSliderFrame::StartAPZDrag(WidgetGUIEve
 
   // Custom scrollbar mediators are not supported in the APZ codepath.
   if (UsesCustomScrollbarMediator(scrollbarBox)) {
     return;
   }
 
   bool isHorizontal = IsXULHorizontal();
 
-  mozilla::layers::FrameMetrics::ViewID scrollTargetId;
+  mozilla::layers::ScrollableLayerGuid::ViewID scrollTargetId;
   bool hasID = nsLayoutUtils::FindIDFor(scrollableContent, &scrollTargetId);
-  bool hasAPZView = hasID && (scrollTargetId != layers::FrameMetrics::NULL_SCROLL_ID);
+  bool hasAPZView = hasID && (scrollTargetId != layers::ScrollableLayerGuid::NULL_SCROLL_ID);
 
   if (!hasAPZView) {
     return;
   }
 
   if (!nsLayoutUtils::HasDisplayPort(scrollableContent)) {
     return;
   }
--- a/widget/PuppetWidget.cpp
+++ b/widget/PuppetWidget.cpp
@@ -575,17 +575,17 @@ PuppetWidget::SetConfirmedTargetAPZC(
 {
   if (mTabChild) {
     mTabChild->SetTargetAPZC(aInputBlockId, aTargets);
   }
 }
 
 void
 PuppetWidget::UpdateZoomConstraints(const uint32_t& aPresShellId,
-                                    const FrameMetrics::ViewID& aViewId,
+                                    const ScrollableLayerGuid::ViewID& aViewId,
                                     const Maybe<ZoomConstraints>& aConstraints)
 {
   if (mTabChild) {
     mTabChild->DoUpdateZoomConstraints(aPresShellId, aViewId, aConstraints);
   }
 }
 
 bool
@@ -1421,17 +1421,17 @@ PuppetWidget::EnableIMEForPlugin(bool aE
 
   // We don't have valid state in cache or state is plugin, so delegate to
   // chrome process.
   mTabChild->SendEnableIMEForPlugin(aEnable);
 }
 
 void
 PuppetWidget::ZoomToRect(const uint32_t& aPresShellId,
-                         const FrameMetrics::ViewID& aViewId,
+                         const ScrollableLayerGuid::ViewID& aViewId,
                          const CSSRect& aRect,
                          const uint32_t& aFlags)
 {
   if (!mTabChild) {
     return;
   }
 
   mTabChild->ZoomToRect(aPresShellId, aViewId, aRect, aFlags);
--- a/widget/PuppetWidget.h
+++ b/widget/PuppetWidget.h
@@ -149,17 +149,17 @@ public:
                  LayoutDeviceIntPoint* aPoint = nullptr);
 
   virtual nsresult DispatchEvent(WidgetGUIEvent* aEvent,
                                  nsEventStatus& aStatus) override;
   nsEventStatus DispatchInputEvent(WidgetInputEvent* aEvent) override;
   void SetConfirmedTargetAPZC(uint64_t aInputBlockId,
                               const nsTArray<ScrollableLayerGuid>& aTargets) const override;
   void UpdateZoomConstraints(const uint32_t& aPresShellId,
-                             const FrameMetrics::ViewID& aViewId,
+                             const ScrollableLayerGuid::ViewID& aViewId,
                              const mozilla::Maybe<ZoomConstraints>& aConstraints) override;
   bool AsyncPanZoomEnabled() const override;
 
   virtual void GetEditCommands(
                  NativeKeyBindingsType aType,
                  const mozilla::WidgetKeyboardEvent& aEvent,
                  nsTArray<mozilla::CommandInt>& aCommands) override;
 
@@ -287,17 +287,17 @@ public:
 
   virtual void StartAsyncScrollbarDrag(const AsyncDragMetrics& aDragMetrics) override;
 
   virtual void SetCandidateWindowForPlugin(
                  const CandidateWindowPosition& aPosition) override;
   virtual void EnableIMEForPlugin(bool aEnable) override;
 
   virtual void ZoomToRect(const uint32_t& aPresShellId,
-                          const FrameMetrics::ViewID& aViewId,
+                          const ScrollableLayerGuid::ViewID& aViewId,
                           const CSSRect& aRect,
                           const uint32_t& aFlags) override;
 
   virtual bool HasPendingInputEvent() override;
 
   void HandledWindowedPluginKeyEvent(const NativeEventData& aKeyEventData,
                                      bool aIsConsumed);
 
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -2355,17 +2355,17 @@ nsWindow::CreateRootContentController()
 uint32_t
 nsWindow::GetMaxTouchPoints() const
 {
     return GeckoAppShell::GetMaxTouchPoints();
 }
 
 void
 nsWindow::UpdateZoomConstraints(const uint32_t& aPresShellId,
-                                const FrameMetrics::ViewID& aViewId,
+                                const ScrollableLayerGuid::ViewID& aViewId,
                                 const mozilla::Maybe<ZoomConstraints>& aConstraints)
 {
     nsBaseWidget::UpdateZoomConstraints(aPresShellId, aViewId, aConstraints);
 }
 
 CompositorBridgeChild*
 nsWindow::GetCompositorBridgeChild() const
 {
--- a/widget/android/nsWindow.h
+++ b/widget/android/nsWindow.h
@@ -285,17 +285,17 @@ public:
 
     virtual bool NeedsPaint() override;
 
     virtual bool WidgetPaintsBackground() override;
 
     virtual uint32_t GetMaxTouchPoints() const override;
 
     void UpdateZoomConstraints(const uint32_t& aPresShellId,
-                               const FrameMetrics::ViewID& aViewId,
+                               const ScrollableLayerGuid::ViewID& aViewId,
                                const mozilla::Maybe<ZoomConstraints>& aConstraints) override;
 
     nsresult SynthesizeNativeTouchPoint(uint32_t aPointerId,
                                         TouchPointerState aPointerState,
                                         LayoutDeviceIntPoint aPoint,
                                         double aPointerPressure,
                                         uint32_t aPointerOrientation,
                                         nsIObserver* aObserver) override;
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -1029,17 +1029,17 @@ nsBaseWidget::SetConfirmedTargetAPZC(uin
       mAPZC,
       &IAPZCTreeManager::SetTargetAPZC,
       aInputBlockId,
       aTargets));
 }
 
 void
 nsBaseWidget::UpdateZoomConstraints(const uint32_t& aPresShellId,
-                                    const FrameMetrics::ViewID& aViewId,
+                                    const ScrollableLayerGuid::ViewID& aViewId,
                                     const Maybe<ZoomConstraints>& aConstraints)
 {
   if (!mCompositorSession || !mAPZC) {
     if (mInitialZoomConstraints) {
       MOZ_ASSERT(mInitialZoomConstraints->mPresShellID == aPresShellId);
       MOZ_ASSERT(mInitialZoomConstraints->mViewID == aViewId);
       if (!aConstraints) {
         mInitialZoomConstraints.reset();
@@ -1985,17 +1985,17 @@ nsBaseWidget::GetNativeTextEventDispatch
   // TODO: If all platforms supported use of TextEventDispatcher for handling
   //       native IME and keyboard events, this method should be removed since
   //       in such case, this is overridden by all the subclasses.
   return nullptr;
 }
 
 void
 nsBaseWidget::ZoomToRect(const uint32_t& aPresShellId,
-                         const FrameMetrics::ViewID& aViewId,
+                         const ScrollableLayerGuid::ViewID& aViewId,
                          const CSSRect& aRect,
                          const uint32_t& aFlags)
 {
   if (!mCompositorSession || !mAPZC) {
     return;
   }
   LayersId layerId = mCompositorSession->RootLayerTreeId();
   APZThreadUtils::RunOnControllerThread(
--- a/widget/nsBaseWidget.h
+++ b/widget/nsBaseWidget.h
@@ -301,28 +301,28 @@ public:
   virtual void               SetAttachedWidgetListener(nsIWidgetListener* aListener) override;
   virtual nsIWidgetListener* GetPreviouslyAttachedWidgetListener() override;
   virtual void               SetPreviouslyAttachedWidgetListener(nsIWidgetListener* aListener) override;
   virtual NativeIMEContext GetNativeIMEContext() override;
   TextEventDispatcher* GetTextEventDispatcher() final;
   virtual TextEventDispatcherListener*
     GetNativeTextEventDispatcherListener() override;
   virtual void ZoomToRect(const uint32_t& aPresShellId,
-                          const FrameMetrics::ViewID& aViewId,
+                          const ScrollableLayerGuid::ViewID& aViewId,
                           const CSSRect& aRect,
                           const uint32_t& aFlags) override;
   // Dispatch an event that must be first be routed through APZ.
   nsEventStatus DispatchInputEvent(mozilla::WidgetInputEvent* aEvent) override;
   void DispatchEventToAPZOnly(mozilla::WidgetInputEvent* aEvent) override;
 
   void SetConfirmedTargetAPZC(uint64_t aInputBlockId,
                               const nsTArray<ScrollableLayerGuid>& aTargets) const override;
 
   void UpdateZoomConstraints(const uint32_t& aPresShellId,
-                             const FrameMetrics::ViewID& aViewId,
+                             const ScrollableLayerGuid::ViewID& aViewId,
                              const mozilla::Maybe<ZoomConstraints>& aConstraints) override;
 
   bool AsyncPanZoomEnabled() const override;
 
   typedef void (nsIPresShell::*NotificationFunc)(void);
   void NotifyPresShell(NotificationFunc aNotificationFunc);
 
   void NotifyWindowDestroyed();
@@ -710,24 +710,24 @@ protected:
   bool              mUpdateCursor;
   bool              mUseAttachedEvents;
   bool              mIMEHasFocus;
   bool              mIsFullyOccluded;
   static nsIRollupListener* gRollupListener;
 
   struct InitialZoomConstraints {
     InitialZoomConstraints(const uint32_t& aPresShellID,
-                           const FrameMetrics::ViewID& aViewID,
+                           const ScrollableLayerGuid::ViewID& aViewID,
                            const ZoomConstraints& aConstraints)
       : mPresShellID(aPresShellID), mViewID(aViewID), mConstraints(aConstraints)
     {
     }
 
     uint32_t mPresShellID;
-    FrameMetrics::ViewID mViewID;
+    ScrollableLayerGuid::ViewID mViewID;
     ZoomConstraints mConstraints;
   };
 
   mozilla::Maybe<InitialZoomConstraints> mInitialZoomConstraints;
 
   // This points to the resize listeners who have been notified that a live
   // resize is in progress. This should always be empty when a live-resize is
   // not in progress.
--- a/widget/nsIWidget.h
+++ b/widget/nsIWidget.h
@@ -18,24 +18,25 @@
 #include "nsITheme.h"
 #include "nsITimer.h"
 #include "nsRegionFwd.h"
 #include "nsStyleConsts.h"
 #include "nsXULAppAPI.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/EventForwards.h"
 #include "mozilla/layers/LayersTypes.h"
+#include "mozilla/layers/ScrollableLayerGuid.h"
+#include "mozilla/layers/ZoomConstraints.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/gfx/Point.h"
 #include "mozilla/widget/IMEData.h"
 #include "nsDataHashtable.h"
 #include "nsIObserver.h"
 #include "nsIWidgetListener.h"
-#include "FrameMetrics.h"
 #include "Units.h"
 
 // forward declarations
 class   nsIBidiKeyboard;
 class   nsIRollupListener;
 class   imgIContainer;
 class   nsIContent;
 class   ViewWrapper;
@@ -54,21 +55,21 @@ class TabChild;
 } // namespace dom
 namespace plugins {
 class PluginWidgetChild;
 } // namespace plugins
 namespace layers {
 class AsyncDragMetrics;
 class Compositor;
 class CompositorBridgeChild;
+struct FrameMetrics;
 class LayerManager;
 class LayerManagerComposite;
 class PLayerTransactionChild;
 class WebRenderBridgeChild;
-struct ScrollableLayerGuid;
 } // namespace layers
 namespace gfx {
 class DrawTarget;
 class SourceSurface;
 } // namespace gfx
 namespace widget {
 class TextEventDispatcher;
 class TextEventDispatcherListener;
@@ -2054,17 +2055,17 @@ public:
     /**
      * Some platforms (only cocoa right now) round widget coordinates to the
      * nearest even pixels (see bug 892994), this function allows us to
      * determine how widget coordinates will be rounded.
      */
     virtual int32_t RoundsWidgetCoordinatesTo() { return 1; }
 
     virtual void UpdateZoomConstraints(const uint32_t& aPresShellId,
-                                       const FrameMetrics::ViewID& aViewId,
+                                       const ScrollableLayerGuid::ViewID& aViewId,
                                        const mozilla::Maybe<ZoomConstraints>& aConstraints) {};
 
     /**
      * GetTextEventDispatcher() returns TextEventDispatcher belonging to the
      * widget.  Note that this never returns nullptr.
      */
     virtual TextEventDispatcher* GetTextEventDispatcher() = 0;
 
@@ -2072,17 +2073,17 @@ public:
      * GetNativeTextEventDispatcherListener() returns a
      * TextEventDispatcherListener instance which is used when the widget
      * instance handles native IME and/or keyboard events.
      */
     virtual TextEventDispatcherListener*
       GetNativeTextEventDispatcherListener() = 0;
 
     virtual void ZoomToRect(const uint32_t& aPresShellId,
-                            const FrameMetrics::ViewID& aViewId,
+                            const ScrollableLayerGuid::ViewID& aViewId,
                             const CSSRect& aRect,
                             const uint32_t& aFlags) = 0;
 
     /**
      * OnWindowedPluginKeyEvent() is called when native key event is
      * received in the focused plugin process directly in PluginInstanceChild.
      *
      * @param aKeyEventData     The native key event data.  The actual type