Bug 1160250 - Extract a helper function from the triplicated composition-bounds-updating code. r=botond,tn
authorKartikaya Gupta <kgupta@mozilla.com>
Thu, 07 May 2015 14:39:20 -0400
changeset 242817 5ff0763a09c459984523f72561d9f64c32830300
parent 242816 ffeb7ddc393f45cadc0d9824818cd9ef8c09953c
child 242818 9dfb28c444008452cb9bb5f99137b9c3747140f0
push id59521
push userkgupta@mozilla.com
push dateThu, 07 May 2015 18:39:43 +0000
treeherdermozilla-inbound@9dfb28c44400 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond, tn
bugs1160250
milestone40.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 1160250 - Extract a helper function from the triplicated composition-bounds-updating code. r=botond,tn
layout/base/nsLayoutUtils.cpp
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -7592,16 +7592,75 @@ nsLayoutUtils::GetContentViewerSize(nsPr
 
   nsIntRect bounds;
   cv->GetBounds(bounds);
   aOutSize = LayoutDeviceIntRect::FromUntyped(bounds).Size();
   return true;
 }
 
 static bool
+UpdateCompositionBoundsForRCDRSF(ParentLayerRect& aCompBounds,
+                                 nsPresContext* aPresContext,
+                                 const nsRect& aFrameBounds,
+                                 bool aScaleContentViewerSize,
+                                 const LayoutDeviceToLayerScale2D& aCumulativeResolution)
+{
+  nsIFrame* rootFrame = aPresContext->PresShell()->GetRootFrame();
+  if (!rootFrame) {
+    return false;
+  }
+
+  // On Android, we need to do things a bit differently to get things
+  // right (see bug 983208, bug 988882). We use the bounds of the nearest
+  // widget, but clamp the height to the frame bounds height. This clamping
+  // is done to get correct results for a page where the page is sized to
+  // the screen and thus the dynamic toolbar never disappears. In such a
+  // case, we want the composition bounds to exclude the toolbar height,
+  // but the widget bounds includes it. We don't currently have a good way
+  // of knowing about the toolbar height, but clamping to the frame bounds
+  // height gives the correct answer in the cases we care about.
+#ifdef MOZ_WIDGET_ANDROID
+  nsIWidget* widget = rootFrame->GetNearestWidget();
+#else
+  nsView* view = rootFrame->GetView();
+  nsIWidget* widget = view ? view->GetWidget() : nullptr;
+#endif
+
+  if (widget) {
+    nsIntRect widgetBounds;
+    widget->GetBounds(widgetBounds);
+    widgetBounds.MoveTo(0, 0);
+    aCompBounds = ParentLayerRect(ViewAs<ParentLayerPixel>(widgetBounds));
+#ifdef MOZ_WIDGET_ANDROID
+    ParentLayerRect frameBounds =
+          LayoutDeviceRect::FromAppUnits(aFrameBounds, aPresContext->AppUnitsPerDevPixel())
+        * aCumulativeResolution
+        * LayerToParentLayerScale(1.0);
+    if (frameBounds.height < aCompBounds.height) {
+      aCompBounds.height = frameBounds.height;
+    }
+#endif
+    return true;
+  }
+
+  LayoutDeviceIntSize contentSize;
+  if (nsLayoutUtils::GetContentViewerSize(aPresContext, contentSize)) {
+    LayoutDeviceToParentLayerScale scale;
+    if (aScaleContentViewerSize && aPresContext->GetParentPresContext()) {
+      scale = LayoutDeviceToParentLayerScale(
+        aPresContext->GetParentPresContext()->PresShell()->GetCumulativeResolution());
+    }
+    aCompBounds.SizeTo(contentSize * scale);
+    return true;
+  }
+
+  return false;
+}
+
+static bool
 DeflateScrollbarAreaFromCompositionBoundsFor(nsIFrame* aScrollFrame)
 {
   if (!aScrollFrame || !aScrollFrame->GetScrollTargetFrame()) {
     return false;
   }
   nsPresContext* presContext = aScrollFrame->PresContext();
   nsIPresShell* presShell = presContext->GetPresShell();
   if (!presShell) {
@@ -7624,60 +7683,26 @@ nsLayoutUtils::CalculateCompositionSizeF
   // scroll port. The scroll port excludes the frame borders and the scroll
   // bars, which we don't want to be part of the composition bounds.
   nsIScrollableFrame* scrollableFrame = aFrame->GetScrollTargetFrame();
   nsSize size = scrollableFrame ? scrollableFrame->GetScrollPortRect().Size() : aFrame->GetSize();
 
   nsPresContext* presContext = aFrame->PresContext();
   nsIPresShell* presShell = presContext->PresShell();
 
-  // See the comments in the code that calculates the root
-  // composition bounds in ComputeFrameMetrics.
-  // TODO: Reuse that code here.
   bool isRootContentDocRootScrollFrame = presContext->IsRootContentDocument()
                                       && aFrame == presShell->GetRootScrollFrame();
   if (isRootContentDocRootScrollFrame) {
-    if (nsIFrame* rootFrame = presShell->GetRootFrame()) {
-#ifdef MOZ_WIDGET_ANDROID
-      nsIWidget* widget = rootFrame->GetNearestWidget();
-#else
-      nsView* view = rootFrame->GetView();
-      nsIWidget* widget = view ? view->GetWidget() : nullptr;
-#endif
+    ParentLayerRect compBounds;
+    // TODO: The UpdateCompositionBoundsForRCDRSF below doesn't take into
+    // account the mTransformScale as part of the LayerToParentLayerScale.
+    if (UpdateCompositionBoundsForRCDRSF(compBounds, presContext, aFrame->GetRect(),
+        false, LayoutDeviceToParentLayerScale2D(presShell->GetCumulativeResolution()))) {
       int32_t auPerDevPixel = presContext->AppUnitsPerDevPixel();
-      if (widget) {
-        nsIntRect widgetBounds;
-        widget->GetBounds(widgetBounds);
-        size = nsSize(widgetBounds.width * auPerDevPixel,
-                      widgetBounds.height * auPerDevPixel);
-#ifdef MOZ_WIDGET_ANDROID
-        nsRect frameRect = aFrame->GetRect();
-        float cumulativeResolution = presShell->GetCumulativeResolution();
-        LayoutDeviceToParentLayerScale layoutToParentLayerScale =
-          // The ScreenToParentLayerScale should be mTransformScale which is
-          // not calculated yet, but we don't yet handle CSS transforms, so we
-          // assume it's 1 here.
-          LayoutDeviceToLayerScale(cumulativeResolution) *
-          LayerToScreenScale(1.0) * ScreenToParentLayerScale(1.0);
-        ParentLayerRect frameRectPixels =
-          LayoutDeviceRect::FromAppUnits(frameRect, auPerDevPixel)
-          * layoutToParentLayerScale;
-        if (frameRectPixels.height < ParentLayerRect(ViewAs<ParentLayerPixel>(widgetBounds)).height) {
-          // Our return value is in appunits of the parent, so we need to
-          // include the resolution.
-          size.height =
-            NSToCoordRound(frameRect.height * cumulativeResolution);
-        }
-#endif
-      } else {
-        LayoutDeviceIntSize contentSize;
-        if (nsLayoutUtils::GetContentViewerSize(presContext, contentSize)) {
-          size = LayoutDevicePixel::ToAppUnits(contentSize, auPerDevPixel);
-        }
-      }
+      size = nsSize(compBounds.width * auPerDevPixel, compBounds.height * auPerDevPixel);
     }
   }
 
   if (aSubtractScrollbars && DeflateScrollbarAreaFromCompositionBoundsFor(aFrame)) {
     MOZ_ASSERT(scrollableFrame);
     nsMargin margins = scrollableFrame->GetActualScrollbarSizes();
     size.width -= margins.LeftRight();
     size.height -= margins.TopBottom();
@@ -8275,54 +8300,18 @@ nsLayoutUtils::ComputeFrameMetrics(nsIFr
   // the prescontext that the viewport frame is reflowed into. In that case if our
   // document has a widget then the widget's bounds will correspond to what is
   // visible. If we don't have a widget the root view's bounds correspond to what
   // would be visible because they don't get modified by setCSSViewport.
   bool isRootScrollFrame = aScrollFrame == presShell->GetRootScrollFrame();
   bool isRootContentDocRootScrollFrame = isRootScrollFrame
                                       && presContext->IsRootContentDocument();
   if (isRootContentDocRootScrollFrame) {
-    if (nsIFrame* rootFrame = presShell->GetRootFrame()) {
-      // On Android, we need to do things a bit differently to get things
-      // right (see bug 983208, bug 988882). We use the bounds of the nearest
-      // widget, but clamp the height to the frame bounds height. This clamping
-      // is done to get correct results for a page where the page is sized to
-      // the screen and thus the dynamic toolbar never disappears. In such a
-      // case, we want the composition bounds to exclude the toolbar height,
-      // but the widget bounds includes it. We don't currently have a good way
-      // of knowing about the toolbar height, but clamping to the frame bounds
-      // height gives the correct answer in the cases we care about.
-#ifdef MOZ_WIDGET_ANDROID
-      nsIWidget* widget = rootFrame->GetNearestWidget();
-#else
-      nsView* view = rootFrame->GetView();
-      nsIWidget* widget = view ? view->GetWidget() : nullptr;
-#endif
-      if (widget) {
-        nsIntRect widgetBounds;
-        widget->GetBounds(widgetBounds);
-        widgetBounds.MoveTo(0,0);
-        metrics.mCompositionBounds = ParentLayerRect(ViewAs<ParentLayerPixel>(widgetBounds));
-#ifdef MOZ_WIDGET_ANDROID
-        if (frameBounds.height < metrics.mCompositionBounds.height) {
-          metrics.mCompositionBounds.height = frameBounds.height;
-        }
-#endif
-      } else {
-        LayoutDeviceIntSize contentSize;
-        if (nsLayoutUtils::GetContentViewerSize(presContext, contentSize)) {
-          LayoutDeviceToParentLayerScale scale;
-          if (presContext->GetParentPresContext()) {
-            float res = presContext->GetParentPresContext()->PresShell()->GetCumulativeResolution();
-            scale = LayoutDeviceToParentLayerScale(res);
-          }
-          metrics.mCompositionBounds.SizeTo(contentSize * scale);
-        }
-      }
-    }
+    UpdateCompositionBoundsForRCDRSF(metrics.mCompositionBounds, presContext,
+      compositionBounds, true, metrics.GetCumulativeResolution());
   }
 
   if (DeflateScrollbarAreaFromCompositionBoundsFor(aScrollFrame)) {
     MOZ_ASSERT(scrollableFrame);
     nsMargin sizes = scrollableFrame->GetActualScrollbarSizes();
     // Scrollbars are not subject to scaling, so CSS pixels = layer pixels for them.
     ParentLayerMargin boundMargins = CSSMargin::FromAppUnits(sizes) * CSSToParentLayerScale(1.0f);
     metrics.mCompositionBounds.Deflate(boundMargins);