Bug 1501665 Part 8: Allow MVM::RequestReflow to adjust resolution, and do so when destroying the MVM. r=botond
☠☠ backed out by af46b1e88998 ☠ ☠
authorBrad Werth <bwerth@mozilla.com>
Mon, 18 Mar 2019 14:58:31 +0000
changeset 464815 088dc24eabc75eea96301d50550e0a8817f5f809
parent 464814 178210eb72baa05f877b3a35e0c94d0b23880d13
child 464816 3542bf2b89ddf170efe6c723a64f297868bc7db1
push id80720
push userbwerth@mozilla.com
push dateMon, 18 Mar 2019 15:02:22 +0000
treeherderautoland@2fa518cb0dfc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
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 1501665 Part 8: Allow MVM::RequestReflow to adjust resolution, and do so when destroying the MVM. r=botond Currently the MobileViewportManager leaves somethings permanently changed even after it is destroyed: it may have changed the resolution of the Document, and it may have set a fixed size for the visual viewport. Both of these changes need to be un-done to return to normal display of the Document. Differential Revision: https://phabricator.services.mozilla.com/D17999
--- a/layout/base/MobileViewportManager.cpp
+++ b/layout/base/MobileViewportManager.cpp
@@ -116,19 +116,20 @@ mozilla::CSSToScreenScale MobileViewport
     const mozilla::ScreenIntSize& aDisplaySize,
     const mozilla::CSSSize& aViewportOrContentSize) const {
   CSSToScreenScale intrinsicScale =
       MaxScaleRatio(ScreenSize(aDisplaySize), aViewportOrContentSize);
   MVM_LOG("%p: Intrinsic computed zoom is %f\n", this, intrinsicScale.scale);
   return ClampZoom(intrinsicScale, aViewportInfo);
-void MobileViewportManager::RequestReflow() {
-  MVM_LOG("%p: got a reflow request\n", this);
-  RefreshViewportSize(false);
+void MobileViewportManager::RequestReflow(bool aForceAdjustResolution) {
+  MVM_LOG("%p: got a reflow request with force resolution: %d\n", this,
+          aForceAdjustResolution);
+  RefreshViewportSize(aForceAdjustResolution);
 void MobileViewportManager::ResolutionUpdated() {
   MVM_LOG("%p: resolution updated\n", this);
   if (!mPresShell) {
@@ -501,17 +502,18 @@ void MobileViewportManager::RefreshViewp
   // If it's the first-paint or the viewport changed, we need to update
   // various APZ properties (the zoom and some things that might depend on it)
   MVM_LOG("%p: Updating properties because %d || %d\n", this, mIsFirstPaint,
           mMobileViewportSize != viewport);
-  if (nsLayoutUtils::AllowZoomingForDocument(mDocument)) {
+  if (aForceAdjustResolution ||
+      nsLayoutUtils::AllowZoomingForDocument(mDocument)) {
     UpdateResolution(viewportInfo, displaySize, viewport,
                      displayWidthChangeRatio, UpdateType::ViewportSize);
   } else {
     // Even without zoom, we need to update that the visual viewport size
     // has changed.
   if (gfxPlatform::AsyncPanZoomEnabled()) {
--- a/layout/base/MobileViewportManager.h
+++ b/layout/base/MobileViewportManager.h
@@ -55,17 +55,17 @@ class MobileViewportManager final : publ
   float ComputeIntrinsicResolution() const;
   void SetRestoreResolution(float aResolution);
   /* Notify the MobileViewportManager that a reflow was requested in the
    * presShell.*/
-  void RequestReflow();
+  void RequestReflow(bool aForceAdjustResolution);
   /* Notify the MobileViewportManager that the resolution on the presShell was
    * updated, and the visual viewport size needs to be updated. */
   void ResolutionUpdated();
   /* Called to compute the initial viewport on page load or before-first-paint,
    * whichever happens first. Also called directly if we are created after the
    * presShell is initialized. */
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -1834,18 +1834,20 @@ nsresult PresShell::ResizeReflow(nscoord
     // If we have a ZoomConstraintsClient and the available screen area
     // changed, then we might need to disable double-tap-to-zoom, so notify
     // the ZCC to update itself.
   if (mMobileViewportManager) {
     // If we have a mobile viewport manager, request a reflow from it. It can
     // recompute the final CSS viewport and trigger a call to
-    // ResizeReflowIgnoreOverride if it changed.
-    mMobileViewportManager->RequestReflow();
+    // ResizeReflowIgnoreOverride if it changed. We don't force adjusting
+    // of resolution, because that is only necessary when we are destroying
+    // the MVM.
+    mMobileViewportManager->RequestReflow(false);
     return NS_OK;
   return ResizeReflowIgnoreOverride(aWidth, aHeight, aOldWidth, aOldHeight,
 nsresult PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight,
@@ -10522,18 +10524,29 @@ void PresShell::UpdateViewportOverridden
              "Shouldn't reach this without a MobileViewportManager.");
-  mMobileViewportManager->Destroy();
-  mMobileViewportManager = nullptr;
+  // Before we get rid of our MVM, ask it to update the viewport while
+  // forcing resolution, which will undo any scaling it might have imposed.
+  // To do this correctly, we need to first null out mMobileViewportManager,
+  // because during reflow we will check PresShell::GetIsViewportOverriden(),
+  // which uses that value as a signifier.
+  RefPtr<MobileViewportManager> oldMVM;
+  mMobileViewportManager.swap(oldMVM);
+  oldMVM->RequestReflow(true);
+  ResetVisualViewportSize();
+  oldMVM->Destroy();
+  oldMVM = nullptr;
   if (aAfterInitialization) {
     // Force a reflow to our correct size by going back to the docShell
     // and asking it to reassert its size. This is necessary because
     // everything underneath the docShell, like the ViewManager, has been
     // altered by the MobileViewportManager in an irreversible way.
     nsDocShell* docShell =