Bug 1515113. r=kats
authorTimothy Nikkel <tnikkel@gmail.com>
Tue, 08 Jan 2019 14:26:08 -0600
changeset 510077 1913de91fd89b55f07d5438f10d9af41a657bdb9
parent 510076 72c3b5930c7d65461a786922c1091907ae80abd7
child 510078 8d9995ade756ad7b55037dad3b6ef514319848cb
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1515113
milestone66.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 1515113. r=kats
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;
+  }
+
   if (SameCOMIdentity(aSubject, ToSupports(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(
@@ -339,16 +356,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.
@@ -357,24 +378,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->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).
       return;
@@ -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 =