Bug 1521644 - Trigger a full display list rebuild when transition to or from using an async zoom container. r=mattwoodrow
authorBotond Ballo <botond@mozilla.com>
Fri, 01 Feb 2019 18:30:28 +0000
changeset 456492 352baaa37697490a3604e8725610e273b2744a0e
parent 456491 edb058a84ce446ba6fd4b5b4a26dfb21b12ed9d2
child 456493 50ed1bfe7f5ae5bd0edf65eeadbb6165845442fc
push id111656
push userdvarga@mozilla.com
push dateSat, 02 Feb 2019 09:51:54 +0000
treeherdermozilla-inbound@d8cebb3b46cf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1521644
milestone67.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 1521644 - Trigger a full display list rebuild when transition to or from using an async zoom container. r=mattwoodrow Differential Revision: https://phabricator.services.mozilla.com/D17168
layout/base/nsLayoutUtils.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/painting/nsDisplayList.cpp
layout/painting/nsDisplayList.h
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -3608,20 +3608,34 @@ nsresult nsLayoutUtils::PaintFrame(gfxCo
       builder.SetAncestorHasApzAwareEventHandler(
           gfxPlatform::AsyncPanZoomEnabled() &&
           nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(presShell));
 
       DisplayListChecker beforeMergeChecker;
       DisplayListChecker toBeMergedChecker;
       DisplayListChecker afterMergeChecker;
 
+      // If we transition between wrapping the RCD-RSF contents into an async
+      // zoom container vs. not, we need to rebuild the display list. This only
+      // happens when the zooming or container scrolling prefs are toggled
+      // (manually by the user, or during test setup).
+      bool shouldAttemptPartialUpdate = useRetainedBuilder;
+      bool didBuildAsyncZoomContainer = builder.ShouldBuildAsyncZoomContainer();
+      builder.SetBuildAsyncZoomContainer(
+          gfxPrefs::APZAllowZooming() &&
+          !gfxPrefs::LayoutUseContainersForRootFrames());
+      if (builder.ShouldBuildAsyncZoomContainer() !=
+          didBuildAsyncZoomContainer) {
+        shouldAttemptPartialUpdate = false;
+      }
+
       // Attempt to do a partial build and merge into the existing list.
       // This calls BuildDisplayListForStacking context on a subset of the
       // viewport.
-      if (useRetainedBuilder) {
+      if (shouldAttemptPartialUpdate) {
         if (gfxPrefs::LayoutVerifyRetainDisplayList()) {
           beforeMergeChecker.Set(&list, "BM");
         }
         updateState = retainedBuilder->AttemptPartialUpdate(
             aBackstop, beforeMergeChecker ? &toBeMergedChecker : nullptr);
         if ((updateState != PartialUpdateResult::Failed) &&
             beforeMergeChecker) {
           afterMergeChecker.Set(&list, "AM");
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -3441,18 +3441,17 @@ void ScrollFrameHelper::BuildDisplayList
         contentBoxClip = Some(inflatedClip);
       }
     }
   }
 
   nsDisplayListCollection set(aBuilder);
 
   bool willBuildAsyncZoomContainer =
-      gfxPrefs::APZAllowZooming() &&
-      !gfxPrefs::LayoutUseContainersForRootFrames() && mIsRoot &&
+      aBuilder->ShouldBuildAsyncZoomContainer() && mIsRoot &&
       mOuter->PresContext()->IsRootContentDocument();
 
   nsRect scrollPortClip = mScrollPort + aBuilder->ToReferenceFrame(mOuter);
   nsRect clipRect = scrollPortClip;
   // Our override of GetBorderRadii ensures we never have a radius at
   // the corners where we have a scrollbar.
   nscoord radii[8];
   bool haveRadii = mOuter->GetPaddingBoxBorderRadii(radii);
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -1037,16 +1037,17 @@ nsDisplayListBuilder::nsDisplayListBuild
       mAsyncPanZoomEnabled(nsLayoutUtils::AsyncPanZoomEnabled(aReferenceFrame)),
       mBuildingInvisibleItems(false),
       mHitTestIsForVisibility(false),
       mIsBuilding(false),
       mInInvalidSubtree(false),
       mDisablePartialUpdates(false),
       mPartialBuildFailed(false),
       mIsInActiveDocShell(false),
+      mBuildAsyncZoomContainer(false),
       mHitTestArea(),
       mHitTestInfo(CompositorHitTestInvisibleToHit) {
   MOZ_COUNT_CTOR(nsDisplayListBuilder);
 
   mBuildCompositorHitTestInfo = mAsyncPanZoomEnabled && IsForPainting();
 
   static_assert(
       static_cast<uint32_t>(DisplayItemType::TYPE_MAX) < (1 << TYPE_BITS),
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -1728,16 +1728,23 @@ class nsDisplayListBuilder {
       const ActiveScrolledRoot* aASR);
 
   bool HitTestIsForVisibility() const { return mHitTestIsForVisibility; }
 
   void SetHitTestIsForVisibility(bool aHitTestIsForVisibility) {
     mHitTestIsForVisibility = aHitTestIsForVisibility;
   }
 
+  bool ShouldBuildAsyncZoomContainer() const {
+    return mBuildAsyncZoomContainer;
+  }
+  void SetBuildAsyncZoomContainer(bool aBuildAsyncZoomContainer) {
+    mBuildAsyncZoomContainer = aBuildAsyncZoomContainer;
+  }
+
   /**
    * Represents a region composed of frame/rect pairs.
    * WeakFrames are used to track whether a rect still belongs to the region.
    * Modified frames and rects are removed and re-added to the region if needed.
    */
   struct WeakFrameRegion {
     /**
      * A wrapper to store WeakFrame and the pointer to the underlying frame.
@@ -1983,16 +1990,17 @@ class nsDisplayListBuilder {
   bool mBuildingInvisibleItems;
   bool mHitTestIsForVisibility;
   bool mIsBuilding;
   bool mInInvalidSubtree;
   bool mBuildCompositorHitTestInfo;
   bool mDisablePartialUpdates;
   bool mPartialBuildFailed;
   bool mIsInActiveDocShell;
+  bool mBuildAsyncZoomContainer;
 
   nsRect mHitTestArea;
   CompositorHitTestInfo mHitTestInfo;
 };
 
 class nsDisplayItem;
 class nsDisplayList;
 class RetainedDisplayList;