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 a=lsblakk
authorTimothy Nikkel <tnikkel@gmail.com>
Wed, 02 Apr 2014 17:46:38 -0500
changeset 191648 eef9ddcce2046e863b9565a3ede048fe1099db3f
parent 191647 19f843dcbb5088f97d6ae92e14dec60ef96853ce
child 191649 7906c1b48e0d53f3853911f7ea2e13c83f7e0ffb
push id3503
push userraliiev@mozilla.com
push dateMon, 28 Apr 2014 18:51:11 +0000
treeherdermozilla-beta@c95ac01e332e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats, lsblakk
bugs989897
milestone30.0a2
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 a=lsblakk 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;
@@ -640,21 +641,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();
@@ -666,59 +667,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,