Bug 1504233 - Part 1: Update container item ASR properly when hit test information is present r=mattwoodrow
authorMiko Mynttinen <mikokm@gmail.com>
Mon, 26 Nov 2018 20:14:09 +0000
changeset 504557 089d689d8eb5ed58ab0014858cdb44b15b7ff34d
parent 504556 9f6a7e664cef95703e629aa3fd02cd6a5b014f54
child 504558 bb579a94d0f69b239d897307ac9c81eb7f7a72ef
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1504233
milestone65.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 1504233 - Part 1: Update container item ASR properly when hit test information is present r=mattwoodrow Differential Revision: https://phabricator.services.mozilla.com/D12612
layout/painting/RetainedDisplayListBuilder.cpp
layout/painting/nsDisplayList.h
--- a/layout/painting/RetainedDisplayListBuilder.cpp
+++ b/layout/painting/RetainedDisplayListBuilder.cpp
@@ -230,31 +230,63 @@ AnyContentAncestorModified(nsIFrame* aFr
     if (aStopAtFrame && f == aStopAtFrame) {
       break;
     }
   }
 
   return false;
 }
 
+static Maybe<const ActiveScrolledRoot*>
+SelectContainerASR(const DisplayItemClipChain* aClipChain,
+                   const ActiveScrolledRoot* aItemASR,
+                   Maybe<const ActiveScrolledRoot*>& aContainerASR)
+{
+  const ActiveScrolledRoot* itemClipASR = aClipChain
+                                        ? aClipChain->mASR
+                                        : nullptr;
+
+  const ActiveScrolledRoot* finiteBoundsASR =
+    ActiveScrolledRoot::PickDescendant(itemClipASR, aItemASR);
+
+  if (!aContainerASR) {
+    return Some(finiteBoundsASR);
+  }
+
+  return Some(ActiveScrolledRoot::PickAncestor(
+    *aContainerASR, finiteBoundsASR));
+}
+
 static void
 UpdateASR(nsDisplayItem* aItem, Maybe<const ActiveScrolledRoot*>& aContainerASR)
 {
-  if (!aContainerASR) {
+  Maybe<const ActiveScrolledRoot*> asr;
+
+  if (aItem->HasHitTestInfo()) {
+    const HitTestInfo& info =
+      static_cast<nsDisplayHitTestInfoItem*>(aItem)->GetHitTestInfo();
+    asr = SelectContainerASR(info.mClipChain, info.mASR, aContainerASR);
+  } else {
+    asr = aContainerASR;
+  }
+
+  if (!asr) {
     return;
   }
 
   nsDisplayWrapList* wrapList = aItem->AsDisplayWrapList();
   if (!wrapList) {
-    aItem->SetActiveScrolledRoot(aContainerASR.value());
+    aItem->SetActiveScrolledRoot(*asr);
     return;
   }
 
   wrapList->SetActiveScrolledRoot(ActiveScrolledRoot::PickAncestor(
-    wrapList->GetFrameActiveScrolledRoot(), aContainerASR.value()));
+    wrapList->GetFrameActiveScrolledRoot(), *asr));
+
+  wrapList->UpdateHitTestInfoActiveScrolledRoot(*asr);
 }
 
 void
 OldItemInfo::AddedMatchToMergedList(RetainedDisplayListBuilder* aBuilder,
                                     MergedListIndex aIndex)
 {
   AddedToMergedList(aIndex);
 }
@@ -463,28 +495,18 @@ public:
 
   bool HasModifiedFrame(nsDisplayItem* aItem)
   {
     return AnyContentAncestorModified(aItem->FrameForInvalidation());
   }
 
   void UpdateContainerASR(nsDisplayItem* aItem)
   {
-    const ActiveScrolledRoot* itemClipASR =
-      aItem->GetClipChain() ? aItem->GetClipChain()->mASR : nullptr;
-
-    const ActiveScrolledRoot* finiteBoundsASR =
-      ActiveScrolledRoot::PickDescendant(itemClipASR,
-                                         aItem->GetActiveScrolledRoot());
-    if (!mContainerASR) {
-      mContainerASR = Some(finiteBoundsASR);
-    } else {
-      mContainerASR = Some(ActiveScrolledRoot::PickAncestor(
-        mContainerASR.value(), finiteBoundsASR));
-    }
+    mContainerASR = SelectContainerASR(
+      aItem->GetClipChain(), aItem->GetActiveScrolledRoot(), mContainerASR);
   }
 
   MergedListIndex AddNewNode(
     nsDisplayItem* aItem,
     const Maybe<OldListIndex>& aOldIndex,
     Span<const MergedListIndex> aDirectPredecessors,
     const Maybe<MergedListIndex>& aExtraDirectPredecessor)
   {
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -3914,16 +3914,36 @@ public:
   {
   }
 
   const HitTestInfo& GetHitTestInfo() const
   {
     return *mHitTestInfo;
   }
 
+  void SetActiveScrolledRoot(
+    const ActiveScrolledRoot* aActiveScrolledRoot) override
+  {
+    nsDisplayItem::SetActiveScrolledRoot(aActiveScrolledRoot);
+    UpdateHitTestInfoActiveScrolledRoot(aActiveScrolledRoot);
+  }
+
+  /**
+   * Updates mASR and mClip fields using the given |aActiveScrolledRoot|.
+   */
+  void UpdateHitTestInfoActiveScrolledRoot(
+    const ActiveScrolledRoot* aActiveScrolledRoot)
+  {
+    if (HasHitTestInfo()) {
+      mHitTestInfo->mASR = aActiveScrolledRoot;
+      mHitTestInfo->mClip = mozilla::DisplayItemClipChain::ClipForASR(
+        mHitTestInfo->mClipChain, mHitTestInfo->mASR);
+    }
+  }
+
   void SetHitTestInfo(mozilla::UniquePtr<HitTestInfo>&& aHitTestInfo)
   {
     MOZ_ASSERT(aHitTestInfo);
     MOZ_ASSERT(aHitTestInfo->mFlags !=
       mozilla::gfx::CompositorHitTestInvisibleToHit);
 
     mHitTestInfo = std::move(aHitTestInfo);
   }
@@ -5562,16 +5582,25 @@ public:
     // overflow rect of a frame for some reason (e.g. when setting up dirty
     // rects in nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay), but that
     // frame contains placeholders for out-of-flows that aren't descendants of
     // the frame.
     buildingRect.UnionRect(mBaseBuildingRect, buildingRect);
     SetBuildingRect(buildingRect);
   }
 
+  void SetActiveScrolledRoot(
+    const ActiveScrolledRoot* aActiveScrolledRoot) override
+  {
+    // Skip unnecessary call to
+    // |nsDisplayHitTestInfoItem::UpdateHitTestInfoActiveScrolledRoot()|, since
+    // callers will manually call that with different ASR.
+    nsDisplayItem::SetActiveScrolledRoot(aActiveScrolledRoot);
+  }
+
   void HitTest(nsDisplayListBuilder* aBuilder,
                const nsRect& aRect,
                HitTestState* aState,
                nsTArray<nsIFrame*>* aOutFrames) override;
   nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override;
   nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
                            bool* aSnap) const override;
   mozilla::Maybe<nscolor> IsUniform(
@@ -7166,17 +7195,17 @@ public:
     return mStoredList.GetChildren();
   }
 
   bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override;
 
   void SetActiveScrolledRoot(
     const ActiveScrolledRoot* aActiveScrolledRoot) override
   {
-    nsDisplayItem::SetActiveScrolledRoot(aActiveScrolledRoot);
+    nsDisplayHitTestInfoItem::SetActiveScrolledRoot(aActiveScrolledRoot);
     mStoredList.SetActiveScrolledRoot(aActiveScrolledRoot);
   }
 
   void HitTest(nsDisplayListBuilder* aBuilder,
                const nsRect& aRect,
                HitTestState* aState,
                nsTArray<nsIFrame*>* aOutFrames) override;
   nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override;
@@ -7642,17 +7671,17 @@ public:
   RetainedDisplayList* GetChildren() const override
   {
     return mList.GetChildren();
   }
 
   void SetActiveScrolledRoot(
     const ActiveScrolledRoot* aActiveScrolledRoot) override
   {
-    nsDisplayItem::SetActiveScrolledRoot(aActiveScrolledRoot);
+    nsDisplayHitTestInfoItem::SetActiveScrolledRoot(aActiveScrolledRoot);
     mList.SetActiveScrolledRoot(aActiveScrolledRoot);
   }
 
   nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) const override
   {
     return mList.GetComponentAlphaBounds(aBuilder);
   }