Bug 880676 - Correct the composition bounds to be in screen coordinates rather than layer coordinates. r=kentuckyfriedtakahe
authorKartikaya Gupta <kgupta@mozilla.com>
Fri, 14 Jun 2013 16:11:29 -0400
changeset 146605 494c2b42bd9440d2dc68768ee9c10135de5c8cdf
parent 146604 de0018e03e39fe75b82ca6dffa78507365ce23fa
child 146606 1cffa2a5298c009448cfe8ecbad2eb76a465e713
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskentuckyfriedtakahe
bugs880676
milestone24.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 880676 - Correct the composition bounds to be in screen coordinates rather than layer coordinates. r=kentuckyfriedtakahe
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/ipc/TabParent.cpp
gfx/layers/FrameMetrics.h
gfx/layers/ipc/AsyncPanZoomController.cpp
gfx/layers/ipc/AsyncPanZoomController.h
gfx/layers/ipc/Axis.cpp
layout/base/Units.h
layout/base/nsDisplayList.cpp
layout/ipc/RenderFrameParent.cpp
layout/ipc/RenderFrameParent.h
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -343,19 +343,17 @@ TabChild::Observe(nsISupports *aSubject,
         // page.
         SetCSSViewport(kDefaultViewportSize);
 
         // Calculate a really simple resolution that we probably won't
         // be keeping, as well as putting the scroll offset back to
         // the top-left of the page.
         mLastMetrics.mZoom = gfxSize(1.0, 1.0);
         mLastMetrics.mViewport = CSSRect(CSSPoint(), kDefaultViewportSize);
-        // I don't know what units mInnerSize is in, hence FromUnknownRect
-        mLastMetrics.mCompositionBounds = LayerIntRect::FromUnknownRect(
-          gfx::IntRect(0, 0, mInnerSize.width, mInnerSize.height));
+        mLastMetrics.mCompositionBounds = ScreenIntRect(ScreenIntPoint(), mInnerSize);
         mLastMetrics.mResolution =
           AsyncPanZoomController::CalculateResolution(mLastMetrics);
         mLastMetrics.mScrollOffset = CSSPoint(0, 0);
         utils->SetResolution(mLastMetrics.mResolution.width,
                              mLastMetrics.mResolution.height);
 
         HandlePossibleViewportChange();
       }
@@ -585,19 +583,17 @@ TabChild::HandlePossibleViewportChange()
   int32_t oldScreenWidth = mLastMetrics.mCompositionBounds.width;
   if (!oldScreenWidth) {
     oldScreenWidth = mInnerSize.width;
   }
 
   FrameMetrics metrics(mLastMetrics);
   metrics.mViewport = CSSRect(CSSPoint(), viewport);
   metrics.mScrollableRect = CSSRect(CSSPoint(), pageSize);
-  // I don't know what units mInnerSize is in, hence FromUnknownRect
-  metrics.mCompositionBounds = LayerIntRect::FromUnknownRect(
-    gfx::IntRect(0, 0, mInnerSize.width, mInnerSize.height));
+  metrics.mCompositionBounds = ScreenIntRect(ScreenIntPoint(), mInnerSize);
 
   // Changing the zoom when we're not doing a first paint will get ignored
   // by AsyncPanZoomController and causes a blurry flash.
   bool isFirstPaint;
   nsresult rv = utils->GetIsFirstPaint(&isFirstPaint);
   MOZ_ASSERT(NS_SUCCEEDED(rv));
   if (NS_FAILED(rv) || isFirstPaint) {
     gfxSize intrinsicScale =
@@ -1408,17 +1404,18 @@ TabChild::RecvUpdateDimensions(const nsR
     }
 
     mOuterRect.x = rect.x;
     mOuterRect.y = rect.y;
     mOuterRect.width = rect.width;
     mOuterRect.height = rect.height;
 
     mOrientation = orientation;
-    mInnerSize = size;
+    mInnerSize = ScreenIntSize::FromUnknownSize(
+      gfx::IntSize(size.width, size.height));
     mWidget->Resize(0, 0, size.width, size.height,
                     true);
 
     nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(mWebNav);
     baseWin->SetPositionAndSize(0, 0, size.width, size.height,
                                 true);
 
     HandlePossibleViewportChange();
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -436,17 +436,17 @@ private:
     nsCOMPtr<nsIWebNavigation> mWebNav;
     nsCOMPtr<nsIWidget> mWidget;
     nsCOMPtr<nsIURI> mLastURI;
     FrameMetrics mLastMetrics;
     RenderFrameChild* mRemoteFrame;
     nsRefPtr<TabChildGlobal> mTabChildGlobal;
     uint32_t mChromeFlags;
     nsIntRect mOuterRect;
-    nsIntSize mInnerSize;
+    ScreenIntSize mInnerSize;
     // When we're tracking a possible tap gesture, this is the "down"
     // point of the touchstart.
     nsIntPoint mGestureDownPoint;
     // The touch identifier of the active gesture.
     int32_t mActivePointerId;
     // A timer task that fires if the tap-hold timeout is exceeded by
     // the touch we're tracking.  That is, if touchend or a touchmove
     // that exceeds the gesture threshold doesn't happen.
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -459,17 +459,18 @@ TabParent::UpdateDimensions(const nsRect
       mDimensions != size || !mRect.IsEqualEdges(rect)) {
     mUpdatedDimensions = true;
     mRect = rect;
     mDimensions = size;
     mOrientation = orientation;
 
     unused << SendUpdateDimensions(mRect, mDimensions, mOrientation);
     if (RenderFrameParent* rfp = GetRenderFrame()) {
-      rfp->NotifyDimensionsChanged(mDimensions.width, mDimensions.height);
+      rfp->NotifyDimensionsChanged(ScreenIntSize::FromUnknownSize(
+        gfx::IntSize(mDimensions.width, mDimensions.height)));
     }
   }
 }
 
 void
 TabParent::UpdateFrame(const FrameMetrics& aFrameMetrics)
 {
   if (!mIsDestroyed) {
@@ -1459,17 +1460,18 @@ TabParent::RecvBrowserFrameOpenWindow(PB
 bool
 TabParent::RecvPRenderFrameConstructor(PRenderFrameParent* actor,
                                        ScrollingBehavior* scrolling,
                                        TextureFactoryIdentifier* factoryIdentifier,
                                        uint64_t* layersId)
 {
   RenderFrameParent* rfp = GetRenderFrame();
   if (mDimensions != nsIntSize() && rfp) {
-    rfp->NotifyDimensionsChanged(mDimensions.width, mDimensions.height);
+    rfp->NotifyDimensionsChanged(ScreenIntSize::FromUnknownSize(
+      gfx::IntSize(mDimensions.width, mDimensions.height)));
   }
 
   return true;
 }
 
 bool
 TabParent::RecvZoomToRect(const gfxRect& aRect)
 {
--- a/gfx/layers/FrameMetrics.h
+++ b/gfx/layers/FrameMetrics.h
@@ -113,17 +113,17 @@ public:
   // viewport dimensions to calculate the displayport, we'd run into situations
   // where we're prerendering the wrong regions and the content may be clipped,
   // or too much of it prerendered. If the displayport is the same as the
   // viewport, there is no need for this and we can just use the viewport
   // instead.
   //
   // This is only valid on the root layer. Nested iframes do not need this
   // metric as they do not have a displayport set. See bug 775452.
-  LayerIntRect mCompositionBounds;
+  ScreenIntRect mCompositionBounds;
 
   // ---------------------------------------------------------------------------
   // The following metrics are all in CSS pixels. They are not in any uniform
   // space, so each is explained separately.
   //
 
   // The area of a frame's contents that has been painted, relative to the
   // viewport. It is in the same coordinate space as |mViewport|. For example,
--- a/gfx/layers/ipc/AsyncPanZoomController.cpp
+++ b/gfx/layers/ipc/AsyncPanZoomController.cpp
@@ -892,17 +892,17 @@ const CSSRect AsyncPanZoomController::Ca
   // data. In this case, we're dealing with either a stationary frame or a first
   // paint. In either of these cases, we can just assume it'll take 1 second to
   // paint. Getting this correct is not important anyways since it's only really
   // useful when accelerating, which can't be happening at this point.
   double estimatedPaintDuration =
     aEstimatedPaintDuration > EPSILON ? aEstimatedPaintDuration : 1.0;
 
   gfxSize resolution = CalculateResolution(aFrameMetrics);
-  CSSIntRect compositionBounds = LayerIntRect::ToCSSIntRectRoundIn(
+  CSSIntRect compositionBounds = ScreenIntRect::ToCSSIntRectRoundIn(
     aFrameMetrics.mCompositionBounds, resolution.width, resolution.height);
   CSSRect scrollableRect = aFrameMetrics.mScrollableRect;
 
   // Ensure the scrollableRect is at least as big as the compositionBounds
   // because the scrollableRect can be smaller if the content is not large
   // and the scrollableRect hasn't been updated yet.
   // We move the scrollableRect up because we don't know if we can move it
   // down. i.e. we know that scrollableRect can go back as far as zero.
@@ -983,17 +983,17 @@ AsyncPanZoomController::CalculateResolut
   return gfxSize(intrinsicScale.width * userZoom.width,
                  intrinsicScale.height * userZoom.height);
 }
 
 /*static*/ CSSRect
 AsyncPanZoomController::CalculateCompositedRectInCssPixels(const FrameMetrics& aMetrics)
 {
   gfxSize resolution = CalculateResolution(aMetrics);
-  CSSIntRect rect = LayerIntRect::ToCSSIntRectRoundIn(
+  CSSIntRect rect = ScreenIntRect::ToCSSIntRectRoundIn(
     aMetrics.mCompositionBounds, resolution.width, resolution.height);
   return CSSRect(rect);
 }
 
 void AsyncPanZoomController::SetDPI(int aDPI) {
   mDPI = aDPI;
 }
 
@@ -1269,20 +1269,20 @@ void AsyncPanZoomController::NotifyLayer
   }
 }
 
 const FrameMetrics& AsyncPanZoomController::GetFrameMetrics() {
   mMonitor.AssertCurrentThreadOwns();
   return mFrameMetrics;
 }
 
-void AsyncPanZoomController::UpdateCompositionBounds(const LayerIntRect& aCompositionBounds) {
+void AsyncPanZoomController::UpdateCompositionBounds(const ScreenIntRect& aCompositionBounds) {
   MonitorAutoLock mon(mMonitor);
 
-  LayerIntRect oldCompositionBounds = mFrameMetrics.mCompositionBounds;
+  ScreenIntRect oldCompositionBounds = mFrameMetrics.mCompositionBounds;
   mFrameMetrics.mCompositionBounds = aCompositionBounds;
 
   // If the window had 0 dimensions before, or does now, we don't want to
   // repaint or update the zoom since we'll run into rendering issues and/or
   // divide-by-zero. This manifests itself as the screen flashing. If the page
   // has gone out of view, the buffer will be cleared elsewhere anyways.
   if (aCompositionBounds.width && aCompositionBounds.height &&
       oldCompositionBounds.width && oldCompositionBounds.height) {
@@ -1307,17 +1307,17 @@ void AsyncPanZoomController::DetectScrol
 void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
   CSSRect zoomToRect(aRect.x, aRect.y, aRect.width, aRect.height);
 
   SetState(ANIMATING_ZOOM);
 
   {
     MonitorAutoLock mon(mMonitor);
 
-    LayerIntRect compositionBounds = mFrameMetrics.mCompositionBounds;
+    ScreenIntRect compositionBounds = mFrameMetrics.mCompositionBounds;
     CSSRect cssPageRect = mFrameMetrics.mScrollableRect;
     CSSPoint scrollOffset = mFrameMetrics.mScrollOffset;
     gfxSize resolution = CalculateResolution(mFrameMetrics);
     gfxSize currentZoom = mFrameMetrics.mZoom;
     float targetZoom;
     gfxFloat targetResolution;
 
     // The minimum zoom to prevent over-zoom-out.
@@ -1342,17 +1342,17 @@ void AsyncPanZoomController::ZoomToRect(
     }
     // 1. If the rect is empty, request received from browserElementScrolling.js
     // 2. currentZoom is equal to mMaxZoom and user still double-tapping it
     // 3. currentZoom is equal to localMinZoom and user still double-tapping it
     // Treat these three cases as a request to zoom out as much as possible.
     if (zoomToRect.IsEmpty() ||
         (currentZoom.width == mMaxZoom && targetZoom >= mMaxZoom) ||
         (currentZoom.width == localMinZoom && targetZoom <= localMinZoom)) {
-      CSSIntRect cssCompositionBounds = LayerIntRect::ToCSSIntRectRoundIn(
+      CSSIntRect cssCompositionBounds = ScreenIntRect::ToCSSIntRectRoundIn(
         compositionBounds, resolution.width, resolution.height);
 
       float y = scrollOffset.y;
       float newHeight =
         cssCompositionBounds.height * cssPageRect.width / cssCompositionBounds.width;
       float dh = cssCompositionBounds.height - newHeight;
 
       zoomToRect = CSSRect(0.0f,
--- a/gfx/layers/ipc/AsyncPanZoomController.h
+++ b/gfx/layers/ipc/AsyncPanZoomController.h
@@ -106,17 +106,17 @@ public:
 
   /**
    * Updates the composition bounds, i.e. the dimensions of the final size of
    * the frame this is tied to during composition onto, in device pixels. In
    * general, this will just be:
    * { x = 0, y = 0, width = surface.width, height = surface.height }, however
    * there is no hard requirement for this.
    */
-  void UpdateCompositionBounds(const LayerIntRect& aCompositionBounds);
+  void UpdateCompositionBounds(const ScreenIntRect& aCompositionBounds);
 
   /**
    * We are scrolling a subframe, so disable our machinery until we hit
    * a touch end or a new touch start. This prevents us from accidentally
    * panning both the subframe and the parent frame.
    *
    * XXX/bug 775452: We should eventually be supporting async scrollable
    * subframes.
--- a/gfx/layers/ipc/Axis.cpp
+++ b/gfx/layers/ipc/Axis.cpp
@@ -314,17 +314,17 @@ float Axis::GetPageLength() {
 }
 
 bool Axis::ScaleWillOverscrollBothSides(float aScale) {
   const FrameMetrics& metrics = mAsyncPanZoomController->GetFrameMetrics();
 
   CSSRect cssContentRect = metrics.mScrollableRect;
 
   float scale = metrics.mZoom.width * aScale;
-  CSSIntRect cssCompositionBounds = LayerIntRect::ToCSSIntRectRoundIn(
+  CSSIntRect cssCompositionBounds = ScreenIntRect::ToCSSIntRectRoundIn(
     metrics.mCompositionBounds, scale, scale);
 
   return GetRectLength(cssContentRect) < GetRectLength(CSSRect(cssCompositionBounds));
 }
 
 AxisX::AxisX(AsyncPanZoomController* aAsyncPanZoomController)
   : Axis(aAsyncPanZoomController)
 {
--- a/layout/base/Units.h
+++ b/layout/base/Units.h
@@ -97,22 +97,16 @@ struct LayerPixel {
                                       aRect.y * aResolutionY,
                                       aRect.width * aResolutionX,
                                       aRect.height * aResolutionY);
   }
 
   static gfx::IntRectTyped<LayerPixel> FromCSSRectRounded(const CSSRect& aRect, float aResolutionX, float aResolutionY) {
     return RoundToInt(FromCSSRect(aRect, aResolutionX, aResolutionY));
   }
-
-  static CSSIntRect ToCSSIntRectRoundIn(const gfx::IntRectTyped<LayerPixel>& aRect, float aResolutionX, float aResolutionY) {
-    gfx::IntRectTyped<CSSPixel> ret(aRect.x, aRect.y, aRect.width, aRect.height);
-    ret.ScaleInverseRoundIn(aResolutionX, aResolutionY);
-    return ret;
-  }
 };
 
 typedef gfx::PointTyped<LayerPixel> LayerPoint;
 typedef gfx::IntPointTyped<LayerPixel> LayerIntPoint;
 typedef gfx::IntSizeTyped<LayerPixel> LayerIntSize;
 typedef gfx::RectTyped<LayerPixel> LayerRect;
 typedef gfx::IntRectTyped<LayerPixel> LayerIntRect;
 
@@ -125,18 +119,26 @@ typedef gfx::IntRectTyped<LayerPixel> La
  * chrome UI element sizes) that are not subject to content zoom should
  * generally be represented in ScreenPixel units.
  */
 struct ScreenPixel {
   static CSSPoint ToCSSPoint(const gfx::PointTyped<ScreenPixel>& aPoint, float aResolutionX, float aResolutionY) {
     return CSSPoint(aPoint.x * aResolutionX,
                     aPoint.y * aResolutionY);
   }
+
+  static CSSIntRect ToCSSIntRectRoundIn(const gfx::IntRectTyped<ScreenPixel>& aRect, float aResolutionX, float aResolutionY) {
+    gfx::IntRectTyped<CSSPixel> ret(aRect.x, aRect.y, aRect.width, aRect.height);
+    ret.ScaleInverseRoundIn(aResolutionX, aResolutionY);
+    return ret;
+  }
 };
 
 typedef gfx::PointTyped<ScreenPixel> ScreenPoint;
 typedef gfx::IntPointTyped<ScreenPixel> ScreenIntPoint;
 typedef gfx::SizeTyped<ScreenPixel> ScreenSize;
 typedef gfx::IntSizeTyped<ScreenPixel> ScreenIntSize;
+typedef gfx::RectTyped<ScreenPixel> ScreenRect;
+typedef gfx::IntRectTyped<ScreenPixel> ScreenIntRect;
 
 };
 
 #endif
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -671,18 +671,17 @@ static void RecordFrameMetrics(nsIFrame*
   metrics.mDevPixelsPerCSSPixel =
     (float)nsPresContext::AppUnitsPerCSSPixel() / auPerDevPixel;
 
   metrics.mMayHaveTouchListeners = aMayHaveTouchListeners;
 
   if (nsIWidget* widget = aForFrame->GetNearestWidget()) {
     nsIntRect bounds;
     widget->GetBounds(bounds);
-    // I don't know what units bounds are in, hence FromUnknownRect
-    metrics.mCompositionBounds = LayerIntRect::FromUnknownRect(
+    metrics.mCompositionBounds = ScreenIntRect::FromUnknownRect(
       mozilla::gfx::IntRect(bounds.x, bounds.y, bounds.width, bounds.height));
   }
 
   metrics.mPresShellId = presShell->GetPresShellId();
 
   aRoot->SetFrameMetrics(metrics);
 }
 
--- a/layout/ipc/RenderFrameParent.cpp
+++ b/layout/ipc/RenderFrameParent.cpp
@@ -785,22 +785,21 @@ RenderFrameParent::NotifyInputEvent(cons
                                     nsInputEvent* aOutEvent)
 {
   if (mPanZoomController) {
     mPanZoomController->ReceiveInputEvent(aEvent, aOutEvent);
   }
 }
 
 void
-RenderFrameParent::NotifyDimensionsChanged(int width, int height)
+RenderFrameParent::NotifyDimensionsChanged(ScreenIntSize size)
 {
   if (mPanZoomController) {
-    // I don't know what units width/height are in, hence FromUnknownRect
     mPanZoomController->UpdateCompositionBounds(
-      LayerIntRect::FromUnknownRect(gfx::IntRect(0, 0, width, height)));
+      ScreenIntRect(ScreenIntPoint(), size));
   }
 }
 
 void
 RenderFrameParent::ActorDestroy(ActorDestroyReason why)
 {
   if (mLayersId != 0) {
     CompositorParent::DeallocateLayerTreeId(mLayersId);
--- a/layout/ipc/RenderFrameParent.h
+++ b/layout/ipc/RenderFrameParent.h
@@ -91,17 +91,17 @@ public:
 
   void OwnerContentChanged(nsIContent* aContent);
 
   void SetBackgroundColor(nscolor aColor) { mBackgroundColor = gfxRGBA(aColor); };
 
   void NotifyInputEvent(const nsInputEvent& aEvent,
                         nsInputEvent* aOutEvent);
 
-  void NotifyDimensionsChanged(int width, int height);
+  void NotifyDimensionsChanged(ScreenIntSize size);
 
   void ZoomToRect(const gfxRect& aRect);
 
   void ContentReceivedTouch(bool aPreventDefault);
 
   void UpdateZoomConstraints(bool aAllowZoom, float aMinZoom, float aMaxZoom);
 
 protected: