Bug 989897. In order to properly compute root composition size view the root composition size first as layer pixels in the target layer, then convert to css pixels. r=kats
authorTimothy Nikkel <tnikkel@gmail.com>
Wed, 02 Apr 2014 17:46:38 -0500
changeset 176764 4c74157ac995e1b28865281ad4745ba2ed191cc3
parent 176763 d2e06fb325b879130834590a36dc4d2463b61d76
child 176765 bab702b3df10ea96fd97af762a24a03f88fce23a
push id41849
push usertnikkel@gmail.com
push dateWed, 02 Apr 2014 22:47:02 +0000
treeherdermozilla-inbound@4c74157ac995 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs989897
milestone31.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 989897. In order to properly compute root composition size view the root composition size first as layer pixels in the target layer, then convert to css pixels. r=kats Since our goal is to use the root composition size to bound the layer size of the display port of the child layer this makes sense.
layout/base/UnitTransforms.h
layout/base/nsDisplayList.cpp
--- a/layout/base/UnitTransforms.h
+++ b/layout/base/UnitTransforms.h
@@ -15,17 +15,19 @@ namespace mozilla {
 // coordinate system to another without changing the values it stores (this
 // can be thought of as a cast).
 // To use these functions, you must provide a justification for each use!
 // Feel free to add more justifications to PixelCastJustification, along with
 // a comment that explains under what circumstances it is appropriate to use.
 
 MOZ_BEGIN_ENUM_CLASS(PixelCastJustification, uint8_t)
   // For the root layer, Screen Pixel = Parent Layer Pixel.
-  ScreenToParentLayerForRoot
+  ScreenToParentLayerForRoot,
+  // For the root composition size we want to view it as layer pixels in any layer
+  ParentLayerToLayerForRootComposition
 MOZ_END_ENUM_CLASS(PixelCastJustification)
 
 template <class TargetUnits, class SourceUnits>
 gfx::SizeTyped<TargetUnits> ViewAs(const gfx::SizeTyped<SourceUnits>& aSize, PixelCastJustification) {
   return gfx::SizeTyped<TargetUnits>(aSize.width, aSize.height);
 }
 template <class TargetUnits, class SourceUnits>
 gfx::IntSizeTyped<TargetUnits> ViewAs(const gfx::IntSizeTyped<SourceUnits>& aSize, PixelCastJustification) {
@@ -38,16 +40,20 @@ gfx::IntSizeTyped<TargetUnits> ViewAs(co
 template <class TargetUnits>
 gfx::PointTyped<TargetUnits> ViewAs(const gfxPoint& aPoint) {
   return gfx::PointTyped<TargetUnits>(aPoint.x, aPoint.y);
 }
 template <class TargetUnits>
 gfx::RectTyped<TargetUnits> ViewAs(const gfxRect& aRect) {
   return gfx::RectTyped<TargetUnits>(aRect.x, aRect.y, aRect.width, aRect.height);
 }
+template <class TargetUnits>
+gfx::IntSizeTyped<TargetUnits> ViewAs(const nsIntSize& aSize) {
+  return gfx::IntSizeTyped<TargetUnits>(aSize.width, aSize.height);
+}
 
 // Convenience functions for casting typed entities to untyped entities.
 // Using these functions does not require a justification, but once we convert
 // all code to use strongly typed units they should not be needed any longer.
 template <class SourceUnits>
 gfxPoint ViewAsUntyped(const gfx::PointTyped<SourceUnits>& aPoint) {
   return gfxPoint(aPoint.x, aPoint.y);
 }
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -46,16 +46,17 @@
 #include "ImageContainer.h"
 #include "nsCanvasFrame.h"
 #include "StickyScrollContainer.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/Preferences.h"
 #include "ActiveLayerTracker.h"
 #include "nsContentUtils.h"
 #include "nsPrintfCString.h"
+#include "UnitTransforms.h"
 
 #include <stdint.h>
 #include <algorithm>
 
 using namespace mozilla;
 using namespace mozilla::css;
 using namespace mozilla::layers;
 using namespace mozilla::dom;
@@ -641,21 +642,21 @@ static bool GetApzcTreePrintPref() {
 static CSSSize
 CalculateRootCompositionSize(FrameMetrics& aMetrics,
                              bool aIsRootContentDocRootScrollFrame,
                              nsPresContext* aPresContext,
                              nsIFrame* aForFrame, nsIFrame* aScrollFrame)
 {
 
   if (aIsRootContentDocRootScrollFrame) {
-    // convert from parent layer pixels to layer pixels to css pixels
-    return ParentLayerSize(aMetrics.mCompositionBounds.Size())
-                           * aMetrics.mResolution / aMetrics.LayersPixelsPerCSSPixel();
-  }
-  ParentLayerIntSize rootCompositionSize;
+    return ViewAs<LayerPixel>(ParentLayerSize(aMetrics.mCompositionBounds.Size()),
+                              PixelCastJustification::ParentLayerToLayerForRootComposition)
+           / aMetrics.LayersPixelsPerCSSPixel();
+  }
+  LayerSize rootCompositionSize;
   nsPresContext* rootPresContext =
     aPresContext->GetToplevelContentDocumentPresContext();
   if (!rootPresContext) {
     rootPresContext = aPresContext->GetRootPresContext();
   }
   nsIPresShell* rootPresShell = nullptr;
   if (rootPresContext) {
     nsIPresShell* rootPresShell = rootPresContext->PresShell();
@@ -667,59 +668,50 @@ CalculateRootCompositionSize(FrameMetric
         // out what a proper fix is.
         if (!widget) {
           widget = rootFrame->GetNearestWidget();
         }
   #endif
         if (widget) {
           nsIntRect bounds;
           widget->GetBounds(bounds);
-          rootCompositionSize = ParentLayerIntSize::FromUnknownSize(mozilla::gfx::IntSize(
-            bounds.width, bounds.height));
+          rootCompositionSize = LayerSize(ViewAs<LayerPixel>(bounds.Size()));
         } else {
-          gfxSize res = rootPresShell->GetCumulativeResolution();
-          LayoutDeviceToParentLayerScale parentResolution(res.width);
+          LayoutDeviceToParentLayerScale parentResolution(
+            rootPresShell->GetCumulativeResolution().width
+            / rootPresShell->GetResolution().width);
           int32_t rootAUPerDevPixel = rootPresContext->AppUnitsPerDevPixel();
           nsRect viewBounds = view->GetBounds();
-          rootCompositionSize =
-            RoundedToInt(LayoutDeviceRect::FromAppUnits(viewBounds, rootAUPerDevPixel)
-            * parentResolution).Size();
+          rootCompositionSize = ViewAs<LayerPixel>(
+            (LayoutDeviceRect::FromAppUnits(viewBounds, rootAUPerDevPixel)
+             * parentResolution).Size(), PixelCastJustification::ParentLayerToLayerForRootComposition);
         }
       }
     }
   } else {
     nsIWidget* widget = (aScrollFrame ? aScrollFrame : aForFrame)->GetNearestWidget();
     nsIntRect bounds;
     widget->GetBounds(bounds);
-    rootCompositionSize = ParentLayerIntSize::FromUnknownSize(mozilla::gfx::IntSize(
-      bounds.width, bounds.height));
-  }
-
-  LayoutDeviceToParentLayerScale parentResolution(1.0f);
-  if (rootPresShell) {
-    parentResolution.scale =
-      rootPresShell->GetCumulativeResolution().width / rootPresShell->GetResolution().width;
-  }
-
-  CSSSize size =
-    ParentLayerSize(rootCompositionSize) / (parentResolution * aMetrics.mDevPixelsPerCSSPixel);
+    rootCompositionSize = LayerSize(ViewAs<LayerPixel>(bounds.Size()));
+  }
 
   // Adjust composition size for the size of scroll bars.
   nsIFrame* rootRootScrollFrame = rootPresShell ? rootPresShell->GetRootScrollFrame() : nullptr;
   nsIScrollableFrame* rootScrollableFrame = nullptr;
   if (rootRootScrollFrame) {
     rootScrollableFrame = aScrollFrame->GetScrollTargetFrame();
   }
   if (rootScrollableFrame && !LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars)) {
     CSSMargin margins = CSSMargin::FromAppUnits(rootScrollableFrame->GetActualScrollbarSizes());
-    size.width -= margins.LeftRight();
-    size.height -= margins.TopBottom();
-  }
-
-  return size;
+    // Scrollbars are not subject to scaling, so CSS pixels = layer pixels for them.
+    rootCompositionSize.width -= margins.LeftRight();
+    rootCompositionSize.height -= margins.TopBottom();
+  }
+
+  return rootCompositionSize / aMetrics.LayersPixelsPerCSSPixel();
 }
 
 static void RecordFrameMetrics(nsIFrame* aForFrame,
                                nsIFrame* aScrollFrame,
                                const nsIFrame* aReferenceFrame,
                                ContainerLayer* aRoot,
                                const nsRect& aVisibleRect,
                                const nsRect& aViewport,