Bug 1420512 - Try unifying data structures for scrollbar container and scrollbar thumb info. r=botond
authorDaniel Zielas <zielas.daniel@gmail.com>
Fri, 02 Mar 2018 19:00:03 +0100
changeset 412524 a2866a322bbb526bd1f9f69d352e5389dce849b5
parent 412523 09c9390d42d6bc95ffd2e3a3933053d718a1ebe3
child 412525 a2385811ffdc30f153b8d5853f198c89020bf5ce
push id33806
push userncsoregi@mozilla.com
push dateTue, 10 Apr 2018 09:57:15 +0000
treeherdermozilla-central@a8061a09cd70 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond
bugs1420512
milestone61.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 1420512 - Try unifying data structures for scrollbar container and scrollbar thumb info. r=botond MozReview-Commit-ID: 9zPkrA3CwsN
gfx/layers/LayerAttributes.h
gfx/layers/LayerMetricsWrapper.h
gfx/layers/Layers.cpp
gfx/layers/Layers.h
gfx/layers/apz/public/APZSampler.h
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/src/APZCTreeManager.h
gfx/layers/apz/src/APZSampler.cpp
gfx/layers/apz/src/AsyncPanZoomController.cpp
gfx/layers/apz/src/AsyncPanZoomController.h
gfx/layers/apz/src/HitTestingTreeNode.cpp
gfx/layers/apz/src/HitTestingTreeNode.h
gfx/layers/composite/AsyncCompositionManager.cpp
gfx/layers/composite/ContainerLayerComposite.h
gfx/layers/wr/WebRenderScrollData.h
gfx/layers/wr/WebRenderScrollDataWrapper.h
layout/generic/nsFrame.cpp
layout/painting/nsDisplayList.cpp
layout/painting/nsDisplayList.h
layout/xul/nsBoxFrame.cpp
layout/xul/nsSliderFrame.cpp
--- a/gfx/layers/LayerAttributes.h
+++ b/gfx/layers/LayerAttributes.h
@@ -1,202 +1,241 @@
 /* -*- 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 mozilla_gfx_layers_LayerAttributes_h
 #define mozilla_gfx_layers_LayerAttributes_h
 
 #include "mozilla/Maybe.h"
 #include "mozilla/gfx/Types.h"
 #include "mozilla/layers/LayersTypes.h"
 
 namespace IPC {
 template <typename T> struct ParamTraits;
 } // namespace IPC
 
 namespace mozilla {
 namespace layers {
 
-// Data stored for scroll thumb container layers.
-struct ScrollThumbData {
-  ScrollThumbData()
-    : mThumbRatio(0.0f)
-    , mIsAsyncDraggable(false)
-  {}
-  ScrollThumbData(ScrollDirection aDirection,
-                  float aThumbRatio,
-                  CSSCoord aThumbStart,
-                  CSSCoord aThumbLength,
-                  bool aIsAsyncDraggable,
-                  CSSCoord aScrollTrackStart,
-                  CSSCoord aScrollTrackLength)
+enum class ScrollbarLayerType : uint8_t { None, Thumb, Container };
+
+/**
+ *  It stores data for scroll thumb layer or container layers.
+ */
+struct ScrollbarData {
+  ScrollbarData() = default;
+
+  ScrollbarData(ScrollDirection aDirection,
+                ScrollbarLayerType aScrollbarLayerType,
+                float aThumbRatio,
+                CSSCoord aThumbStart,
+                CSSCoord aThumbLength,
+                bool aThumbIsAsyncDraggable,
+                CSSCoord aScrollTrackStart,
+                CSSCoord aScrollTrackLength)
     : mDirection(Some(aDirection))
+    , mScrollbarLayerType(aScrollbarLayerType)
     , mThumbRatio(aThumbRatio)
     , mThumbStart(aThumbStart)
     , mThumbLength(aThumbLength)
-    , mIsAsyncDraggable(aIsAsyncDraggable)
+    , mThumbIsAsyncDraggable(aThumbIsAsyncDraggable)
     , mScrollTrackStart(aScrollTrackStart)
     , mScrollTrackLength(aScrollTrackLength)
   {}
 
+  /**
+   * The mDirection contains a direction if mScrollbarLayerType is Thumb
+   * or Container, otherwise it's empty.
+   */
   Maybe<ScrollDirection> mDirection;
-  // The scrollbar thumb ratio is the ratio of the thumb position (in the CSS
-  // pixels of the scrollframe's parent's space) to the scroll position (in the
-  // CSS pixels of the scrollframe's space).
-  float mThumbRatio;
+
+  /**
+   * Indicate what kind of layer this data is for. All possibilities are defined in
+   * enum ScrollbarLayerType
+   */
+  ScrollbarLayerType mScrollbarLayerType = ScrollbarLayerType::None;
+
+  /**
+   * The scrollbar thumb ratio is the ratio of the thumb position (in the CSS
+   * pixels of the scrollframe's parent's space) to the scroll position (in the
+   * CSS pixels of the scrollframe's space).
+   */
+  float mThumbRatio = 0.0f;
+
   CSSCoord mThumbStart;
   CSSCoord mThumbLength;
-  // Whether the scrollbar thumb can be dragged asynchronously.
-  bool mIsAsyncDraggable;
+
+  /**
+   * Whether the scrollbar thumb can be dragged asynchronously.
+   */
+  bool mThumbIsAsyncDraggable = false;
+
   CSSCoord mScrollTrackStart;
   CSSCoord mScrollTrackLength;
+  uint64_t mTargetViewId = FrameMetrics::NULL_SCROLL_ID;
 
-  bool operator==(const ScrollThumbData& aOther) const {
+  bool operator==(const ScrollbarData& aOther) const {
     return mDirection == aOther.mDirection &&
+           mScrollbarLayerType == aOther.mScrollbarLayerType &&
            mThumbRatio == aOther.mThumbRatio &&
            mThumbStart == aOther.mThumbStart &&
            mThumbLength == aOther.mThumbLength &&
-           mIsAsyncDraggable == aOther.mIsAsyncDraggable &&
+           mThumbIsAsyncDraggable == aOther.mThumbIsAsyncDraggable &&
            mScrollTrackStart == aOther.mScrollTrackStart &&
-           mScrollTrackLength == aOther.mScrollTrackLength;
+           mScrollTrackLength == aOther.mScrollTrackLength &&
+           mTargetViewId == aOther.mTargetViewId;
   }
-  bool operator!=(const ScrollThumbData& aOther) const {
+  bool operator!=(const ScrollbarData& aOther) const {
     return !(*this == aOther);
   }
 };
 
-// Infrequently changing layer attributes that require no special
-// serialization work.
+/**
+ * Infrequently changing layer attributes that require no special
+ * serialization work.
+ */
 class SimpleLayerAttributes final
 {
   friend struct IPC::ParamTraits<mozilla::layers::SimpleLayerAttributes>;
 public:
   SimpleLayerAttributes()
    : mTransformIsPerspective(false),
      mPostXScale(1.0f),
      mPostYScale(1.0f),
      mContentFlags(0),
      mOpacity(1.0f),
      mIsFixedPosition(false),
-     mScrollbarTargetContainerId(FrameMetrics::NULL_SCROLL_ID),
      mMixBlendMode(gfx::CompositionOp::OP_OVER),
      mForceIsolatedGroup(false)
   {
   }
 
-  //
-  // Setters.
-  // All set methods return true if values changed, false otherwise.
-  //
+  /**
+   * Setters.
+   * All set methods return true if values changed, false otherwise.
+   */
 
   bool SetPostScale(float aXScale, float aYScale) {
     if (mPostXScale == aXScale && mPostYScale == aYScale) {
       return false;
     }
     mPostXScale = aXScale;
     mPostYScale = aYScale;
     return true;
   }
+
   bool SetContentFlags(uint32_t aFlags) {
     if (aFlags == mContentFlags) {
       return false;
     }
     mContentFlags = aFlags;
     return true;
   }
+
   bool SetOpacity(float aOpacity) {
     if (aOpacity == mOpacity) {
       return false;
     }
     mOpacity = aOpacity;
     return true;
   }
+
   bool SetIsFixedPosition(bool aFixedPosition) {
     if (mIsFixedPosition == aFixedPosition) {
       return false;
     }
     mIsFixedPosition = aFixedPosition;
     return true;
   }
-  bool SetScrollThumbData(FrameMetrics::ViewID aScrollId, const ScrollThumbData& aThumbData) {
-    if (mScrollbarTargetContainerId == aScrollId &&
-        mThumbData == aThumbData)
+
+  bool SetScrollbarData(const ScrollbarData& aScrollbarData) {
+    if (mScrollbarData == aScrollbarData)
     {
       return false;
     }
-    mScrollbarTargetContainerId = aScrollId;
-    mThumbData = aThumbData;
+    mScrollbarData = aScrollbarData;
     return true;
   }
-  bool SetScrollbarContainer(FrameMetrics::ViewID aScrollId,
+
+  bool SetScrollbarContainer(FrameMetrics::ViewID aTargetViewId,
                              ScrollDirection aDirection) {
-    if (mScrollbarContainerDirection &&
-        *mScrollbarContainerDirection == aDirection &&
-        mScrollbarTargetContainerId == aScrollId) {
+    if (mScrollbarData.mScrollbarLayerType == ScrollbarLayerType::Container &&
+        mScrollbarData.mDirection &&
+        *mScrollbarData.mDirection == aDirection &&
+        mScrollbarData.mTargetViewId == aTargetViewId) {
       return false;
     }
-    mScrollbarContainerDirection = Some(aDirection);
-    mScrollbarTargetContainerId = aScrollId;
+    mScrollbarData.mDirection = Some(aDirection);
+    mScrollbarData.mTargetViewId = aTargetViewId;
+    mScrollbarData.mScrollbarLayerType = ScrollbarLayerType::Container;
     return true;
   }
+
   bool SetMixBlendMode(gfx::CompositionOp aMixBlendMode) {
     if (mMixBlendMode == aMixBlendMode) {
       return false;
     }
     mMixBlendMode = aMixBlendMode;
     return true;
   }
+
   bool SetForceIsolatedGroup(bool aForceIsolatedGroup) {
     if (mForceIsolatedGroup == aForceIsolatedGroup) {
       return false;
     }
     mForceIsolatedGroup = aForceIsolatedGroup;
     return true;
   }
+
   bool SetTransform(const gfx::Matrix4x4& aMatrix) {
     if (mTransform == aMatrix) {
       return false;
     }
     mTransform = aMatrix;
     return true;
   }
+
   bool SetTransformIsPerspective(bool aIsPerspective) {
     if (mTransformIsPerspective == aIsPerspective) {
       return false;
     }
     mTransformIsPerspective = aIsPerspective;
     return true;
   }
+
   bool SetScrolledClip(const Maybe<LayerClip>& aScrolledClip) {
     if (mScrolledClip == aScrolledClip) {
       return false;
     }
     mScrolledClip = aScrolledClip;
     return true;
   }
-  bool SetFixedPositionData(FrameMetrics::ViewID aScrollId,
+
+  bool SetFixedPositionData(FrameMetrics::ViewID aTargetViewId,
                             const LayerPoint& aAnchor,
                             int32_t aSides)
   {
     if (mFixedPositionData &&
-        mFixedPositionData->mScrollId == aScrollId &&
+        mFixedPositionData->mScrollId == aTargetViewId &&
         mFixedPositionData->mAnchor == aAnchor &&
         mFixedPositionData->mSides == aSides) {
       return false;
     }
     if (!mFixedPositionData) {
       mFixedPositionData.emplace();
     }
-    mFixedPositionData->mScrollId = aScrollId;
+    mFixedPositionData->mScrollId = aTargetViewId;
     mFixedPositionData->mAnchor = aAnchor;
     mFixedPositionData->mSides = aSides;
     return true;
   }
+
   bool SetStickyPositionData(FrameMetrics::ViewID aScrollId,
                              LayerRectAbsolute aOuter, LayerRectAbsolute aInner)
   {
     if (mStickyPositionData &&
         mStickyPositionData->mOuter.IsEqualEdges(aOuter) &&
         mStickyPositionData->mInner.IsEqualEdges(aInner)) {
       return false;
     }
@@ -204,132 +243,145 @@ public:
       mStickyPositionData.emplace();
     }
     mStickyPositionData->mScrollId = aScrollId;
     mStickyPositionData->mOuter = aOuter;
     mStickyPositionData->mInner = aInner;
     return true;
   }
 
-  // This returns true if scrolling info is equivalent for the purposes of
-  // APZ hit testing.
+  /**
+   * This returns true if scrolling info is equivalent for the purposes of
+   * APZ hit testing.
+   */
   bool HitTestingInfoIsEqual(const SimpleLayerAttributes& aOther) const {
-    if (mScrollbarContainerDirection != aOther.mScrollbarContainerDirection) {
+    if (mScrollbarData != aOther.mScrollbarData) {
       return false;
     }
-    if (mScrollbarTargetContainerId != aOther.mScrollbarTargetContainerId) {
-      return false;
-    }
-    if (mThumbData != aOther.mThumbData) {
-      return false;
-    }
-    if (FixedPositionScrollContainerId() != aOther.FixedPositionScrollContainerId()) {
+    if (GetFixedPositionScrollContainerId() != aOther.GetFixedPositionScrollContainerId()) {
       return false;
     }
     if (mTransform != aOther.mTransform) {
       return false;
     }
     return true;
   }
 
-  //
-  // Getters.
-  //
+  /**
+   * Getters.
+   */
 
-  float PostXScale() const {
+  float GetPostXScale() const {
     return mPostXScale;
   }
-  float PostYScale() const {
+
+  float GetPostYScale() const {
     return mPostYScale;
   }
-  uint32_t ContentFlags() const {
+
+  uint32_t GetContentFlags() const {
     return mContentFlags;
   }
-  float Opacity() const {
+
+  float GetOpacity() const {
     return mOpacity;
   }
+
   bool IsFixedPosition() const {
     return mIsFixedPosition;
   }
-  FrameMetrics::ViewID ScrollbarTargetContainerId() const {
-    return mScrollbarTargetContainerId;
+
+  FrameMetrics::ViewID GetScrollbarTargetViewId() const {
+    return mScrollbarData.mTargetViewId;
+  }
+
+  const ScrollbarData& GetScrollbarData() const {
+    return mScrollbarData;
   }
-  const ScrollThumbData& ThumbData() const {
-    return mThumbData;
-  }
+
   Maybe<ScrollDirection> GetScrollbarContainerDirection() const {
-    return mScrollbarContainerDirection;
+    return (mScrollbarData.mScrollbarLayerType == ScrollbarLayerType::Container)
+      ? mScrollbarData.mDirection
+      : Nothing();
   }
-  gfx::CompositionOp MixBlendMode() const {
+
+  gfx::CompositionOp GetMixBlendMode() const {
     return mMixBlendMode;
   }
-  bool ForceIsolatedGroup() const {
+
+  bool GetForceIsolatedGroup() const {
     return mForceIsolatedGroup;
   }
-  const gfx::Matrix4x4& Transform() const {
+
+  const gfx::Matrix4x4& GetTransform() const {
     return mTransform;
   }
-  bool TransformIsPerspective() const {
+
+  bool GetTransformIsPerspective() const {
     return mTransformIsPerspective;
   }
-  const Maybe<LayerClip>& ScrolledClip() const {
+
+  const Maybe<LayerClip>& GetScrolledClip() const {
     return mScrolledClip;
   }
-  FrameMetrics::ViewID FixedPositionScrollContainerId() const {
+
+  FrameMetrics::ViewID GetFixedPositionScrollContainerId() const {
     return mFixedPositionData
            ? mFixedPositionData->mScrollId
            : FrameMetrics::NULL_SCROLL_ID;
   }
-  LayerPoint FixedPositionAnchor() const {
+
+  LayerPoint GetFixedPositionAnchor() const {
     return mFixedPositionData ? mFixedPositionData->mAnchor : LayerPoint();
   }
-  int32_t FixedPositionSides() const {
+
+  int32_t GetFixedPositionSides() const {
     return mFixedPositionData ? mFixedPositionData->mSides : eSideBitsNone;
   }
+
   bool IsStickyPosition() const {
     return !!mStickyPositionData;
   }
-  FrameMetrics::ViewID StickyScrollContainerId() const {
+
+  FrameMetrics::ViewID GetStickyScrollContainerId() const {
     return mStickyPositionData->mScrollId;
   }
-  const LayerRectAbsolute& StickyScrollRangeOuter() const {
+
+  const LayerRectAbsolute& GetStickyScrollRangeOuter() const {
     return mStickyPositionData->mOuter;
   }
-  const LayerRectAbsolute& StickyScrollRangeInner() const {
+
+  const LayerRectAbsolute& GetStickyScrollRangeInner() const {
     return mStickyPositionData->mInner;
   }
 
   bool operator ==(const SimpleLayerAttributes& aOther) const {
     return mTransform == aOther.mTransform &&
            mTransformIsPerspective == aOther.mTransformIsPerspective &&
            mScrolledClip == aOther.mScrolledClip &&
            mPostXScale == aOther.mPostXScale &&
            mPostYScale == aOther.mPostYScale &&
            mContentFlags == aOther.mContentFlags &&
            mOpacity == aOther.mOpacity &&
            mIsFixedPosition == aOther.mIsFixedPosition &&
-           mScrollbarTargetContainerId == aOther.mScrollbarTargetContainerId &&
-           mThumbData == aOther.mThumbData &&
-           mScrollbarContainerDirection == aOther.mScrollbarContainerDirection &&
+           mScrollbarData == aOther.mScrollbarData &&
            mMixBlendMode == aOther.mMixBlendMode &&
            mForceIsolatedGroup == aOther.mForceIsolatedGroup;
   }
 
 private:
   gfx::Matrix4x4 mTransform;
   bool mTransformIsPerspective;
   Maybe<LayerClip> mScrolledClip;
   float mPostXScale;
   float mPostYScale;
   uint32_t mContentFlags;
   float mOpacity;
   bool mIsFixedPosition;
-  uint64_t mScrollbarTargetContainerId;
-  ScrollThumbData mThumbData;
-  Maybe<ScrollDirection> mScrollbarContainerDirection;
+  ScrollbarData mScrollbarData;
   gfx::CompositionOp mMixBlendMode;
   bool mForceIsolatedGroup;
 
   struct FixedPositionData {
     FrameMetrics::ViewID mScrollId;
     LayerPoint mAnchor;
     int32_t mSides;
   };
@@ -337,16 +389,18 @@ private:
 
   struct StickyPositionData {
     FrameMetrics::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 ==.
+  /**
+   * This class may only contain plain-old-data members that can be safely
+   * copied over IPC. Make sure to add new members to operator ==.
+   */
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // mozilla_gfx_layers_LayerAttributes_h
--- a/gfx/layers/LayerMetricsWrapper.h
+++ b/gfx/layers/LayerMetricsWrapper.h
@@ -405,37 +405,37 @@ public:
     MOZ_ASSERT(IsValid());
 
     if (mLayer->AsRefLayer()) {
       return mLayer->AsRefLayer()->GetEventRegionsOverride();
     }
     return EventRegionsOverride::NoOverride;
   }
 
-  const ScrollThumbData& GetScrollThumbData() const
+  const ScrollbarData& GetScrollbarData() const
   {
     MOZ_ASSERT(IsValid());
 
-    return mLayer->GetScrollThumbData();
+    return mLayer->GetScrollbarData();
   }
 
   uint64_t GetScrollbarAnimationId() const
   {
     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 GetScrollbarTargetContainerId() const
   {
     MOZ_ASSERT(IsValid());
 
-    return mLayer->GetScrollbarTargetContainerId();
+    return mLayer->GetScrollbarTargetViewId();
   }
 
   Maybe<ScrollDirection> GetScrollbarContainerDirection() const
   {
     MOZ_ASSERT(IsValid());
     return mLayer->GetScrollbarContainerDirection();
   }
 
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -544,17 +544,17 @@ Layer::CalculateScissorRect(const Render
     scissor.MoveBy(-container->GetIntermediateSurfaceRect().TopLeft());
   }
   return currentClip.Intersect(scissor);
 }
 
 Maybe<ParentLayerIntRect>
 Layer::GetScrolledClipRect() const
 {
-  const Maybe<LayerClip> clip = mSimpleAttrs.ScrolledClip();
+  const Maybe<LayerClip> clip = mSimpleAttrs.GetScrolledClip();
   return clip ? Some(clip->GetClipRect()) : Nothing();
 }
 
 const ScrollMetadata&
 Layer::GetScrollMetadata(uint32_t aIndex) const
 {
   MOZ_ASSERT(aIndex < GetScrollMetadataCount());
   return mScrollMetadata[aIndex];
@@ -584,17 +584,17 @@ Layer::IsScrollableWithoutContent() cons
   return AsContainerLayer()
       && HasScrollableFrameMetrics()
       && !GetFirstChild();
 }
 
 Matrix4x4
 Layer::GetTransform() const
 {
-  Matrix4x4 transform = mSimpleAttrs.Transform();
+  Matrix4x4 transform = mSimpleAttrs.GetTransform();
   transform.PostScale(GetPostXScale(), GetPostYScale(), 1.0f);
   if (const ContainerLayer* c = AsContainerLayer()) {
     transform.PreScale(c->GetPreXScale(), c->GetPreYScale(), 1.0f);
   }
   return transform;
 }
 
 const CSSTransformMatrix
@@ -628,17 +628,17 @@ bool
 Layer::HasTransformAnimation() const
 {
   return mAnimationInfo.HasTransformAnimation();
 }
 
 void
 Layer::ApplyPendingUpdatesForThisTransaction()
 {
-  if (mPendingTransform && *mPendingTransform != mSimpleAttrs.Transform()) {
+  if (mPendingTransform && *mPendingTransform != mSimpleAttrs.GetTransform()) {
     MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PendingUpdatesForThisTransaction", this));
     mSimpleAttrs.SetTransform(*mPendingTransform);
     MutatedSimple();
   }
   mPendingTransform = nullptr;
 
   if (mAnimationInfo.ApplyPendingUpdatesForThisTransaction()) {
     MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PendingUpdatesForThisTransaction", this));
@@ -653,17 +653,17 @@ Layer::ApplyPendingUpdatesForThisTransac
       Mutated();
     }
   }
 }
 
 float
 Layer::GetLocalOpacity()
 {
-  float opacity = mSimpleAttrs.Opacity();
+  float opacity = mSimpleAttrs.GetOpacity();
   if (HostLayer* shadow = AsHostLayer())
     opacity = shadow->GetShadowOpacity();
   return std::min(std::max(opacity, 0.0f), 1.0f);
 }
 
 float
 Layer::GetEffectiveOpacity()
 {
@@ -673,25 +673,25 @@ Layer::GetEffectiveOpacity()
     opacity *= c->GetLocalOpacity();
   }
   return opacity;
 }
 
 CompositionOp
 Layer::GetEffectiveMixBlendMode()
 {
-  if (mSimpleAttrs.MixBlendMode() != CompositionOp::OP_OVER)
-    return mSimpleAttrs.MixBlendMode();
+  if (mSimpleAttrs.GetMixBlendMode() != CompositionOp::OP_OVER)
+    return mSimpleAttrs.GetMixBlendMode();
   for (ContainerLayer* c = GetParent(); c && !c->UseIntermediateSurface();
     c = c->GetParent()) {
-    if(c->mSimpleAttrs.MixBlendMode() != CompositionOp::OP_OVER)
-      return c->mSimpleAttrs.MixBlendMode();
+    if(c->mSimpleAttrs.GetMixBlendMode() != CompositionOp::OP_OVER)
+      return c->mSimpleAttrs.GetMixBlendMode();
   }
 
-  return mSimpleAttrs.MixBlendMode();
+  return mSimpleAttrs.GetMixBlendMode();
 }
 
 Matrix4x4
 Layer::ComputeTransformToPreserve3DRoot()
 {
   Matrix4x4 transform = GetLocalTransform();
   for (Layer* layer = GetParent();
        layer && layer->Extend3DContext();
@@ -1761,24 +1761,24 @@ Layer::PrintInfo(std::stringstream& aStr
   aStream << aPrefix;
   aStream << nsPrintfCString("%s%s (0x%p)", mManager->Name(), Name(), this).get();
 
   layers::PrintInfo(aStream, AsHostLayer());
 
   if (mClipRect) {
     AppendToString(aStream, *mClipRect, " [clip=", "]");
   }
-  if (mSimpleAttrs.ScrolledClip()) {
-    AppendToString(aStream, mSimpleAttrs.ScrolledClip()->GetClipRect(), " [scrolled-clip=", "]");
-    if (const Maybe<size_t>& ix = mSimpleAttrs.ScrolledClip()->GetMaskLayerIndex()) {
+  if (mSimpleAttrs.GetScrolledClip()) {
+    AppendToString(aStream, mSimpleAttrs.GetScrolledClip()->GetClipRect(), " [scrolled-clip=", "]");
+    if (const Maybe<size_t>& ix = mSimpleAttrs.GetScrolledClip()->GetMaskLayerIndex()) {
       AppendToString(aStream, ix.value(), " [scrolled-mask=", "]");
     }
   }
-  if (1.0 != mSimpleAttrs.PostXScale() || 1.0 != mSimpleAttrs.PostYScale()) {
-    aStream << nsPrintfCString(" [postScale=%g, %g]", mSimpleAttrs.PostXScale(), mSimpleAttrs.PostYScale()).get();
+  if (1.0 != mSimpleAttrs.GetPostXScale() || 1.0 != mSimpleAttrs.GetPostYScale()) {
+    aStream << nsPrintfCString(" [postScale=%g, %g]", mSimpleAttrs.GetPostXScale(), mSimpleAttrs.GetPostYScale()).get();
   }
   if (!GetBaseTransform().IsIdentity()) {
     AppendToString(aStream, GetBaseTransform(), " [transform=", "]");
   }
   if (!GetEffectiveTransform().IsIdentity()) {
     AppendToString(aStream, GetEffectiveTransform(), " [effective-transform=", "]");
   }
   if (GetTransformIsPerspective()) {
@@ -1811,22 +1811,22 @@ Layer::PrintInfo(std::stringstream& aStr
     aStream << " [combines3DTransformWithAncestors]";
   }
   if (Is3DContextLeaf()) {
     aStream << " [is3DContextLeaf]";
   }
   if (GetScrollbarContainerDirection().isSome()) {
     aStream << " [scrollbar]";
   }
-  if (Maybe<ScrollDirection> thumbDirection = GetScrollThumbData().mDirection) {
+  if (Maybe<ScrollDirection> thumbDirection = GetScrollbarData().mDirection) {
     if (*thumbDirection == ScrollDirection::eVertical) {
-      aStream << nsPrintfCString(" [vscrollbar=%" PRIu64 "]", GetScrollbarTargetContainerId()).get();
+      aStream << nsPrintfCString(" [vscrollbar=%" PRIu64 "]", GetScrollbarTargetViewId()).get();
     }
     if (*thumbDirection == ScrollDirection::eHorizontal) {
-      aStream << nsPrintfCString(" [hscrollbar=%" PRIu64 "]", GetScrollbarTargetContainerId()).get();
+      aStream << nsPrintfCString(" [hscrollbar=%" PRIu64 "]", GetScrollbarTargetViewId()).get();
     }
   }
   if (GetIsFixedPosition()) {
     LayerPoint anchor = GetFixedPositionAnchor();
     aStream << nsPrintfCString(" [isFixedPosition scrollId=%" PRIu64 " sides=0x%x anchor=%s]",
                      GetFixedPositionScrollContainerId(),
                      GetFixedPositionSides(),
                      ToString(anchor).c_str()).get();
@@ -1962,21 +1962,21 @@ Layer::DumpPacket(layerscope::LayersPack
   }
   // Opacity
   layer->set_opacity(GetOpacity());
   // Content opaque
   layer->set_copaque(static_cast<bool>(GetContentFlags() & CONTENT_OPAQUE));
   // Component alpha
   layer->set_calpha(static_cast<bool>(GetContentFlags() & CONTENT_COMPONENT_ALPHA));
   // Vertical or horizontal bar
-  if (Maybe<ScrollDirection> thumbDirection = GetScrollThumbData().mDirection) {
-    layer->set_direct(*thumbDirection == ScrollDirection::eVertical ?
+  if (GetScrollbarData().mScrollbarLayerType == layers::ScrollbarLayerType::Thumb) {
+    layer->set_direct(*GetScrollbarData().mDirection == ScrollDirection::eVertical ?
                       LayersPacket::Layer::VERTICAL :
                       LayersPacket::Layer::HORIZONTAL);
-    layer->set_barid(GetScrollbarTargetContainerId());
+    layer->set_barid(GetScrollbarTargetViewId());
   }
 
   // Mask layer
   if (mMaskLayer) {
     layer->set_mask(reinterpret_cast<uint64_t>(mMaskLayer.get()));
   }
 
   // DisplayList log.
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -1020,17 +1020,17 @@ public:
     if (mSimpleAttrs.SetForceIsolatedGroup(aForceIsolatedGroup)) {
       MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ForceIsolatedGroup", this));
       MutatedSimple();
     }
   }
 
   bool GetForceIsolatedGroup() const
   {
-    return mSimpleAttrs.ForceIsolatedGroup();
+    return mSimpleAttrs.GetForceIsolatedGroup();
   }
 
   /**
    * CONSTRUCTION PHASE ONLY
    * Set a clip rect which will be applied to this layer as it is
    * composited to the destination. The coordinates are relative to
    * the parent layer (i.e. the contents of this layer
    * are transformed before this clip rect is applied).
@@ -1258,19 +1258,19 @@ public:
   }
 
   /**
    * CONSTRUCTION PHASE ONLY
    * If a layer is a scroll thumb container layer, set the scroll identifier
    * of the scroll frame scrolled by the thumb, and other data related to the
    * thumb.
    */
-  void SetScrollThumbData(FrameMetrics::ViewID aScrollId, const ScrollThumbData& aThumbData)
+  void SetScrollbarData(const ScrollbarData& aThumbData)
   {
-    if (mSimpleAttrs.SetScrollThumbData(aScrollId, aThumbData)) {
+    if (mSimpleAttrs.SetScrollbarData(aThumbData)) {
       MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ScrollbarData", this));
       MutatedSimple();
     }
   }
 
   // Set during construction for the container layer of scrollbar components.
   // |aScrollId| holds the scroll identifier of the scrollable content that
   // the scrollbar is for.
@@ -1286,22 +1286,22 @@ public:
   void SetSimpleAttributes(const SimpleLayerAttributes& aAttrs) {
     mSimpleAttrs = aAttrs;
   }
   const SimpleLayerAttributes& GetSimpleAttributes() const {
     return mSimpleAttrs;
   }
 
   // These getters can be used anytime.
-  float GetOpacity() { return mSimpleAttrs.Opacity(); }
-  gfx::CompositionOp GetMixBlendMode() const { return mSimpleAttrs.MixBlendMode(); }
+  float GetOpacity() { return mSimpleAttrs.GetOpacity(); }
+  gfx::CompositionOp GetMixBlendMode() const { return mSimpleAttrs.GetMixBlendMode(); }
   const Maybe<ParentLayerIntRect>& GetClipRect() const { return mClipRect; }
-  const Maybe<LayerClip>& GetScrolledClip() const { return mSimpleAttrs.ScrolledClip(); }
+  const Maybe<LayerClip>& GetScrolledClip() const { return mSimpleAttrs.GetScrolledClip(); }
   Maybe<ParentLayerIntRect> GetScrolledClipRect() const;
-  uint32_t GetContentFlags() { return mSimpleAttrs.ContentFlags(); }
+  uint32_t GetContentFlags() { return mSimpleAttrs.GetContentFlags(); }
   const LayerIntRegion& GetVisibleRegion() const { return mVisibleRegion; }
   const ScrollMetadata& GetScrollMetadata(uint32_t aIndex) const;
   const FrameMetrics& GetFrameMetrics(uint32_t aIndex) const;
   uint32_t GetScrollMetadataCount() const { return mScrollMetadata.Length(); }
   const nsTArray<ScrollMetadata>& GetAllScrollMetadata() { return mScrollMetadata; }
   bool HasScrollableFrameMetrics() const;
   bool IsScrollableWithoutContent() const;
   const EventRegions& GetEventRegions() const { return mEventRegions; }
@@ -1321,31 +1321,31 @@ public:
   Layer* GetPrevSibling() { return mPrevSibling; }
   const Layer* GetPrevSibling() const { return mPrevSibling; }
   virtual Layer* GetFirstChild() const { return nullptr; }
   virtual Layer* GetLastChild() const { return nullptr; }
   gfx::Matrix4x4 GetTransform() const;
   // Same as GetTransform(), but returns the transform as a strongly-typed
   // matrix. Eventually this will replace GetTransform().
   const CSSTransformMatrix GetTransformTyped() const;
-  const gfx::Matrix4x4& GetBaseTransform() const { return mSimpleAttrs.Transform(); }
+  const gfx::Matrix4x4& GetBaseTransform() const { return mSimpleAttrs.GetTransform(); }
   // Note: these are virtual because ContainerLayerComposite overrides them.
-  virtual float GetPostXScale() const { return mSimpleAttrs.PostXScale(); }
-  virtual float GetPostYScale() const { return mSimpleAttrs.PostYScale(); }
+  virtual float GetPostXScale() const { return mSimpleAttrs.GetPostXScale(); }
+  virtual float GetPostYScale() const { return mSimpleAttrs.GetPostYScale(); }
   bool GetIsFixedPosition() { return mSimpleAttrs.IsFixedPosition(); }
-  bool GetTransformIsPerspective() const { return mSimpleAttrs.TransformIsPerspective(); }
+  bool GetTransformIsPerspective() const { return mSimpleAttrs.GetTransformIsPerspective(); }
   bool GetIsStickyPosition() { return mSimpleAttrs.IsStickyPosition(); }
-  FrameMetrics::ViewID GetFixedPositionScrollContainerId() { return mSimpleAttrs.FixedPositionScrollContainerId(); }
-  LayerPoint GetFixedPositionAnchor() { return mSimpleAttrs.FixedPositionAnchor(); }
-  int32_t GetFixedPositionSides() { return mSimpleAttrs.FixedPositionSides(); }
-  FrameMetrics::ViewID GetStickyScrollContainerId() { return mSimpleAttrs.StickyScrollContainerId(); }
-  const LayerRectAbsolute& GetStickyScrollRangeOuter() { return mSimpleAttrs.StickyScrollRangeOuter(); }
-  const LayerRectAbsolute& GetStickyScrollRangeInner() { return mSimpleAttrs.StickyScrollRangeInner(); }
-  FrameMetrics::ViewID GetScrollbarTargetContainerId() { return mSimpleAttrs.ScrollbarTargetContainerId(); }
-  const ScrollThumbData& GetScrollThumbData() const { return mSimpleAttrs.ThumbData(); }
+  FrameMetrics::ViewID GetFixedPositionScrollContainerId() { return mSimpleAttrs.GetFixedPositionScrollContainerId(); }
+  LayerPoint GetFixedPositionAnchor() { return mSimpleAttrs.GetFixedPositionAnchor(); }
+  int32_t GetFixedPositionSides() { return mSimpleAttrs.GetFixedPositionSides(); }
+  FrameMetrics::ViewID GetStickyScrollContainerId() { return mSimpleAttrs.GetStickyScrollContainerId(); }
+  const LayerRectAbsolute& GetStickyScrollRangeOuter() { return mSimpleAttrs.GetStickyScrollRangeOuter(); }
+  const LayerRectAbsolute& GetStickyScrollRangeInner() { return mSimpleAttrs.GetStickyScrollRangeInner(); }
+  FrameMetrics::ViewID GetScrollbarTargetViewId() { return mSimpleAttrs.GetScrollbarTargetViewId(); }
+  const ScrollbarData& GetScrollbarData() const { return mSimpleAttrs.GetScrollbarData(); }
   bool IsScrollbarContainer() { return mSimpleAttrs.GetScrollbarContainerDirection().isSome(); }
   Maybe<ScrollDirection> GetScrollbarContainerDirection() { return mSimpleAttrs.GetScrollbarContainerDirection(); }
   Layer* GetMaskLayer() const { return mMaskLayer; }
   bool HasPendingTransform() const { return mPendingTransform; }
 
   void CheckCanary() const { mCanary.Check(); }
 
   // Ancestor mask layers are associated with FrameMetrics, but for simplicity
--- a/gfx/layers/apz/public/APZSampler.h
+++ b/gfx/layers/apz/public/APZSampler.h
@@ -19,17 +19,17 @@ namespace wr {
 class TransactionBuilder;
 struct WrTransformProperty;
 } // namespace wr
 
 namespace layers {
 
 class APZCTreeManager;
 class LayerMetricsWrapper;
-struct ScrollThumbData;
+struct ScrollbarData;
 
 /**
  * This interface exposes APZ methods related to "sampling" (i.e. reading the
  * async transforms produced by APZ). These methods should all be called on
  * the sampler thread.
  */
 class APZSampler {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(APZSampler)
@@ -53,17 +53,17 @@ public:
    * |aContent| instead of |aApzc| and |aMetrics|; aContent is the
    * LayerMetricsWrapper corresponding to the scroll frame that is scrolled by
    * the scroll thumb, and so the APZC and metrics can be obtained from
    * |aContent|.
    */
   LayerToParentLayerMatrix4x4 ComputeTransformForScrollThumb(
       const LayerToParentLayerMatrix4x4& aCurrentTransform,
       const LayerMetricsWrapper& aContent,
-      const ScrollThumbData& aThumbData,
+      const ScrollbarData& aThumbData,
       bool aScrollbarIsDescendant,
       AsyncTransformComponentMatrix* aOutClipTransform);
 
   ParentLayerPoint GetCurrentAsyncScrollOffset(const LayerMetricsWrapper& aLayer);
   AsyncTransform GetCurrentAsyncTransform(const LayerMetricsWrapper& aLayer);
   AsyncTransformComponentMatrix GetOverscrollTransform(const LayerMetricsWrapper& aLayer);
   AsyncTransformComponentMatrix GetCurrentAsyncTransformWithOverscroll(const LayerMetricsWrapper& aLayer);
 
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -629,17 +629,17 @@ APZCTreeManager::PushStateToWR(wr::Trans
         MOZ_ASSERT(scrollTargetApzc);
         LayerToParentLayerMatrix4x4 transform = scrollTargetApzc->CallWithLastContentPaintMetrics(
             [&](const FrameMetrics& aMetrics) {
                 return ComputeTransformForScrollThumb(
                     aNode->GetTransform() * AsyncTransformMatrix(),
                     scrollTargetNode->GetTransform().ToUnknownMatrix(),
                     scrollTargetApzc,
                     aMetrics,
-                    aNode->GetScrollThumbData(),
+                    aNode->GetScrollbarData(),
                     scrollTargetNode->IsAncestorOf(aNode),
                     nullptr);
             });
         aTransformArray.AppendElement(wr::ToWrTransformProperty(
             aNode->GetScrollbarAnimationId(),
             transform));
       });
 
@@ -860,18 +860,17 @@ APZCTreeManager::PrepareNodeForLayer(con
         aLayer.GetTransformTyped(),
         (!parentHasPerspective && aLayer.GetClipRect())
           ? Some(ParentLayerIntRegion(*aLayer.GetClipRect()))
           : Nothing(),
         GetEventRegionsOverride(aParent, aLayer),
         aLayer.IsBackfaceHidden());
     node->SetScrollbarData(aLayer.GetScrollbarTargetContainerId(),
                            aLayer.GetScrollbarAnimationId(),
-                           aLayer.GetScrollThumbData(),
-                           aLayer.GetScrollbarContainerDirection());
+                           aLayer.GetScrollbarData());
     node->SetFixedPosData(aLayer.GetFixedPositionScrollContainerId());
     return node;
   }
 
   AsyncPanZoomController* apzc = nullptr;
   // 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.
@@ -1081,18 +1080,17 @@ APZCTreeManager::PrepareNodeForLayer(con
         aLayer.IsBackfaceHidden());
   }
 
   // Note: if layer properties must be propagated to nodes, RecvUpdate in
   // LayerTransactionParent.cpp must ensure that APZ will be notified
   // when those properties change.
   node->SetScrollbarData(aLayer.GetScrollbarTargetContainerId(),
                          aLayer.GetScrollbarAnimationId(),
-                         aLayer.GetScrollThumbData(),
-                         aLayer.GetScrollbarContainerDirection());
+                         aLayer.GetScrollbarData());
   node->SetFixedPosData(aLayer.GetFixedPositionScrollContainerId());
   return node;
 }
 
 template<typename PanGestureOrScrollWheelInput>
 static bool
 WillHandleInput(const PanGestureOrScrollWheelInput& aPanInput)
 {
@@ -1208,17 +1206,17 @@ APZCTreeManager::ReceiveInputEvent(Input
           confFlags.mTargetConfirmed = false;
         }
         result = mInputQueue->ReceiveInputEvent(
           apzc, confFlags, mouseInput, aOutInputBlockId);
 
         // If we're starting an async scrollbar drag
         if (apzDragEnabled && startsDrag && hitScrollbarNode &&
             hitScrollbarNode->IsScrollThumbNode() &&
-            hitScrollbarNode->GetScrollThumbData().mIsAsyncDraggable) {
+            hitScrollbarNode->GetScrollbarData().mThumbIsAsyncDraggable) {
           SetupScrollbarDrag(mouseInput, hitScrollbarNode.get(), apzc.get());
         }
 
         if (result == nsEventStatus_eConsumeDoDefault) {
           // This input event is part of a drag block, so whether or not it is
           // directed at a scrollbar depends on whether the drag block started
           // on a scrollbar.
           hitScrollbar = mInputQueue->IsDragOnScrollbar(hitScrollbar);
@@ -1588,17 +1586,17 @@ APZCTreeManager::ProcessTouchInput(Multi
         &mHitResultForInputBlock, &hitScrollbarNode);
 
     // Check if this event starts a scrollbar touch-drag. The conditions
     // checked are similar to the ones we check for MOUSE_INPUT starting
     // a scrollbar mouse-drag.
     mInScrollbarTouchDrag = gfxPrefs::APZDragEnabled() &&
                             gfxPrefs::APZTouchDragEnabled() && hitScrollbarNode &&
                             hitScrollbarNode->IsScrollThumbNode() &&
-                            hitScrollbarNode->GetScrollThumbData().mIsAsyncDraggable;
+                            hitScrollbarNode->GetScrollbarData().mThumbIsAsyncDraggable;
 
     MOZ_ASSERT(touchBehaviors.Length() == aInput.mTouches.Length());
     for (size_t i = 0; i < touchBehaviors.Length(); i++) {
       APZCTM_LOG("Touch point has allowed behaviours 0x%02x\n", touchBehaviors[i]);
       if (touchBehaviors[i] == AllowedTouchBehavior::UNKNOWN) {
         // If there's any unknown items in the list, throw it out and we'll
         // wait for the main thread to send us a notification.
         touchBehaviors.Clear();
@@ -1763,17 +1761,17 @@ APZCTreeManager::SetupScrollbarDrag(Mous
                                     const HitTestingTreeNode* aScrollThumbNode,
                                     AsyncPanZoomController* aApzc)
 {
   DragBlockState* dragBlock = mInputQueue->GetCurrentDragBlock();
   if (!dragBlock) {
     return;
   }
 
-  const ScrollThumbData& thumbData = aScrollThumbNode->GetScrollThumbData();
+  const ScrollbarData& thumbData = aScrollThumbNode->GetScrollbarData();
   MOZ_ASSERT(thumbData.mDirection.isSome());
 
   // Record the thumb's position at the start of the drag.
   // We snap back to this position if, during the drag, the mouse
   // gets sufficiently far away from the scrollbar.
   dragBlock->SetInitialThumbPos(thumbData.mThumbStart);
 
   // Under some conditions, we can confirm the drag block right away.
@@ -3001,17 +2999,17 @@ APZCTreeManager::ComputeTransformForNode
       MOZ_ASSERT(scrollTargetApzc);
       return scrollTargetApzc->CallWithLastContentPaintMetrics(
         [&](const FrameMetrics& aMetrics) {
           return ComputeTransformForScrollThumb(
               aNode->GetTransform() * AsyncTransformMatrix(),
               scrollTargetNode->GetTransform().ToUnknownMatrix(),
               scrollTargetApzc,
               aMetrics,
-              aNode->GetScrollThumbData(),
+              aNode->GetScrollbarData(),
               scrollTargetNode->IsAncestorOf(aNode),
               nullptr);
         });
     }
   }
   // Otherwise, the node does not have an async transform.
   return aNode->GetTransform() * AsyncTransformMatrix();
 }
@@ -3055,17 +3053,17 @@ APZCTreeManager::GetAPZTestData(LayersId
 }
 
 /*static*/ LayerToParentLayerMatrix4x4
 APZCTreeManager::ComputeTransformForScrollThumb(
     const LayerToParentLayerMatrix4x4& aCurrentTransform,
     const Matrix4x4& aScrollableContentTransform,
     AsyncPanZoomController* aApzc,
     const FrameMetrics& aMetrics,
-    const ScrollThumbData& aThumbData,
+    const ScrollbarData& aScrollbarData,
     bool aScrollbarIsDescendant,
     AsyncTransformComponentMatrix* aOutClipTransform)
 {
   // We only apply the transform if the scroll-target layer has non-container
   // children (i.e. when it has some possibly-visible content). This is to
   // avoid moving scroll-bars in the situation that only a scroll information
   // layer has been built for a scroll frame, as this would result in a
   // disparity between scrollbars and visible content.
@@ -3078,32 +3076,32 @@ APZCTreeManager::ComputeTransformForScro
   AsyncTransformComponentMatrix asyncTransform =
     aApzc->GetCurrentAsyncTransform(AsyncPanZoomController::eForCompositing);
 
   // |asyncTransform| represents the amount by which we have scrolled and
   // zoomed since the last paint. Because the scrollbar was sized and positioned based
   // on the painted content, we need to adjust it based on asyncTransform so that
   // it reflects what the user is actually seeing now.
   AsyncTransformComponentMatrix scrollbarTransform;
-  if (*aThumbData.mDirection == ScrollDirection::eVertical) {
+  if (*aScrollbarData.mDirection == ScrollDirection::eVertical) {
     const ParentLayerCoord asyncScrollY = asyncTransform._42;
     const float asyncZoomY = asyncTransform._22;
 
     // The scroll thumb needs to be scaled in the direction of scrolling by the
     // inverse of the async zoom. This is because zooming in decreases the
     // fraction of the whole srollable rect that is in view.
     const float yScale = 1.f / asyncZoomY;
 
     // Note: |metrics.GetZoom()| doesn't yet include the async zoom.
     const CSSToParentLayerScale effectiveZoom(aMetrics.GetZoom().yScale * asyncZoomY);
 
     // Here we convert the scrollbar thumb ratio into a true unitless ratio by
     // dividing out the conversion factor from the scrollframe's parent's space
     // to the scrollframe's space.
-    const float ratio = aThumbData.mThumbRatio /
+    const float ratio = aScrollbarData.mThumbRatio /
         (aMetrics.GetPresShellResolution() * asyncZoomY);
     // The scroll thumb needs to be translated in opposite direction of the
     // async scroll. This is because scrolling down, which translates the layer
     // content up, should result in moving the scroll thumb down.
     ParentLayerCoord yTranslation = -asyncScrollY * ratio;
 
     // The scroll thumb additionally needs to be translated to compensate for
     // the scale applied above. The origin with respect to which the scale is
@@ -3130,27 +3128,27 @@ APZCTreeManager::ComputeTransformForScro
       // resolution-cancelling transform which ensures the scroll thumb isn't
       // actually rendered at a larger scale.
       yTranslation *= aMetrics.GetPresShellResolution();
     }
 
     scrollbarTransform.PostScale(1.f, yScale, 1.f);
     scrollbarTransform.PostTranslate(0, yTranslation, 0);
   }
-  if (*aThumbData.mDirection == ScrollDirection::eHorizontal) {
+  if (*aScrollbarData.mDirection == ScrollDirection::eHorizontal) {
     // See detailed comments under the VERTICAL case.
 
     const ParentLayerCoord asyncScrollX = asyncTransform._41;
     const float asyncZoomX = asyncTransform._11;
 
     const float xScale = 1.f / asyncZoomX;
 
     const CSSToParentLayerScale effectiveZoom(aMetrics.GetZoom().xScale * asyncZoomX);
 
-    const float ratio = aThumbData.mThumbRatio /
+    const float ratio = aScrollbarData.mThumbRatio /
         (aMetrics.GetPresShellResolution() * asyncZoomX);
     ParentLayerCoord xTranslation = -asyncScrollX * ratio;
 
     const CSSCoord thumbOrigin = (aMetrics.GetScrollOffset().x * ratio);
     const CSSCoord thumbOriginScaled = thumbOrigin * xScale;
     const CSSCoord thumbOriginDelta = thumbOriginScaled - thumbOrigin;
     const ParentLayerCoord thumbOriginDeltaPL = thumbOriginDelta * effectiveZoom;
     xTranslation -= thumbOriginDeltaPL;
--- a/gfx/layers/apz/src/APZCTreeManager.h
+++ b/gfx/layers/apz/src/APZCTreeManager.h
@@ -519,17 +519,17 @@ public:
    * @return The new shadow transform for the scroll thumb layer, including
    *    any pre- or post-scales.
    */
   static LayerToParentLayerMatrix4x4 ComputeTransformForScrollThumb(
       const LayerToParentLayerMatrix4x4& aCurrentTransform,
       const gfx::Matrix4x4& aScrollableContentTransform,
       AsyncPanZoomController* aApzc,
       const FrameMetrics& aMetrics,
-      const ScrollThumbData& aThumbData,
+      const ScrollbarData& aScrollbarData,
       bool aScrollbarIsDescendant,
       AsyncTransformComponentMatrix* aOutClipTransform);
 
   // Assert that the current thread is the sampler thread for this APZCTM.
   void AssertOnSamplerThread();
   // Assert that the current thread is the updater thread for this APZCTM.
   void AssertOnUpdaterThread();
 
--- a/gfx/layers/apz/src/APZSampler.cpp
+++ b/gfx/layers/apz/src/APZSampler.cpp
@@ -62,17 +62,17 @@ APZSampler::SampleAnimations(const Layer
   );
 
   return activeAnimations;
 }
 
 LayerToParentLayerMatrix4x4
 APZSampler::ComputeTransformForScrollThumb(const LayerToParentLayerMatrix4x4& aCurrentTransform,
                                            const LayerMetricsWrapper& aContent,
-                                           const ScrollThumbData& aThumbData,
+                                           const ScrollbarData& aThumbData,
                                            bool aScrollbarIsDescendant,
                                            AsyncTransformComponentMatrix* aOutClipTransform)
 {
   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
   AssertOnSamplerThread();
 
   return mApz->ComputeTransformForScrollThumb(aCurrentTransform,
                                               aContent.GetTransform(),
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -976,19 +976,20 @@ nsEventStatus AsyncPanZoomController::Ha
   if (aEvent.mType == MouseInput::MouseType::MOUSE_DOWN) {
     SetState(SCROLLBAR_DRAG);
   }
 
   if (aEvent.mType != MouseInput::MouseType::MOUSE_MOVE) {
     return nsEventStatus_eConsumeNoDefault;
   }
 
-  const ScrollThumbData& thumbData = node->GetScrollThumbData();
-  MOZ_ASSERT(thumbData.mDirection.isSome());
-  ScrollDirection direction = *thumbData.mDirection;
+  const ScrollbarData& scrollbarData = node->GetScrollbarData();
+  MOZ_ASSERT(scrollbarData.mScrollbarLayerType == layers::ScrollbarLayerType::Thumb);
+  MOZ_ASSERT(scrollbarData.mDirection.isSome());
+  ScrollDirection direction = *scrollbarData.mDirection;
 
   bool isMouseAwayFromThumb = false;
   if (int snapMultiplier = gfxPrefs::SliderSnapMultiplier()) {
     // It's fine to ignore the async component of the thumb's transform,
     // because any async transform of the thumb will be in the direction of
     // scrolling, but here we're interested in the other direction.
     ParentLayerRect thumbRect =
         (node->GetTransform() * AsyncTransformMatrix()).TransformBounds(
@@ -1004,22 +1005,22 @@ nsEventStatus AsyncPanZoomController::Ha
     }
   }
 
   RecursiveMutexAutoLock lock(mRecursiveMutex);
   CSSCoord thumbPosition;
   if (isMouseAwayFromThumb) {
     thumbPosition = aInitialThumbPos;
   } else {
-    thumbPosition = ConvertScrollbarPoint(aEvent.mLocalOrigin, thumbData) -
+    thumbPosition = ConvertScrollbarPoint(aEvent.mLocalOrigin, scrollbarData) -
                     aDragMetrics.mScrollbarDragOffset;
   }
 
-  CSSCoord maxThumbPos = thumbData.mScrollTrackLength;
-  maxThumbPos -= thumbData.mThumbLength;
+  CSSCoord maxThumbPos = scrollbarData.mScrollTrackLength;
+  maxThumbPos -= scrollbarData.mThumbLength;
 
   float scrollPercent = thumbPosition / maxThumbPos;
 
   CSSCoord minScrollPosition =
     GetAxisStart(direction, mFrameMetrics.GetScrollableRect().TopLeft());
   CSSCoord maxScrollPosition =
     GetAxisStart(direction, mFrameMetrics.GetScrollableRect().BottomRight()) -
     GetAxisLength(direction, mFrameMetrics.CalculateCompositedRectInCssPixels());
@@ -1699,17 +1700,17 @@ AsyncPanZoomController::ConvertToGecko(c
                 PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent));
     return true;
   }
   return false;
 }
 
 CSSCoord
 AsyncPanZoomController::ConvertScrollbarPoint(const ParentLayerPoint& aScrollbarPoint,
-                                              const ScrollThumbData& aThumbData) const
+                                              const ScrollbarData& aThumbData) const
 {
   RecursiveMutexAutoLock lock(mRecursiveMutex);
 
   // First, get it into the right coordinate space.
   CSSPoint scrollbarPoint = aScrollbarPoint / mFrameMetrics.GetZoom();
   // The scrollbar can be transformed with the frame but the pres shell
   // resolution is only applied to the scroll frame.
   scrollbarPoint = scrollbarPoint * mFrameMetrics.GetPresShellResolution();
--- a/gfx/layers/apz/src/AsyncPanZoomController.h
+++ b/gfx/layers/apz/src/AsyncPanZoomController.h
@@ -498,17 +498,17 @@ public:
   bool CanScroll(ScrollDirection aDirection) const;
 
   /**
    * Convert a point on the scrollbar from this APZC's ParentLayer coordinates
    * to CSS coordinates relative to the beginning of the scroll track.
    * Only the component in the direction of scrolling is returned.
    */
   CSSCoord ConvertScrollbarPoint(const ParentLayerPoint& aScrollbarPoint,
-                                 const ScrollThumbData& aThumbData) const;
+                                 const ScrollbarData& aThumbData) const;
 
   void NotifyMozMouseScrollEvent(const nsString& aString) const;
 
   bool OverscrollBehaviorAllowsSwipe() const;
 
 protected:
   // Protected destructor, to discourage deletion outside of Release():
   virtual ~AsyncPanZoomController();
--- a/gfx/layers/apz/src/HitTestingTreeNode.cpp
+++ b/gfx/layers/apz/src/HitTestingTreeNode.cpp
@@ -91,71 +91,67 @@ HitTestingTreeNode::SetLastChild(HitTest
       aChild->SetApzcParent(parent);
     }
   }
 }
 
 void
 HitTestingTreeNode::SetScrollbarData(FrameMetrics::ViewID aScrollViewId,
                                      const uint64_t& aScrollbarAnimationId,
-                                     const ScrollThumbData& aThumbData,
-                                     const Maybe<ScrollDirection>& aScrollContainerDirection)
+                                     const ScrollbarData& aScrollbarData)
 {
   mScrollViewId = aScrollViewId;
   mScrollbarAnimationId = aScrollbarAnimationId;
-  mScrollThumbData = aThumbData;
-  mScrollbarContainerDirection = aScrollContainerDirection;
+  mScrollbarData = aScrollbarData;
 }
 
 bool
 HitTestingTreeNode::MatchesScrollDragMetrics(const AsyncDragMetrics& aDragMetrics) const
 {
   return IsScrollThumbNode() &&
-         mScrollThumbData.mDirection == aDragMetrics.mDirection &&
+         mScrollbarData.mDirection == aDragMetrics.mDirection &&
          mScrollViewId == aDragMetrics.mViewId;
 }
 
 bool
 HitTestingTreeNode::IsScrollThumbNode() const
 {
-  return mScrollThumbData.mDirection.isSome();
+  return mScrollbarData.mScrollbarLayerType == layers::ScrollbarLayerType::Thumb;
 }
 
 bool
 HitTestingTreeNode::IsScrollbarNode() const
 {
-  return mScrollbarContainerDirection.isSome() || IsScrollThumbNode();
+  return mScrollbarData.mScrollbarLayerType != layers::ScrollbarLayerType::None;
 }
 
 ScrollDirection
 HitTestingTreeNode::GetScrollbarDirection() const
 {
   MOZ_ASSERT(IsScrollbarNode());
-  if (mScrollThumbData.mDirection.isSome()) {
-    return *(mScrollThumbData.mDirection);
-  }
-  return *mScrollbarContainerDirection;
+  MOZ_ASSERT(mScrollbarData.mDirection.isSome());
+  return *mScrollbarData.mDirection;
 }
 
 FrameMetrics::ViewID
 HitTestingTreeNode::GetScrollTargetId() const
 {
   return mScrollViewId;
 }
 
 const uint64_t&
 HitTestingTreeNode::GetScrollbarAnimationId() const
 {
   return mScrollbarAnimationId;
 }
 
-const ScrollThumbData&
-HitTestingTreeNode::GetScrollThumbData() const
+const ScrollbarData&
+HitTestingTreeNode::GetScrollbarData() const
 {
-  return mScrollThumbData;
+  return mScrollbarData;
 }
 
 void
 HitTestingTreeNode::SetFixedPosData(FrameMetrics::ViewID aFixedPosTarget)
 {
   mFixedPosTarget = aFixedPosTarget;
 }
 
@@ -386,17 +382,17 @@ HitTestingTreeNode::Dump(const char* aPr
   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() : "",
     Stringify(mEventRegions).c_str(), Stringify(mTransform).c_str(),
     mClipRegion ? Stringify(mClipRegion.ref()).c_str() : "none",
-    mScrollbarContainerDirection.isSome() ? " scrollbar" : "",
+    mScrollbarData.mDirection.isSome() ? " scrollbar" : "",
     IsScrollThumbNode() ? " scrollthumb" : "");
   if (mLastChild) {
     mLastChild->Dump(nsPrintfCString("%s  ", aPrefix).get());
   }
 }
 
 void
 HitTestingTreeNode::SetApzcParent(AsyncPanZoomController* aParent)
--- a/gfx/layers/apz/src/HitTestingTreeNode.h
+++ b/gfx/layers/apz/src/HitTestingTreeNode.h
@@ -92,25 +92,24 @@ public:
                       const EventRegionsOverride& aOverride,
                       bool aIsBackfaceHidden);
   bool IsOutsideClip(const ParentLayerPoint& aPoint) const;
 
   /* Scrollbar info */
 
   void SetScrollbarData(FrameMetrics::ViewID aScrollViewId,
                         const uint64_t& aScrollbarAnimationId,
-                        const ScrollThumbData& aThumbData,
-                        const Maybe<ScrollDirection>& aScrollContainerDirection);
+                        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;
-  const ScrollThumbData& GetScrollThumbData() const;
+  const ScrollbarData& GetScrollbarData() const;
   const uint64_t& GetScrollbarAnimationId() const;
 
   /* Fixed pos info */
 
   void SetFixedPosData(FrameMetrics::ViewID aFixedPosTarget);
   FrameMetrics::ViewID GetFixedPosTarget() const;
 
   /* Convert |aPoint| into the LayerPixel space for the layer corresponding to
@@ -145,21 +144,18 @@ private:
   // represents the scroll id of the scroll frame scrolled by the scrollbar.
   FrameMetrics::ViewID mScrollViewId;
 
   // 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 scroll thumb Container layers only.
-  ScrollThumbData mScrollThumbData;
-
-  // This is set for scroll track Container layers only.
-  Maybe<ScrollDirection> mScrollbarContainerDirection;
+  // This is set for scrollbar Container and Thumb layers.
+  ScrollbarData mScrollbarData;
 
   FrameMetrics::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.
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -748,19 +748,19 @@ MoveScrollbarForLayerMargin(Layer* aRoot
                             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) {
-      return (aNode->GetScrollThumbData().mDirection.isSome() &&
-              *aNode->GetScrollThumbData().mDirection == ScrollDirection::eHorizontal &&
-              aNode->GetScrollbarTargetContainerId() == aRootScrollId);
+      return (aNode->GetScrollbarData().mDirection.isSome() &&
+              *aNode->GetScrollbarData().mDirection == ScrollDirection::eHorizontal &&
+              aNode->GetScrollbarTargetViewId() == aRootScrollId);
     });
   if (scrollbar) {
     // Shift the horizontal scrollbar down into the new space exposed by the
     // dynamic toolbar hiding. Technically we should also scale the vertical
     // scrollbar a bit to expand into the new space but it's not as noticeable
     // and it would add a lot more complexity, so we're going with the "it's not
     // worth it" justification.
     TranslateShadowLayer(scrollbar, ParentLayerPoint(0, -aFixedLayerMargins.bottom), true, nullptr);
@@ -1029,33 +1029,33 @@ AsyncCompositionManager::ApplyAsyncConte
                 maskLayer->GetLocalTransformTyped() * combinedAsyncTransform);
           }
 
           appliedTransform = true;
         }
 
         ExpandRootClipRect(layer, fixedLayerMargins);
 
-        if (layer->GetScrollThumbData().mDirection.isSome()) {
+        if (layer->GetScrollbarData().mScrollbarLayerType == layers::ScrollbarLayerType::Thumb) {
           ApplyAsyncTransformToScrollbar(layer);
         }
       });
 
   return appliedTransform;
 }
 
 static bool
 LayerIsScrollbarTarget(const LayerMetricsWrapper& aTarget, Layer* aScrollbar)
 {
   if (!aTarget.GetApzc()) {
     return false;
   }
   const FrameMetrics& metrics = aTarget.Metrics();
   MOZ_ASSERT(metrics.IsScrollable());
-  if (metrics.GetScrollId() != aScrollbar->GetScrollbarTargetContainerId()) {
+  if (metrics.GetScrollId() != aScrollbar->GetScrollbarTargetViewId()) {
     return false;
   }
   return !metrics.IsScrollInfoLayer();
 }
 
 static void
 ApplyAsyncTransformToScrollbarForContent(const RefPtr<APZSampler>& aSampler,
                                          Layer* aScrollbar,
@@ -1064,17 +1064,17 @@ ApplyAsyncTransformToScrollbarForContent
 {
   AsyncTransformComponentMatrix clipTransform;
 
   MOZ_ASSERT(aSampler);
   LayerToParentLayerMatrix4x4 transform =
       aSampler->ComputeTransformForScrollThumb(
           aScrollbar->GetLocalTransformTyped(),
           aContent,
-          aScrollbar->GetScrollThumbData(),
+          aScrollbar->GetScrollbarData(),
           aScrollbarIsDescendant,
           &clipTransform);
 
   if (aScrollbarIsDescendant) {
     // We also need to make a corresponding change on the clip rect of all the
     // layers on the ancestor chain from the scrollbar layer up to but not
     // including the layer with the async transform. Otherwise the scrollbar
     // shifts but gets clipped and so appears to flicker.
--- a/gfx/layers/composite/ContainerLayerComposite.h
+++ b/gfx/layers/composite/ContainerLayerComposite.h
@@ -103,25 +103,25 @@ public:
 
   // If the layer is marked as scale-to-resolution, add a post-scale
   // to the layer's transform equal to the pres shell resolution we're
   // scaling to. This cancels out the post scale of '1 / resolution'
   // added by Layout. TODO: It would be nice to get rid of both of these
   // post-scales.
   virtual float GetPostXScale() const override {
     if (mScaleToResolution) {
-      return mSimpleAttrs.PostXScale() * mPresShellResolution;
+      return mSimpleAttrs.GetPostXScale() * mPresShellResolution;
     }
-    return mSimpleAttrs.PostXScale();
+    return mSimpleAttrs.GetPostXScale();
   }
   virtual float GetPostYScale() const override {
     if (mScaleToResolution) {
-      return mSimpleAttrs.PostYScale() * mPresShellResolution;
+      return mSimpleAttrs.GetPostYScale() * mPresShellResolution;
     }
-    return mSimpleAttrs.PostYScale();
+    return mSimpleAttrs.GetPostYScale();
   }
 
   virtual const char* Name() const override { return "ContainerLayerComposite"; }
   UniquePtr<PreparedData> mPrepared;
 
   RefPtr<CompositingRenderTarget> mLastIntermediateSurface;
 };
 
--- a/gfx/layers/wr/WebRenderScrollData.h
+++ b/gfx/layers/wr/WebRenderScrollData.h
@@ -72,18 +72,18 @@ public:
   EventRegions GetEventRegions() const { return mEventRegions; }
   void SetEventRegionsOverride(const EventRegionsOverride& aOverride) { mEventRegionsOverride = aOverride; }
   EventRegionsOverride GetEventRegionsOverride() const { return mEventRegionsOverride; }
 
   const LayerIntRegion& GetVisibleRegion() const { return mVisibleRegion; }
   void SetReferentId(LayersId aReferentId) { mReferentId = Some(aReferentId); }
   Maybe<LayersId> GetReferentId() const { return mReferentId; }
 
-  void SetScrollThumbData(const ScrollThumbData& aData) { mScrollThumbData = aData; }
-  const ScrollThumbData& GetScrollThumbData() const { return mScrollThumbData; }
+  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 SetScrollbarTargetContainerId(FrameMetrics::ViewID aId) { mScrollbarTargetContainerId = aId; }
   FrameMetrics::ViewID GetScrollbarTargetContainerId() const { return mScrollbarTargetContainerId; }
   void SetScrollbarContainerDirection(ScrollDirection aDirection) { mScrollbarContainerDirection = Some(aDirection); }
   Maybe<ScrollDirection> GetScrollbarContainerDirection() const { return mScrollbarContainerDirection; }
 
   void SetFixedPositionScrollContainerId(FrameMetrics::ViewID aId) { mFixedPosScrollContainerId = aId; }
@@ -110,17 +110,17 @@ private:
   // over IPC, and use on the parent side in APZ.
 
   gfx::Matrix4x4 mTransform;
   bool mTransformIsPerspective;
   EventRegions mEventRegions;
   LayerIntRegion mVisibleRegion;
   Maybe<LayersId> mReferentId;
   EventRegionsOverride mEventRegionsOverride;
-  ScrollThumbData mScrollThumbData;
+  ScrollbarData mScrollbarData;
   uint64_t mScrollbarAnimationId;
   FrameMetrics::ViewID mScrollbarTargetContainerId;
   Maybe<ScrollDirection> mScrollbarContainerDirection;
   FrameMetrics::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
@@ -196,25 +196,25 @@ private:
   uint32_t mPaintSequenceNumber;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 namespace IPC {
 
-// When ScrollThumbData is stored on the layer tree, it's part of
+// When ScrollbarData is stored on the layer tree, it's part of
 // SimpleAttributes which itself uses PlainOldDataSerializer, so
-// we don't need a ParamTraits specialization for ScrollThumbData
-// separately. Here, however, ScrollThumbData is stored as part
+// we don't need a ParamTraits specialization for ScrollbarData
+// separately. Here, however, ScrollbarData is stored as part
 // of WebRenderLayerScrollData whose fields are serialized
 // individually, so we do.
 template<>
-struct ParamTraits<mozilla::layers::ScrollThumbData>
-  : public PlainOldDataSerializer<mozilla::layers::ScrollThumbData>
+struct ParamTraits<mozilla::layers::ScrollbarData>
+  : public PlainOldDataSerializer<mozilla::layers::ScrollbarData>
 { };
 
 template<>
 struct ParamTraits<mozilla::layers::WebRenderLayerScrollData>
 {
   typedef mozilla::layers::WebRenderLayerScrollData paramType;
 
   static void
@@ -223,17 +223,17 @@ struct ParamTraits<mozilla::layers::WebR
     WriteParam(aMsg, aParam.mDescendantCount);
     WriteParam(aMsg, aParam.mScrollIds);
     WriteParam(aMsg, aParam.mTransform);
     WriteParam(aMsg, aParam.mTransformIsPerspective);
     WriteParam(aMsg, aParam.mEventRegions);
     WriteParam(aMsg, aParam.mVisibleRegion);
     WriteParam(aMsg, aParam.mReferentId);
     WriteParam(aMsg, aParam.mEventRegionsOverride);
-    WriteParam(aMsg, aParam.mScrollThumbData);
+    WriteParam(aMsg, aParam.mScrollbarData);
     WriteParam(aMsg, aParam.mScrollbarAnimationId);
     WriteParam(aMsg, aParam.mScrollbarTargetContainerId);
     WriteParam(aMsg, aParam.mScrollbarContainerDirection);
     WriteParam(aMsg, aParam.mFixedPosScrollContainerId);
   }
 
   static bool
   Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
@@ -241,17 +241,17 @@ struct ParamTraits<mozilla::layers::WebR
     return ReadParam(aMsg, aIter, &aResult->mDescendantCount)
         && ReadParam(aMsg, aIter, &aResult->mScrollIds)
         && ReadParam(aMsg, aIter, &aResult->mTransform)
         && ReadParam(aMsg, aIter, &aResult->mTransformIsPerspective)
         && ReadParam(aMsg, aIter, &aResult->mEventRegions)
         && ReadParam(aMsg, aIter, &aResult->mVisibleRegion)
         && ReadParam(aMsg, aIter, &aResult->mReferentId)
         && ReadParam(aMsg, aIter, &aResult->mEventRegionsOverride)
-        && ReadParam(aMsg, aIter, &aResult->mScrollThumbData)
+        && ReadParam(aMsg, aIter, &aResult->mScrollbarData)
         && ReadParam(aMsg, aIter, &aResult->mScrollbarAnimationId)
         && ReadParam(aMsg, aIter, &aResult->mScrollbarTargetContainerId)
         && ReadParam(aMsg, aIter, &aResult->mScrollbarContainerDirection)
         && ReadParam(aMsg, aIter, &aResult->mFixedPosScrollContainerId);
   }
 };
 
 template<>
--- a/gfx/layers/wr/WebRenderScrollDataWrapper.h
+++ b/gfx/layers/wr/WebRenderScrollDataWrapper.h
@@ -280,20 +280,20 @@ public:
   }
 
   EventRegionsOverride GetEventRegionsOverride() const
   {
     MOZ_ASSERT(IsValid());
     return mLayer->GetEventRegionsOverride();
   }
 
-  const ScrollThumbData& GetScrollThumbData() const
+  const ScrollbarData& GetScrollbarData() const
   {
     MOZ_ASSERT(IsValid());
-    return mLayer->GetScrollThumbData();
+    return mLayer->GetScrollbarData();
   }
 
   uint64_t GetScrollbarAnimationId() const
   {
     MOZ_ASSERT(IsValid());
     return mLayer->GetScrollbarAnimationId();
   }
 
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -3378,17 +3378,17 @@ nsIFrame::BuildDisplayListForStackingCon
 
   if (clipCapturedBy == ContainerItemType::eOwnLayerForTransformWithRoundedClip) {
     clipState.Restore();
     resultList.AppendToTop(
       MakeDisplayItem<nsDisplayOwnLayer>(aBuilder, this, &resultList,
                                        aBuilder->CurrentActiveScrolledRoot(),
                                        nsDisplayOwnLayerFlags::eNone,
                                        mozilla::layers::FrameMetrics::NULL_SCROLL_ID,
-                                       ScrollThumbData{}, /* aForceActive = */ false));
+                                       ScrollbarData{}, /* aForceActive = */ false));
     if (aCreatedContainerItem) {
       *aCreatedContainerItem = true;
     }
   }
 
   /* If we have sticky positioning, wrap it in a sticky position item.
    */
   if (useFixedPosition) {
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -6881,17 +6881,17 @@ nsDisplayTableBlendContainer::CreateForB
 {
   return MakeDisplayItem<nsDisplayTableBlendContainer>(aBuilder, aFrame, aList, aActiveScrolledRoot, true, aAncestorFrame);
 }
 
 nsDisplayOwnLayer::nsDisplayOwnLayer(nsDisplayListBuilder* aBuilder,
                                      nsIFrame* aFrame, nsDisplayList* aList,
                                      const ActiveScrolledRoot* aActiveScrolledRoot,
                                      nsDisplayOwnLayerFlags aFlags, ViewID aScrollTarget,
-                                     const ScrollThumbData& aThumbData,
+                                     const ScrollbarData& aThumbData,
                                      bool aForceActive,
                                      bool aClearClipChain)
     : nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot, aClearClipChain)
     , mFlags(aFlags)
     , mScrollTarget(aScrollTarget)
     , mThumbData(aThumbData)
     , mForceActive(aForceActive)
     , mWrAnimationId(0)
@@ -6923,17 +6923,17 @@ nsDisplayOwnLayer::GetLayerState(nsDispl
   }
 
   return RequiredLayerStateForChildren(aBuilder, aManager, aParameters, mList, mAnimatedGeometryRoot);
 }
 
 bool
 nsDisplayOwnLayer::IsScrollThumbLayer() const
 {
-  return mThumbData.mDirection.isSome();
+  return mThumbData.mScrollbarLayerType == layers::ScrollbarLayerType::Thumb;
 }
 
 bool
 nsDisplayOwnLayer::ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) const
 {
   // Render scroll thumb layers even if they are invisible, because async
   // scrolling might bring them into view.
   return IsScrollThumbLayer();
@@ -6945,17 +6945,18 @@ nsDisplayOwnLayer::BuildLayer(nsDisplayL
                               LayerManager* aManager,
                               const ContainerLayerParameters& aContainerParameters)
 {
   RefPtr<ContainerLayer> layer = aManager->GetLayerBuilder()->
     BuildContainerLayerFor(aBuilder, aManager, mFrame, this, &mList,
                            aContainerParameters, nullptr,
                            FrameLayerBuilder::CONTAINER_ALLOW_PULL_BACKGROUND_COLOR);
   if (IsScrollThumbLayer()) {
-    layer->SetScrollThumbData(mScrollTarget, mThumbData);
+    mThumbData.mTargetViewId = mScrollTarget;
+    layer->SetScrollbarData(mThumbData);
   }
   if (mFlags & nsDisplayOwnLayerFlags::eScrollbarContainer) {
     ScrollDirection dir = (mFlags & nsDisplayOwnLayerFlags::eVerticalScrollbar)
                         ? ScrollDirection::eVertical
                         : ScrollDirection::eHorizontal;
     layer->SetScrollbarContainer(mScrollTarget, dir);
   }
 
@@ -7001,17 +7002,17 @@ nsDisplayOwnLayer::CreateWebRenderComman
 bool
 nsDisplayOwnLayer::UpdateScrollData(mozilla::layers::WebRenderScrollData* aData,
                                     mozilla::layers::WebRenderLayerScrollData* aLayerData)
 {
   bool ret = false;
   if (IsScrollThumbLayer()) {
     ret = true;
     if (aLayerData) {
-      aLayerData->SetScrollThumbData(mThumbData);
+      aLayerData->SetScrollbarData(mThumbData);
       aLayerData->SetScrollbarAnimationId(mWrAnimationId);
       aLayerData->SetScrollbarTargetContainerId(mScrollTarget);
     }
   }
   if (mFlags & nsDisplayOwnLayerFlags::eScrollbarContainer) {
     ret = true;
     if (aLayerData) {
       ScrollDirection dir = (mFlags & nsDisplayOwnLayerFlags::eVerticalScrollbar)
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -5473,17 +5473,17 @@ enum class nsDisplayOwnLayerFlags {
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsDisplayOwnLayerFlags)
 
 /**
  * A display item that has no purpose but to ensure its contents get
  * their own layer.
  */
 class nsDisplayOwnLayer : public nsDisplayWrapList {
 public:
-  typedef mozilla::layers::ScrollThumbData ScrollThumbData;
+  typedef mozilla::layers::ScrollbarData ScrollbarData;
 
   /**
    * @param aFlags eGenerateSubdocInvalidations :
    * Add UserData to the created ContainerLayer, so that invalidations
    * for this layer are send to our nsPresContext.
    * eGenerateScrollableLayer : only valid on nsDisplaySubDocument (and
    * subclasses), indicates this layer is to be a scrollable layer, so call
    * ComputeFrameMetrics, etc.
@@ -5491,17 +5491,17 @@ public:
    * is set in the flags, this parameter should be the ViewID of the
    * scrollable content this scrollbar is for.
    */
   nsDisplayOwnLayer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
                     nsDisplayList* aList,
                     const ActiveScrolledRoot* aActiveScrolledRoot,
                     nsDisplayOwnLayerFlags aFlags = nsDisplayOwnLayerFlags::eNone,
                     ViewID aScrollTarget = mozilla::layers::FrameMetrics::NULL_SCROLL_ID,
-                    const ScrollThumbData& aThumbData = ScrollThumbData{},
+                    const ScrollbarData& aThumbData = ScrollbarData{},
                     bool aForceActive = true,
                     bool aClearClipChain = false);
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayOwnLayer();
 #endif
   nsDisplayOwnLayer(nsDisplayListBuilder* aBuilder, const nsDisplayOwnLayer& aOther)
     : nsDisplayWrapList(aBuilder, aOther)
     , mFlags(aOther.mFlags)
@@ -5546,17 +5546,17 @@ public:
   NS_DISPLAY_DECL_NAME("OwnLayer", TYPE_OWN_LAYER)
 protected:
   nsDisplayOwnLayerFlags mFlags;
   ViewID mScrollTarget;
   // If this nsDisplayOwnLayer represents a scroll thumb layer, mThumbData
   // stores information about the scroll thumb. Otherwise, mThumbData will be
   // default-constructed (in particular with mDirection == Nothing())
   // and can be ignored.
-  ScrollThumbData mThumbData;
+  ScrollbarData mThumbData;
   bool mForceActive;
   uint64_t mWrAnimationId;
 };
 
 /**
  * A display item for subdocuments. This is more or less the same as nsDisplayOwnLayer,
  * except that it always populates the FrameMetrics instance on the ContainerLayer it
  * builds.
--- a/layout/xul/nsBoxFrame.cpp
+++ b/layout/xul/nsBoxFrame.cpp
@@ -1386,17 +1386,17 @@ nsBoxFrame::BuildDisplayList(nsDisplayLi
 
     DisplayListClipState::AutoSaveRestore ownLayerClipState(aBuilder);
 
     // Wrap the list to make it its own layer
     aLists.Content()->AppendToTop(
       MakeDisplayItem<nsDisplayOwnLayer>(aBuilder, this, &masterList, ownLayerASR,
                                          nsDisplayOwnLayerFlags::eNone,
                                          mozilla::layers::FrameMetrics::NULL_SCROLL_ID,
-                                         mozilla::layers::ScrollThumbData{}, true, true));
+                                         mozilla::layers::ScrollbarData{}, true, true));
   }
 }
 
 void
 nsBoxFrame::BuildDisplayListForChildren(nsDisplayListBuilder*   aBuilder,
                                         const nsDisplayListSet& aLists)
 {
   nsIFrame* kid = mFrames.FirstChild();
--- a/layout/xul/nsSliderFrame.cpp
+++ b/layout/xul/nsSliderFrame.cpp
@@ -49,17 +49,17 @@
 #include "mozilla/layers/InputAPZContext.h"
 #include <algorithm>
 
 using namespace mozilla;
 using mozilla::layers::APZCCallbackHelper;
 using mozilla::layers::AsyncDragMetrics;
 using mozilla::layers::InputAPZContext;
 using mozilla::layers::ScrollDirection;
-using mozilla::layers::ScrollThumbData;
+using mozilla::layers::ScrollbarData;
 
 bool nsSliderFrame::gMiddlePref = false;
 int32_t nsSliderFrame::gSnapMultiplier;
 
 // Turn this on if you want to debug slider frames.
 #undef DEBUG_SLIDER
 
 static already_AddRefed<nsIContent>
@@ -455,23 +455,24 @@ nsSliderFrame::BuildDisplayListForChildr
       // Restore the saved clip so it applies to the thumb container layer.
       thumbContentsClipState.Restore();
 
       // Wrap the list to make it its own layer.
       const ActiveScrolledRoot* ownLayerASR = contASRTracker.GetContainerASR();
       aLists.Content()->AppendToTop(
         MakeDisplayItem<nsDisplayOwnLayer>(aBuilder, this, &masterList, ownLayerASR,
                                            flags, scrollTargetId,
-                                           ScrollThumbData{scrollDirection,
-                                                           GetThumbRatio(),
-                                                           thumbStart,
-                                                           thumbLength,
-                                                           isAsyncDraggable,
-                                                           sliderTrackStart,
-                                                           sliderTrackLength}));
+                                           ScrollbarData{scrollDirection,
+                                                         layers::ScrollbarLayerType::Thumb,
+                                                         GetThumbRatio(),
+                                                         thumbStart,
+                                                         thumbLength,
+                                                         isAsyncDraggable,
+                                                         sliderTrackStart,
+                                                         sliderTrackLength}));
 
       return;
     }
   }
 
   nsBoxFrame::BuildDisplayListForChildren(aBuilder, aLists);
 }