Bug 1467873 - Fix FrameMetrics::CalculateCompositedRectInCssPixels(). r=kats draft
authorBotond Ballo <botond@mozilla.com>
Sat, 09 Jun 2018 16:33:26 -0400
changeset 806709 f5b937936fb84b3ae414d6cf0250add4078a9d53
parent 805786 e0595117ff5bda3a63a72ad7b3b8754fec4fb4f0
push id112913
push userbballo@mozilla.com
push dateMon, 11 Jun 2018 05:27:21 +0000
reviewerskats
bugs1467873
milestone62.0a1
Bug 1467873 - Fix FrameMetrics::CalculateCompositedRectInCssPixels(). r=kats - Fix the implementation to return a numerically correct result - Change call sites that should have instead been using CalculateCompositedSizeInCssPixels(), to do so - Rename and document to emphasize that the returned rect is in the CSS pixels of the content surrounding the scroll frame MozReview-Commit-ID: GCPbA1k88rz
gfx/layers/FrameMetrics.h
gfx/layers/apz/src/AsyncPanZoomController.cpp
gfx/layers/apz/util/APZCCallbackHelper.cpp
layout/base/Units.h
--- a/gfx/layers/FrameMetrics.h
+++ b/gfx/layers/FrameMetrics.h
@@ -192,22 +192,35 @@ public:
   CSSSize CalculateCompositedSizeInCssPixels() const
   {
     if (GetZoom() == CSSToParentLayerScale2D(0, 0)) {
       return CSSSize();  // avoid division by zero
     }
     return mCompositionBounds.Size() / GetZoom();
   }
 
-  CSSRect CalculateCompositedRectInCssPixels() const
+  /*
+   * 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
     }
-    return mCompositionBounds / GetZoom();
+    // 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;
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -1051,17 +1051,17 @@ nsEventStatus AsyncPanZoomController::Ha
   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());
+    GetAxisLength(direction, mFrameMetrics.CalculateCompositionBoundsInCssPixelsOfSurroundingContent());
   CSSCoord scrollPosition = minScrollPosition + (scrollPercent * (maxScrollPosition - minScrollPosition));
 
   scrollPosition = std::max(scrollPosition, minScrollPosition);
   scrollPosition = std::min(scrollPosition, maxScrollPosition);
 
   CSSPoint scrollOffset = mFrameMetrics.GetScrollOffset();
   if (direction == ScrollDirection::eHorizontal) {
     scrollOffset.x = scrollPosition;
@@ -1745,17 +1745,17 @@ AsyncPanZoomController::ConvertScrollbar
 
   // 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();
 
   // Now, get it to be relative to the beginning of the scroll track.
-  CSSRect cssCompositionBound = mFrameMetrics.CalculateCompositedRectInCssPixels();
+  CSSRect cssCompositionBound = mFrameMetrics.CalculateCompositionBoundsInCssPixelsOfSurroundingContent();
   return GetAxisStart(*aThumbData.mDirection, scrollbarPoint)
       - GetAxisStart(*aThumbData.mDirection, cssCompositionBound)
       - aThumbData.mScrollTrackStart;
 }
 
 static bool
 AllowsScrollingMoreThanOnePage(double aMultiplier)
 {
--- a/gfx/layers/apz/util/APZCCallbackHelper.cpp
+++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp
@@ -205,20 +205,20 @@ SetDisplayPortMargins(nsIPresShell* aPre
   bool hadDisplayPort = nsLayoutUtils::HasDisplayPort(aContent);
   ScreenMargin margins = aMetrics.GetDisplayPortMargins();
   nsLayoutUtils::SetDisplayPortMargins(aContent, aPresShell, margins, 0);
   if (!hadDisplayPort) {
     nsLayoutUtils::SetZeroMarginDisplayPortOnAsyncScrollableAncestors(
         aContent->GetPrimaryFrame(), nsLayoutUtils::RepaintMode::Repaint);
   }
 
-  CSSRect baseCSS = aMetrics.CalculateCompositedRectInCssPixels();
+  CSSSize baseSize = aMetrics.CalculateCompositedSizeInCssPixels();
   nsRect base(0, 0,
-              baseCSS.Width() * nsPresContext::AppUnitsPerCSSPixel(),
-              baseCSS.Height() * nsPresContext::AppUnitsPerCSSPixel());
+              baseSize.width * nsPresContext::AppUnitsPerCSSPixel(),
+              baseSize.height * nsPresContext::AppUnitsPerCSSPixel());
   nsLayoutUtils::SetDisplayPortBaseIfNotSet(aContent, base);
 }
 
 static already_AddRefed<nsIPresShell>
 GetPresShell(const nsIContent* aContent)
 {
   nsCOMPtr<nsIPresShell> result;
   if (nsIDocument* doc = aContent->GetComposedDoc()) {
--- a/layout/base/Units.h
+++ b/layout/base/Units.h
@@ -134,16 +134,17 @@ typedef gfx::CoordTyped<DesktopPixel> De
 typedef gfx::IntCoordTyped<DesktopPixel> DesktopIntCoord;
 typedef gfx::PointTyped<DesktopPixel> DesktopPoint;
 typedef gfx::IntPointTyped<DesktopPixel> DesktopIntPoint;
 typedef gfx::SizeTyped<DesktopPixel> DesktopSize;
 typedef gfx::IntSizeTyped<DesktopPixel> DesktopIntSize;
 typedef gfx::RectTyped<DesktopPixel> DesktopRect;
 typedef gfx::IntRectTyped<DesktopPixel> DesktopIntRect;
 
+typedef gfx::ScaleFactor<CSSPixel, CSSPixel> CSSToCSSScale;
 typedef gfx::ScaleFactor<CSSPixel, LayoutDevicePixel> CSSToLayoutDeviceScale;
 typedef gfx::ScaleFactor<CSSPixel, LayerPixel> CSSToLayerScale;
 typedef gfx::ScaleFactor<CSSPixel, ScreenPixel> CSSToScreenScale;
 typedef gfx::ScaleFactor<CSSPixel, ParentLayerPixel> CSSToParentLayerScale;
 typedef gfx::ScaleFactor<LayoutDevicePixel, CSSPixel> LayoutDeviceToCSSScale;
 typedef gfx::ScaleFactor<LayoutDevicePixel, LayerPixel> LayoutDeviceToLayerScale;
 typedef gfx::ScaleFactor<LayoutDevicePixel, ScreenPixel> LayoutDeviceToScreenScale;
 typedef gfx::ScaleFactor<LayoutDevicePixel, ParentLayerPixel> LayoutDeviceToParentLayerScale;