Bug 904533 - Compute FrameMetrics::mCompositionBounds correctly for subframes. r=tn
authorBotond Ballo <botond@mozilla.com>
Fri, 30 Aug 2013 13:22:33 -0400
changeset 145526 4db34d255ed0070b9f8a7eacc67a1e35b0c78aa9
parent 145525 6537b89b9063bfc48dec8fbb9bad2af11d0d6e98
child 145527 746266548b657302dc9fab8f49ba84581e61e5b3
push id33307
push userbballo@mozilla.com
push dateWed, 04 Sep 2013 21:17:55 +0000
treeherdermozilla-inbound@4db34d255ed0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstn
bugs904533
milestone26.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 904533 - Compute FrameMetrics::mCompositionBounds correctly for subframes. r=tn
dom/base/nsDOMWindowUtils.cpp
layout/base/Units.h
layout/base/nsDisplayList.cpp
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -618,17 +618,17 @@ nsDOMWindowUtils::SendMouseEventToWindow
                               aIgnoreRootScrollFrame, aPressure,
                               aInputSourceArg, true, nullptr);
 }
 
 static LayoutDeviceIntPoint
 ToWidgetPoint(const CSSPoint& aPoint, const nsPoint& aOffset,
               nsPresContext* aPresContext)
 {
-  return LayoutDeviceIntPoint::FromAppUnits(
+  return LayoutDeviceIntPoint::FromAppUnitsRounded(
     CSSPoint::ToAppUnits(aPoint) + aOffset,
     aPresContext->AppUnitsPerDevPixel());
 }
 
 static inline int16_t
 GetButtonsFlagForButton(int32_t aButton)
 {
   switch (aButton) {
--- a/layout/base/Units.h
+++ b/layout/base/Units.h
@@ -143,27 +143,34 @@ struct LayoutDevicePixel {
   static nsIntPoint ToUntyped(const LayoutDeviceIntPoint& aPoint) {
     return nsIntPoint(aPoint.x, aPoint.y);
   }
 
   static LayoutDeviceIntRect FromUntyped(const nsIntRect& aRect) {
     return LayoutDeviceIntRect(aRect.x, aRect.y, aRect.width, aRect.height);
   }
 
-  static LayoutDeviceIntPoint FromAppUnits(const nsPoint& aPoint, nscoord aAppUnitsPerDevPixel) {
+  static LayoutDeviceRect FromAppUnits(const nsRect& aRect, nscoord aAppUnitsPerDevPixel) {
+    return LayoutDeviceRect(NSAppUnitsToFloatPixels(aRect.x, float(aAppUnitsPerDevPixel)),
+                            NSAppUnitsToFloatPixels(aRect.y, float(aAppUnitsPerDevPixel)),
+                            NSAppUnitsToFloatPixels(aRect.width, float(aAppUnitsPerDevPixel)),
+                            NSAppUnitsToFloatPixels(aRect.height, float(aAppUnitsPerDevPixel)));
+  }
+
+  static LayoutDeviceIntPoint FromAppUnitsRounded(const nsPoint& aPoint, nscoord aAppUnitsPerDevPixel) {
     return LayoutDeviceIntPoint(NSAppUnitsToIntPixels(aPoint.x, aAppUnitsPerDevPixel),
                                 NSAppUnitsToIntPixels(aPoint.y, aAppUnitsPerDevPixel));
   }
 
-  static LayoutDeviceIntPoint FromAppUnitsToNearest(const nsPoint& aPoint, nscoord appUnitsPerDevPixel) {
-    return FromUntyped(aPoint.ToNearestPixels(appUnitsPerDevPixel));
+  static LayoutDeviceIntPoint FromAppUnitsToNearest(const nsPoint& aPoint, nscoord aAppUnitsPerDevPixel) {
+    return FromUntyped(aPoint.ToNearestPixels(aAppUnitsPerDevPixel));
   }
 
-  static LayoutDeviceIntRect FromAppUnitsToNearest(const nsRect& aRect, nscoord appUnitsPerDevPixel) {
-    return FromUntyped(aRect.ToNearestPixels(appUnitsPerDevPixel));
+  static LayoutDeviceIntRect FromAppUnitsToNearest(const nsRect& aRect, nscoord aAppUnitsPerDevPixel) {
+    return FromUntyped(aRect.ToNearestPixels(aAppUnitsPerDevPixel));
   }
 };
 
 /*
  * The pixels that layout rasterizes and delivers to the graphics code.
  * These are generally referred to as "device pixels" in layout code. Layer
  * pixels are affected by:
  * 1) the "display resolution" (see nsIPresShell::SetResolution)
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -39,16 +39,17 @@
 #include "nsSVGClipPathFrame.h"
 #include "GeckoProfiler.h"
 #include "nsAnimationManager.h"
 #include "nsTransitionManager.h"
 #include "nsViewManager.h"
 #include "ImageLayers.h"
 #include "ImageContainer.h"
 #include "nsCanvasFrame.h"
+#include "mozilla/LookAndFeel.h"
 
 #include <stdint.h>
 #include <algorithm>
 
 using namespace mozilla;
 using namespace mozilla::css;
 using namespace mozilla::layers;
 using namespace mozilla::dom;
@@ -666,38 +667,47 @@ static void RecordFrameMetrics(nsIFrame*
   } else {
     // Only the root scrollable frame for a given presShell should pick up
     // the presShell's resolution. All the other subframes are 1.0.
     metrics.mResolution = LayoutDeviceToLayerScale(1.0f);
   }
   metrics.mDevPixelsPerCSSPixel = CSSToLayoutDeviceScale(
     (float)nsPresContext::AppUnitsPerCSSPixel() / auPerDevPixel);
 
-  // Provide an initial zoom to the AsyncPanZoomController so that it
-  // renders the content to the screen at the painted resolution.
+  // Initially, AsyncPanZoomController should render the content to the screen
+  // at the painted resolution.
+  const LayerToScreenScale layerToScreenScale(1.0f);
   metrics.mZoom = metrics.mResolution * metrics.mDevPixelsPerCSSPixel
-                * LayerToScreenScale(1.0f);
+                * layerToScreenScale;
 
   metrics.mMayHaveTouchListeners = aMayHaveTouchListeners;
 
-  if (nsIWidget* widget = aForFrame->GetNearestWidget()) {
-    nsIntRect bounds;
-    widget->GetBounds(bounds);
-    metrics.mCompositionBounds = ScreenIntRect::FromUnknownRect(
-      mozilla::gfx::IntRect(bounds.x, bounds.y, bounds.width, bounds.height));
-  }
-
-  // Adjust for the size of scroll bars.
-  if (scrollableFrame) {
-    nsMargin sizes = scrollableFrame->GetActualScrollbarSizes();
-    ScreenIntMargin boundMargins(nsPresContext::AppUnitsToIntCSSPixels(sizes.top),
-                                 nsPresContext::AppUnitsToIntCSSPixels(sizes.right),
-                                 nsPresContext::AppUnitsToIntCSSPixels(sizes.bottom),
-                                 nsPresContext::AppUnitsToIntCSSPixels(sizes.left));
-    metrics.mCompositionBounds.Deflate(boundMargins);
+  if (aScrollFrame) {
+    metrics.mCompositionBounds = RoundedToInt(LayoutDeviceRect::FromAppUnits(
+        aScrollFrame->GetScreenRectInAppUnits(), auPerDevPixel)
+                               * metrics.mResolution
+                               * layerToScreenScale);
+
+    // Adjust for the size of scroll bars.
+    if (scrollableFrame && !LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars)) {
+      nsMargin sizes = scrollableFrame->GetActualScrollbarSizes();
+      // Scrollbars are not subject to scaling, so CSS pixels = screen pixels for them.
+      ScreenIntMargin boundMargins(nsPresContext::AppUnitsToIntCSSPixels(sizes.top),
+                                   nsPresContext::AppUnitsToIntCSSPixels(sizes.right),
+                                   nsPresContext::AppUnitsToIntCSSPixels(sizes.bottom),
+                                   nsPresContext::AppUnitsToIntCSSPixels(sizes.left));
+      metrics.mCompositionBounds.Deflate(boundMargins);
+    }
+  } else {
+    // We are in a document without a root scroll frame, so it's a xul document.
+    // In this case, use the size of the viewport frame.
+    metrics.mCompositionBounds = RoundedToInt(LayoutDeviceRect::FromAppUnits(
+        aForFrame->GetScreenRectInAppUnits(), auPerDevPixel)
+                               * metrics.mResolution
+                               * layerToScreenScale);
   }
 
   metrics.mPresShellId = presShell->GetPresShellId();
 
   aRoot->SetFrameMetrics(metrics);
 }
 
 nsDisplayListBuilder::~nsDisplayListBuilder() {