Bug 1349750 - Move the scroll track extents from AsyncDragMetrics to ScrollThumbData. r=kats draft
authorBotond Ballo <botond@mozilla.com>
Fri, 05 May 2017 15:54:27 -0400
changeset 577143 9420d0fb36175e190cbff6e162fd41d8e5240c81
parent 577058 60ab680a3995e3b5c0e1b4482ca0e7142352bbd2
child 577144 edee38f3b9a7bbce6bae90a2a63bcd4bbcd6bef1
push id58627
push userbballo@mozilla.com
push dateFri, 12 May 2017 22:26:26 +0000
reviewerskats
bugs1349750
milestone55.0a1
Bug 1349750 - Move the scroll track extents from AsyncDragMetrics to ScrollThumbData. r=kats To conserve space in LayerAttributes, we only store the extents along the relevant axis. MozReview-Commit-ID: GAL8Oa2NOde
gfx/ipc/GfxMessageUtils.h
gfx/layers/LayerAttributes.h
gfx/layers/apz/src/AsyncDragMetrics.h
gfx/layers/apz/src/AsyncPanZoomController.cpp
layout/xul/nsSliderFrame.cpp
--- a/gfx/ipc/GfxMessageUtils.h
+++ b/gfx/ipc/GfxMessageUtils.h
@@ -1300,27 +1300,25 @@ struct ParamTraits<mozilla::layers::Asyn
   typedef mozilla::layers::AsyncDragMetrics paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mViewId);
     WriteParam(aMsg, aParam.mPresShellId);
     WriteParam(aMsg, aParam.mDragStartSequenceNumber);
     WriteParam(aMsg, aParam.mScrollbarDragOffset);
-    WriteParam(aMsg, aParam.mScrollTrack);
     WriteParam(aMsg, aParam.mDirection);
   }
 
   static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     return (ReadParam(aMsg, aIter, &aResult->mViewId) &&
             ReadParam(aMsg, aIter, &aResult->mPresShellId) &&
             ReadParam(aMsg, aIter, &aResult->mDragStartSequenceNumber) &&
             ReadParam(aMsg, aIter, &aResult->mScrollbarDragOffset) &&
-            ReadParam(aMsg, aIter, &aResult->mScrollTrack) &&
             ReadParam(aMsg, aIter, &aResult->mDirection));
   }
 };
 
 template <>
 struct ParamTraits<mozilla::gfx::Glyph>
 {
   typedef mozilla::gfx::Glyph paramType;
--- a/gfx/layers/LayerAttributes.h
+++ b/gfx/layers/LayerAttributes.h
@@ -22,37 +22,45 @@ struct ScrollThumbData {
   ScrollThumbData()
     : mDirection(ScrollDirection::NONE)
     , mThumbRatio(0.0f)
     , mIsAsyncDraggable(false)
   {}
   ScrollThumbData(ScrollDirection aDirection,
                   float aThumbRatio,
                   CSSCoord aThumbLength,
-                  bool aIsAsyncDraggable)
+                  bool aIsAsyncDraggable,
+                  CSSCoord aScrollTrackStart,
+                  CSSCoord aScrollTrackLength)
     : mDirection(aDirection)
     , mThumbRatio(aThumbRatio)
     , mThumbLength(aThumbLength)
     , mIsAsyncDraggable(aIsAsyncDraggable)
+    , mScrollTrackStart(aScrollTrackStart)
+    , mScrollTrackLength(aScrollTrackLength)
   {}
 
   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;
   CSSCoord mThumbLength;
   // Whether the scrollbar thumb can be dragged asynchronously.
   bool mIsAsyncDraggable;
+  CSSCoord mScrollTrackStart;
+  CSSCoord mScrollTrackLength;
 
   bool operator==(const ScrollThumbData& aOther) const {
     return mDirection == aOther.mDirection &&
            mThumbRatio == aOther.mThumbRatio &&
            mThumbLength == aOther.mThumbLength &&
-           mIsAsyncDraggable == aOther.mIsAsyncDraggable;
+           mIsAsyncDraggable == aOther.mIsAsyncDraggable &&
+           mScrollTrackStart == aOther.mScrollTrackStart &&
+           mScrollTrackLength == aOther.mScrollTrackLength;
   }
   bool operator!=(const ScrollThumbData& aOther) const {
     return !(*this == aOther);
   }
 };
 
 // Infrequently changing layer attributes that require no special
 // serialization work.
--- a/gfx/layers/apz/src/AsyncDragMetrics.h
+++ b/gfx/layers/apz/src/AsyncDragMetrics.h
@@ -36,30 +36,27 @@ public:
     , mScrollbarDragOffset(0)
     , mDirection(NONE)
   {}
 
   AsyncDragMetrics(const FrameMetrics::ViewID& aViewId,
                    uint32_t aPresShellId,
                    uint64_t aDragStartSequenceNumber,
                    CSSCoord aScrollbarDragOffset,
-                   const CSSRect& aScrollTrack,
                    DragDirection aDirection)
     : mViewId(aViewId)
     , mPresShellId(aPresShellId)
     , mDragStartSequenceNumber(aDragStartSequenceNumber)
     , mScrollbarDragOffset(aScrollbarDragOffset)
-    , mScrollTrack(aScrollTrack)
     , mDirection(aDirection)
   {}
 
   FrameMetrics::ViewID mViewId;
   uint32_t mPresShellId;
   uint64_t mDragStartSequenceNumber;
   CSSCoord mScrollbarDragOffset;
-  CSSRect mScrollTrack;
   DragDirection mDirection;
 };
 
 }
 }
 
 #endif
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -921,19 +921,19 @@ nsEventStatus AsyncPanZoomController::Ha
   // The scrollbar can be transformed with the frame but the pres shell
   // resolution is only applied to the scroll frame.
   CSSPoint scrollbarPoint = scrollFramePoint * mFrameMetrics.GetPresShellResolution();
   CSSRect cssCompositionBound = mFrameMetrics.CalculateCompositedRectInCssPixels();
 
   CSSCoord mousePosition = GetAxisStart(aDragMetrics.mDirection, scrollbarPoint) -
                         aDragMetrics.mScrollbarDragOffset -
                         GetAxisStart(aDragMetrics.mDirection, cssCompositionBound) -
-                        GetAxisStart(aDragMetrics.mDirection, aDragMetrics.mScrollTrack);
-
-  CSSCoord scrollMax = GetAxisLength(aDragMetrics.mDirection, aDragMetrics.mScrollTrack);
+                        thumbData.mScrollTrackStart;
+
+  CSSCoord scrollMax = thumbData.mScrollTrackLength;
   scrollMax -= thumbData.mThumbLength;
 
   float scrollPercent = mousePosition / scrollMax;
 
   CSSCoord minScrollPosition =
     GetAxisStart(aDragMetrics.mDirection, mFrameMetrics.GetScrollableRect().TopLeft());
   CSSCoord maxScrollPosition =
     GetAxisLength(aDragMetrics.mDirection, mFrameMetrics.GetScrollableRect()) -
--- a/layout/xul/nsSliderFrame.cpp
+++ b/layout/xul/nsSliderFrame.cpp
@@ -356,20 +356,20 @@ nsSliderFrame::BuildDisplayListForChildr
   nsIFrame* thumb = nsBox::GetChildXULBox(this);
 
   if (thumb) {
     nsRect thumbRect(thumb->GetRect());
     nsMargin m;
     thumb->GetXULMargin(m);
     thumbRect.Inflate(m);
 
-    nsRect crect;
-    GetXULClientRect(crect);
+    nsRect sliderTrack;
+    GetXULClientRect(sliderTrack);
 
-    if (crect.width < thumbRect.width || crect.height < thumbRect.height)
+    if (sliderTrack.width < thumbRect.width || sliderTrack.height < thumbRect.height)
       return;
 
     // 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.
@@ -389,16 +389,31 @@ nsSliderFrame::BuildDisplayListForChildr
           : ScrollDirection::VERTICAL;
       const float appUnitsPerCss = float(AppUnitsPerCSSPixel());
       CSSCoord thumbLength = NSAppUnitsToFloatPixels(
           isHorizontal ? thumbRect.width : thumbRect.height, appUnitsPerCss);
 
       nsIFrame* scrollbarBox = GetScrollbar();
       bool isAsyncDraggable = !UsesCustomScrollbarMediator(scrollbarBox);
 
+      nsPoint scrollPortOrigin;
+      if (nsIScrollableFrame* scrollFrame = do_QueryFrame(scrollbarBox->GetParent())) {
+        scrollPortOrigin = scrollFrame->GetScrollPortRect().TopLeft();
+      } else {
+        isAsyncDraggable = false;
+      }
+
+      // This rect is the range in which the scroll thumb can slide in.
+      sliderTrack = sliderTrack + GetRect().TopLeft() + scrollbarBox->GetPosition() -
+                    scrollPortOrigin;
+      CSSCoord sliderTrackStart = NSAppUnitsToFloatPixels(
+          isHorizontal ? sliderTrack.x : sliderTrack.y, appUnitsPerCss);
+      CSSCoord sliderTrackLength = NSAppUnitsToFloatPixels(
+          isHorizontal ? sliderTrack.width : sliderTrack.height, appUnitsPerCss);
+
       nsDisplayListBuilder::AutoContainerASRTracker contASRTracker(aBuilder);
       nsDisplayListCollection tempLists;
       nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, tempLists);
 
       // This is a bit of a hack. Collect up all descendant display items
       // and merge them into a single Content() list.
       nsDisplayList masterList;
       masterList.AppendToTop(tempLists.BorderBackground());
@@ -413,17 +428,19 @@ nsSliderFrame::BuildDisplayListForChildr
       DisplayListClipState::AutoSaveRestore ownLayerClipState(aBuilder);
       ownLayerClipState.ClearUpToASR(ownLayerASR);
       aLists.Content()->AppendNewToTop(new (aBuilder)
         nsDisplayOwnLayer(aBuilder, this, &masterList, ownLayerASR,
                           flags, scrollTargetId,
                           ScrollThumbData{scrollDirection,
                                           GetThumbRatio(),
                                           thumbLength,
-                                          isAsyncDraggable}));
+                                          isAsyncDraggable,
+                                          sliderTrackStart,
+                                          sliderTrackLength}));
 
       return;
     }
   }
   
   nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists);
 }
 
@@ -1039,21 +1056,16 @@ nsSliderFrame::StartAPZDrag(WidgetGUIEve
     return;
   }
 
   nsIContent* scrollableContent = scrollFrame->GetContent();
   if (!scrollableContent) {
     return;
   }
 
-  nsIScrollableFrame* scrollFrameAsScrollable = do_QueryFrame(scrollFrame);
-  if (!scrollFrameAsScrollable) {
-    return;
-  }
-
   // APZ dragging requires the scrollbar to be layerized, which doesn't
   // happen for scroll info layers.
   if (ScrollFrameWillBuildScrollInfoLayer(scrollFrame)) {
     return;
   }
 
   // Custom scrollbar mediators are not supported in the APZ codepath.
   if (UsesCustomScrollbarMediator(scrollbarBox)) {
@@ -1067,31 +1079,22 @@ nsSliderFrame::StartAPZDrag(WidgetGUIEve
   bool hasAPZView = hasID && (scrollTargetId != layers::FrameMetrics::NULL_SCROLL_ID);
 
   if (!hasAPZView) {
     return;
   }
 
   nsCOMPtr<nsIContent> scrollbar = GetContentOfBox(scrollbarBox);
 
-  nsRect sliderTrack;
-  GetXULClientRect(sliderTrack);
-
-  // This rect is the range in which the scroll thumb can slide in.
-  sliderTrack = sliderTrack + GetRect().TopLeft() + scrollbarBox->GetPosition() -
-                scrollFrameAsScrollable->GetScrollPortRect().TopLeft();
-  CSSRect sliderTrackCSS = CSSRect::FromAppUnits(sliderTrack);
-
   nsIPresShell* shell = PresContext()->PresShell();
   uint64_t inputblockId = InputAPZContext::GetInputBlockId();
   uint32_t presShellId = shell->GetPresShellId();
   AsyncDragMetrics dragMetrics(scrollTargetId, presShellId, inputblockId,
                                NSAppUnitsToFloatPixels(mDragStart,
                                  float(AppUnitsPerCSSPixel())),
-                               sliderTrackCSS,
                                isHorizontal ? AsyncDragMetrics::HORIZONTAL :
                                               AsyncDragMetrics::VERTICAL);
 
   if (!nsLayoutUtils::HasDisplayPort(scrollableContent)) {
     return;
   }
 
   // It's important to set this before calling nsIWidget::StartAsyncScrollbarDrag(),