Bug 1225571 - Move the code to update the SPCSPS from repaint request handling to when the resolution is updated in the presShell. r=botond
authorKartikaya Gupta <kgupta@mozilla.com>
Wed, 18 Nov 2015 13:53:14 -0500
changeset 309811 52d6ee1e55c922c78367528e8752fabe64ebab71
parent 309810 df9cdd1400626740fbc21f636aad8c284f0e9128
child 309812 1b5636e3136518de47d25306bb5061e42b99d991
push id7649
push usermartin.thomson@gmail.com
push dateThu, 19 Nov 2015 00:06:17 +0000
reviewersbotond
bugs1225571
milestone45.0a1
Bug 1225571 - Move the code to update the SPCSPS from repaint request handling to when the resolution is updated in the presShell. r=botond
gfx/layers/apz/util/APZCCallbackHelper.cpp
layout/base/MobileViewportManager.cpp
layout/base/MobileViewportManager.h
layout/base/nsPresShell.cpp
--- a/gfx/layers/apz/util/APZCCallbackHelper.cpp
+++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp
@@ -215,28 +215,16 @@ APZCCallbackHelper::UpdateRootFrame(Fram
     // If the pres shell resolution has changed on the content side side
     // the time this repaint request was fired, consider this request out of date
     // and drop it; setting a zoom based on the out-of-date resolution can have
     // the effect of getting us stuck with the stale resolution.
     if (presShellResolution != aMetrics.GetPresShellResolution()) {
       return;
     }
 
-    // Set the scroll port size, which determines the scroll range. For example if
-    // a 500-pixel document is shown in a 100-pixel frame, the scroll port length would
-    // be 100, and gecko would limit the maximum scroll offset to 400 (so as to prevent
-    // overscroll). Note that if the content here was zoomed to 2x, the document would
-    // be 1000 pixels long but the frame would still be 100 pixels, and so the maximum
-    // scroll range would be 900. Therefore this calculation depends on the zoom applied
-    // to the content relative to the container.
-    // Note that this needs to happen before scrolling the frame (in UpdateFrameCommon),
-    // otherwise the scroll position may get clamped incorrectly.
-    CSSSize scrollPort = aMetrics.CalculateCompositedSizeInCssPixels();
-    nsLayoutUtils::SetScrollPositionClampingScrollPortSize(shell, scrollPort);
-
     // The pres shell resolution is updated by the the async zoom since the
     // last paint.
     presShellResolution = aMetrics.GetPresShellResolution()
                         * aMetrics.GetAsyncZoom().scale;
     nsLayoutUtils::SetResolutionAndScaleTo(shell, presShellResolution);
   }
 
   // Do this as late as possible since scrolling can flush layout. It also
--- a/layout/base/MobileViewportManager.cpp
+++ b/layout/base/MobileViewportManager.cpp
@@ -76,16 +76,23 @@ MobileViewportManager::Destroy()
 
 void
 MobileViewportManager::RequestReflow()
 {
   MVM_LOG("%p: got a reflow request\n", this);
   RefreshViewportSize(false);
 }
 
+void
+MobileViewportManager::ResolutionUpdated()
+{
+  MVM_LOG("%p: resolution updated\n", this);
+  RefreshSPCSPS();
+}
+
 NS_IMETHODIMP
 MobileViewportManager::HandleEvent(nsIDOMEvent* event)
 {
   nsAutoString type;
   event->GetType(type);
 
   if (type.Equals(DOM_META_ADDED)) {
     MVM_LOG("%p: got a dom-meta-added event\n", this);
@@ -221,16 +228,38 @@ MobileViewportManager::UpdateDisplayPort
     }
     nsIScrollableFrame* scrollable = do_QueryFrame(root);
     nsLayoutUtils::CalculateAndSetDisplayPortMargins(scrollable,
       nsLayoutUtils::RepaintMode::DoNotRepaint);
   }
 }
 
 void
+MobileViewportManager::RefreshSPCSPS()
+{
+  // This function is a subset of RefreshViewportSize, and only updates the
+  // SPCSPS.
+
+  if (!gfxPrefs::APZAllowZooming()) {
+    return;
+  }
+
+  ScreenIntSize displaySize = ViewAs<ScreenPixel>(
+    mDisplaySize, PixelCastJustification::LayoutDeviceIsScreenForBounds);
+
+  CSSToLayoutDeviceScale cssToDev =
+      mPresShell->GetPresContext()->CSSToDevPixelScale();
+  LayoutDeviceToLayerScale res(nsLayoutUtils::GetResolution(mPresShell));
+  CSSToScreenScale zoom = ViewTargetAs<ScreenPixel>(cssToDev * res / ParentLayerToLayerScale(1),
+    PixelCastJustification::ScreenIsParentLayerForRoot);
+
+  UpdateSPCSPS(displaySize, zoom);
+}
+
+void
 MobileViewportManager::RefreshViewportSize(bool aForceAdjustResolution)
 {
   // This function gets called by the various triggers that may result in a
   // change of the CSS viewport. In some of these cases (e.g. the meta-viewport
   // tag changes) we want to update the resolution and in others (e.g. the full
   // zoom changing) we don't want to update the resolution. See the comment in
   // UpdateResolution for some more detail on this. An important assumption we
   // make here is that this RefreshViewportSize function will be called
--- a/layout/base/MobileViewportManager.h
+++ b/layout/base/MobileViewportManager.h
@@ -27,23 +27,30 @@ public:
   MobileViewportManager(nsIPresShell* aPresShell,
                         nsIDocument* aDocument);
   void Destroy();
 
   /* Notify the MobileViewportManager that a reflow was requested in the
    * presShell.*/
   void RequestReflow();
 
+  /* Notify the MobileViewportManager that the resolution on the presShell was
+   * updated, and the SPCSPS needs to be updated. */
+  void ResolutionUpdated();
+
 private:
   ~MobileViewportManager();
 
   /* Main helper method to update the CSS viewport and any other properties that
    * need updating. */
   void RefreshViewportSize(bool aForceAdjustResolution);
 
+  /* Secondary main helper method to update just the SPCSPS. */
+  void RefreshSPCSPS();
+
   /* Updates the presShell resolution and returns the new zoom. */
   mozilla::CSSToScreenScale UpdateResolution(const nsViewportInfo& aViewportInfo,
                                              const mozilla::ScreenIntSize& aDisplaySize,
                                              const mozilla::CSSSize& aViewport,
                                              const mozilla::Maybe<float>& aDisplayWidthChangeRatio);
   /* Updates the scroll-position-clamping scrollport size */
   void UpdateSPCSPS(const mozilla::ScreenIntSize& aDisplaySize,
                     const mozilla::CSSToScreenScale& aZoom);
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -5311,16 +5311,19 @@ nsresult PresShell::SetResolutionImpl(fl
   }
   if (aResolution == mResolution) {
     return NS_OK;
   }
   RenderingState state(this);
   state.mResolution = aResolution;
   SetRenderingState(state);
   mScaleToResolution = aScaleToResolution;
+  if (mMobileViewportManager) {
+    mMobileViewportManager->ResolutionUpdated();
+  }
 
   return NS_OK;
 }
 
 bool PresShell::ScaleToResolution() const
 {
   return mScaleToResolution;
 }