Bug 1757410 - Ensure MobileViewportManager::UpdateSizesBeforeReflow gets called with up-to-date app-units-per-dev-pixel and CV bounds in UIResolutionChangedInternal. r=emilio
authorHiroyuki Ikezoe <hikezoe.birchill@mozilla.com>
Mon, 15 Aug 2022 03:39:20 +0000
changeset 627122 3459b021f7a5f37433d9784e1421e571e73a6113
parent 627121 c1245a74819a71fdcbdf0196d65552a582d98295
child 627123 985d9726a7f61aa712a3477b63500eed5eb6c0e6
push id40129
push usermlaza@mozilla.com
push dateMon, 15 Aug 2022 09:42:32 +0000
treeherdermozilla-central@dd1d7c05b994 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1757410
milestone105.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 1757410 - Ensure MobileViewportManager::UpdateSizesBeforeReflow gets called with up-to-date app-units-per-dev-pixel and CV bounds in UIResolutionChangedInternal. r=emilio Before this change, BrowserChild::RecvUIResolutionChanged calls UIResolutionChangedSync first, then updates CV bounds. With the setup, when UIResolutionChangedInternal gets called, the CV bounds hasn't yet been updated so that UpdateSizesBeforeReflow doesn't get the proper metrics. This change consists of three parts; 1) Use UIResolutionChangedSync instead of UIResolutionChanged in nsDocumentViewer::SetBoundsWithFlags which calls nsPresContext::AppUnitsPerDevPixel which needs to be actually updated by UIResolutionChangedSync. 2) Move the UIResolutionChangedSync call in RecvUIResolutionChanged after the SetPositionAndSize in the function. 3) Add a UpdateSizesBeforeReflow call in UIResolutionChangedInternal As for 1), nsDocumentViewer::SetBoundsWithFlags calls nsPresContext::AppUnitsPerDevPixel so that UIResolutionChangedInternal needs to be called synchronously rather than asynchronously. As for 2), SetPositionAndSize gets called only if the BrowserChild size is changed, so we need to call UIResolutionChangedSync in other cases. Differential Revision: https://phabricator.services.mozilla.com/D153687
dom/ipc/BrowserChild.cpp
layout/base/nsDocumentViewer.cpp
layout/base/nsPresContext.cpp
--- a/dom/ipc/BrowserChild.cpp
+++ b/dom/ipc/BrowserChild.cpp
@@ -3238,37 +3238,38 @@ void BrowserChild::NotifyJankedAnimation
 }
 
 mozilla::ipc::IPCResult BrowserChild::RecvUIResolutionChanged(
     const float& aDpi, const int32_t& aRounding, const double& aScale) {
   ScreenIntSize oldScreenSize = GetInnerSize();
   if (aDpi > 0) {
     mPuppetWidget->UpdateBackingScaleCache(aDpi, aRounding, aScale);
   }
-  nsCOMPtr<Document> document(GetTopLevelDocument());
-  RefPtr<nsPresContext> presContext =
-      document ? document->GetPresContext() : nullptr;
-  if (presContext) {
-    presContext->UIResolutionChangedSync();
-  }
 
   ScreenIntSize screenSize = GetInnerSize();
   if (mHasValidInnerSize && oldScreenSize != screenSize) {
     ScreenIntRect screenRect = GetOuterRect();
 
     // See RecvUpdateDimensions for the order of these operations.
     nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(WebNavigation());
     baseWin->SetPositionAndSize(0, 0, screenSize.width, screenSize.height,
                                 nsIBaseWindow::eRepaint);
 
     mPuppetWidget->Resize(screenRect.x + mClientOffset.x + mChromeOffset.x,
                           screenRect.y + mClientOffset.y + mChromeOffset.y,
                           screenSize.width, screenSize.height, true);
   }
 
+  nsCOMPtr<Document> document(GetTopLevelDocument());
+  RefPtr<nsPresContext> presContext =
+      document ? document->GetPresContext() : nullptr;
+  if (presContext) {
+    presContext->UIResolutionChangedSync();
+  }
+
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult BrowserChild::RecvSafeAreaInsetsChanged(
     const mozilla::ScreenIntMargin& aSafeAreaInsets) {
   mPuppetWidget->UpdateSafeAreaInsets(aSafeAreaInsets);
 
   nsCOMPtr<nsIScreenManager> screenMgr =
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -1975,17 +1975,17 @@ nsDocumentViewer::SetBoundsWithFlags(con
     mWindow->Resize(aBounds.x, aBounds.y, aBounds.width, aBounds.height, false);
   } else if (mPresContext && mViewManager) {
     // Ensure presContext's deviceContext is up to date, as we sometimes get
     // here before a resolution-change notification has been fully handled
     // during display configuration changes, especially when there are lots
     // of windows/widgets competing to handle the notifications.
     // (See bug 1154125.)
     if (mPresContext->DeviceContext()->CheckDPIChange()) {
-      mPresContext->UIResolutionChanged();
+      mPresContext->UIResolutionChangedSync();
     }
 
     int32_t p2a = mPresContext->AppUnitsPerDevPixel();
     nscoord width = NSIntPixelsToAppUnits(mBounds.width, p2a);
     nscoord height = NSIntPixelsToAppUnits(mBounds.height, p2a);
     nsView* rootView = mViewManager->GetRootView();
     if (boundsChanged && rootView) {
       nsRect viewDims = rootView->GetDimensions();
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -1750,18 +1750,22 @@ static void NotifyChildrenUIResolutionCh
 void nsPresContext::UIResolutionChangedInternal() {
   mPendingUIResolutionChanged = false;
 
   mDeviceContext->CheckDPIChange();
   if (mCurAppUnitsPerDevPixel != mDeviceContext->AppUnitsPerDevPixel()) {
     AppUnitsPerDevPixelChanged();
   }
 
-  if (GetPresShell()) {
-    GetPresShell()->RefreshZoomConstraintsForScreenSizeChange();
+  if (mPresShell) {
+    mPresShell->RefreshZoomConstraintsForScreenSizeChange();
+    if (RefPtr<MobileViewportManager> mvm =
+            mPresShell->GetMobileViewportManager()) {
+      mvm->UpdateSizesBeforeReflow();
+    }
   }
 
   // Recursively notify all remote leaf descendants of the change.
   if (nsPIDOMWindowOuter* window = mDocument->GetWindow()) {
     NotifyChildrenUIResolutionChanged(window);
   }
 
   auto recurse = [](dom::Document& aSubDoc) {