Bug 1515113. r=kats, a=RyanVM
authorTimothy Nikkel <tnikkel@gmail.com>
Wed, 09 Jan 2019 13:47:14 -0500
changeset 509374 d9cb99521a77d8d98fd423b959f8a7179750f5dd
parent 509373 e80c71637a6385d6b99dc4b35792edfa3ad171b1
child 509375 22d5885cacaec69aed4703b07a0cf63dbf0d1f23
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats, RyanVM
bugs1515113
milestone65.0
Bug 1515113. r=kats, a=RyanVM
layout/base/MobileViewportManager.cpp
--- a/layout/base/MobileViewportManager.cpp
+++ b/layout/base/MobileViewportManager.cpp
@@ -92,16 +92,20 @@ void MobileViewportManager::SetRestoreRe
   mRestoreDisplaySize = Some(restoreDisplaySize);
 }
 
 void MobileViewportManager::SetRestoreResolution(float aResolution) {
   mRestoreResolution = Some(aResolution);
 }
 
 float MobileViewportManager::ComputeIntrinsicResolution() const {
+  if (!mDocument || !mPresShell) {
+    return 1.f;
+  }
+
   ScreenIntSize displaySize = ViewAs<ScreenPixel>(
       mDisplaySize, PixelCastJustification::LayoutDeviceIsScreenForBounds);
   CSSToScreenScale intrinsicScale =
       ComputeIntrinsicScale(mDocument->GetViewportInfo(displaySize),
                             displaySize, mMobileViewportSize);
   CSSToLayoutDeviceScale cssToDev =
       mPresShell->GetPresContext()->CSSToDevPixelScale();
   return (intrinsicScale / cssToDev).scale;
@@ -119,16 +123,21 @@ mozilla::CSSToScreenScale MobileViewport
 
 void MobileViewportManager::RequestReflow() {
   MVM_LOG("%p: got a reflow request\n", this);
   RefreshViewportSize(false);
 }
 
 void MobileViewportManager::ResolutionUpdated() {
   MVM_LOG("%p: resolution updated\n", this);
+
+  if (!mPresShell) {
+    return;
+  }
+
   if (!mPainted) {
     // Save the value, so our default zoom calculation
     // can take it into account later on.
     SetRestoreResolution(mPresShell->GetResolution());
   }
   RefreshVisualViewportSize();
 }
 
@@ -154,16 +163,20 @@ MobileViewportManager::HandleEvent(dom::
     }
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MobileViewportManager::Observe(nsISupports* aSubject, const char* aTopic,
                                const char16_t* aData) {
+  if (!mDocument) {
+    return NS_OK;
+  }
+
   if (SameCOMIdentity(aSubject, mDocument) &&
       BEFORE_FIRST_PAINT.EqualsASCII(aTopic)) {
     MVM_LOG("%p: got a before-first-paint event\n", this);
     if (!mPainted) {
       // before-first-paint message arrived before load event
       SetInitialViewport();
     }
   }
@@ -217,16 +230,20 @@ static LayoutDeviceToLayerScale ZoomToRe
              aZoom, PixelCastJustification::ScreenIsParentLayerForRoot) /
          aCssToDev * ParentLayerToLayerScale(1);
 }
 
 void MobileViewportManager::UpdateResolution(
     const nsViewportInfo& aViewportInfo, const ScreenIntSize& aDisplaySize,
     const CSSSize& aViewportOrContentSize,
     const Maybe<float>& aDisplayWidthChangeRatio, UpdateType aType) {
+  if (!mPresShell || !mDocument) {
+    return;
+  }
+
   CSSToLayoutDeviceScale cssToDev =
       mPresShell->GetPresContext()->CSSToDevPixelScale();
   LayoutDeviceToLayerScale res(mPresShell->GetResolution());
   CSSToScreenScale zoom = ResolutionToZoom(res, cssToDev);
   Maybe<CSSToScreenScale> newZoom;
 
   ScreenIntSize compositionSize = GetCompositionSize(aDisplaySize);
   CSSToScreenScale intrinsicScale = ComputeIntrinsicScale(
@@ -338,16 +355,20 @@ void MobileViewportManager::UpdateResolu
   // and needs to be updated if either might have changed.
   if (newZoom || aType == UpdateType::ViewportSize) {
     UpdateVisualViewportSize(aDisplaySize, newZoom ? *newZoom : zoom);
   }
 }
 
 ScreenIntSize MobileViewportManager::GetCompositionSize(
     const ScreenIntSize& aDisplaySize) const {
+  if (!mPresShell) {
+    return ScreenIntSize();
+  }
+
   ScreenIntSize compositionSize(aDisplaySize);
   ScreenMargin scrollbars =
       LayoutDeviceMargin::FromAppUnits(
           nsLayoutUtils::ScrollbarAreaToExcludeFromCompositionBoundsFor(
               mPresShell->GetRootScrollFrame()),
           mPresShell->GetPresContext()->AppUnitsPerDevPixel())
       // Scrollbars are not subject to resolution scaling, so LD pixels =
       // Screen pixels for them.
@@ -356,24 +377,32 @@ ScreenIntSize MobileViewportManager::Get
   compositionSize.width -= scrollbars.LeftRight();
   compositionSize.height -= scrollbars.TopBottom();
 
   return compositionSize;
 }
 
 void MobileViewportManager::UpdateVisualViewportSize(
     const ScreenIntSize& aDisplaySize, const CSSToScreenScale& aZoom) {
+  if (!mPresShell) {
+    return;
+  }
+
   ScreenSize compositionSize = ScreenSize(GetCompositionSize(aDisplaySize));
 
   CSSSize compSize = compositionSize / aZoom;
   MVM_LOG("%p: Setting VVPS %s\n", this, Stringify(compSize).c_str());
   nsLayoutUtils::SetVisualViewportSize(mPresShell, compSize);
 }
 
 void MobileViewportManager::UpdateDisplayPortMargins() {
+  if (!mPresShell) {
+    return;
+  }
+
   if (nsIFrame* root = mPresShell->GetRootScrollFrame()) {
     bool hasDisplayPort = nsLayoutUtils::HasDisplayPort(root->GetContent());
     bool hasResolution =
         mPresShell->ScaleToResolution() && mPresShell->GetResolution() != 1.0f;
     if (!hasDisplayPort && !hasResolution) {
       // We only want to update the displayport if there is one already, or
       // add one if there's a resolution on the document (see bug 1225508
       // comment 1).
@@ -392,16 +421,20 @@ void MobileViewportManager::UpdateDispla
         scrollable, nsLayoutUtils::RepaintMode::DoNotRepaint);
   }
 }
 
 void MobileViewportManager::RefreshVisualViewportSize() {
   // This function is a subset of RefreshViewportSize, and only updates the
   // visual viewport size.
 
+  if (!mPresShell) {
+    return;
+  }
+
   if (!gfxPrefs::APZAllowZooming()) {
     return;
   }
 
   ScreenIntSize displaySize = ViewAs<ScreenPixel>(
       mDisplaySize, PixelCastJustification::LayoutDeviceIsScreenForBounds);
 
   CSSToLayoutDeviceScale cssToDev =
@@ -424,16 +457,20 @@ void MobileViewportManager::RefreshViewp
   // separately for each trigger that changes. For instance it should never get
   // called such that both the full zoom and the meta-viewport tag have changed;
   // instead it would get called twice - once after each trigger changes. This
   // assumption is what allows the aForceAdjustResolution parameter to work as
   // intended; if this assumption is violated then we will need to add extra
   // complicated logic in UpdateResolution to ensure we only do the resolution
   // update in the right scenarios.
 
+  if (!mPresShell || !mDocument) {
+    return;
+  }
+
   Maybe<float> displayWidthChangeRatio;
   LayoutDeviceIntSize newDisplaySize;
   if (nsLayoutUtils::GetContentViewerSize(mPresShell->GetPresContext(),
                                           newDisplaySize)) {
     // See the comment in UpdateResolution for why we're doing this.
     if (mDisplaySize.width > 0) {
       if (aForceAdjustResolution ||
           mDisplaySize.width != newDisplaySize.width) {
@@ -481,32 +518,38 @@ void MobileViewportManager::RefreshViewp
     UpdateDisplayPortMargins();
   }
 
   CSSSize oldSize = mMobileViewportSize;
 
   // Update internal state.
   mMobileViewportSize = viewport;
 
+  RefPtr<MobileViewportManager> strongThis(this);
+
   // Kick off a reflow.
   mPresShell->ResizeReflowIgnoreOverride(
       nsPresContext::CSSPixelsToAppUnits(viewport.width),
       nsPresContext::CSSPixelsToAppUnits(viewport.height),
       nsPresContext::CSSPixelsToAppUnits(oldSize.width),
       nsPresContext::CSSPixelsToAppUnits(oldSize.height));
 
   // We are going to fit the content to the display width if the initial-scale
   // is not specied and if the content is still wider than the display width.
   ShrinkToDisplaySizeIfNeeded(viewportInfo, displaySize);
 
   mIsFirstPaint = false;
 }
 
 void MobileViewportManager::ShrinkToDisplaySizeIfNeeded(
     nsViewportInfo& aViewportInfo, const ScreenIntSize& aDisplaySize) {
+  if (!mPresShell) {
+    return;
+  }
+
   if (!gfxPrefs::APZAllowZooming()) {
     // If the APZ is disabled, we don't scale down wider contents to fit them
     // into device screen because users won't be able to zoom out the tiny
     // contents.
     return;
   }
 
   nsIScrollableFrame* rootScrollableFrame =