commit b75b0abc10eaa46764969a84a71342aa02dfefdc
parent e68671efd8c8e76073e6a9e5c61afad383b62ce1
Author: Alexandru Marc <amarc@mozilla.com>
Date: Wed, 26 Nov 2025 15:39:03 +0200
Revert (Bug 1988032, Bug 1988030) for causing build bustages @ DisplayPortUtils.cpp
This reverts commit 8244ecad8b53e9475d89f635869d12b714c62208.
Revert "Bug 1988032. Disable RDL if are there active CSS anchor pos. r=layout-reviewers,emilio"
This reverts commit 9063b3c208f7f5cc99cf105a6df4d9911fb7d4f7.
Revert "Bug 1988032. Don't async scroll with anchors if there is an active view transition. r=layout-reviewers,emilio"
This reverts commit 472901d51347a44527c2ed4166b55f3b728fb52d.
Revert "Bug 1988030. Detect and reject an anchor that is outside of the positioned frame's containing block. r=layout-reviewers,emilio"
This reverts commit 237e8563f6569f547c6c7fe47ce6997726c0d38b.
Revert "Bug 1988032. Add a pref to control async scroll of CSS anchor positioned content. r=layout-reviewers,hiro"
This reverts commit 98d14e2dc81960e63ae50bceab379450f0b0c5d9.
Revert "Bug 1988032. Add some basic anchor pos plus async scroll reftests. r=hiro,layout-reviewers"
This reverts commit 7165d46e3b2405fcbe87188998e20af6b3c56b7d.
Revert "Bug 1988032. Assign the ASR of the anchor to the anchored content. r=hiro,layout-reviewers,layout-anchor-positioning-reviewers,emilio"
This reverts commit cb45424f429d3618455071440543c3b5423190b4.
Revert "Bug 1988030. Create a function that activates and creates ASRs for scrollframes of the anchor of anchored content. r=hiro,layout-reviewers,layout-anchor-positioning-reviewers,botond,emilio"
This reverts commit 1816a3d49caa602d49af77c9a99b2c0325c31521.
Revert "Bug 1988030. Allow passing a limit ancestor to DisplayPortUtils::OneStepInASRChain that we don't walk past. r=hiro,layout-reviewers"
This reverts commit 7cd59a61c6a01fdd88254a2d880191ebcd3865ab.
Revert "Bug 1988030. Create nsLayoutUtils::GetASRAncestorFrame and OneStepInASRChain that walks only scroll frames that are currently async scrollable in the ASR order. r=botond,hiro,layout-reviewers,layout-anchor-positioning-reviewers,emilio"
This reverts commit e53645f574d4cccad40a679ab9cb3cf0fbbcf110.
Revert "Bug 1988030. Adjust DisplayPortUtils::OneStepInAsyncScrollableAncestorChain to be CSS anchor pos aware. r=hiro,layout-reviewers,layout-anchor-positioning-reviewers,emilio"
This reverts commit e7619a7efccc6f2ca258a9f3cdf4cc1d8741ede4.
Revert "Bug 1988030. Adjust nsLayoutUtils::GetAsyncScrollableAncestorFrame to be CSS anchor pos aware. r=layout-reviewers,layout-anchor-positioning-reviewers,hiro,emilio"
This reverts commit 537725a5c4aaa5e36df125f308024c54b1eb6fda.
Diffstat:
20 files changed, 17 insertions(+), 836 deletions(-)
diff --git a/layout/base/AnchorPositioningUtils.cpp b/layout/base/AnchorPositioningUtils.cpp
@@ -9,7 +9,6 @@
#include "ScrollContainerFrame.h"
#include "mozilla/Maybe.h"
#include "mozilla/PresShell.h"
-#include "mozilla/StaticPrefs_apz.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/Element.h"
#include "nsCanvasFrame.h"
@@ -875,33 +874,4 @@ bool AnchorPositioningUtils::FitsInContainingBlock(
.Contains(rect);
}
-nsIFrame* AnchorPositioningUtils::GetAnchorThatFrameScrollsWith(
- nsIFrame* aFrame) {
- if (!StaticPrefs::apz_async_scroll_css_anchor_pos_AtStartup()) {
- return nullptr;
- }
- mozilla::PhysicalAxes axes = aFrame->GetAnchorPosCompensatingForScroll();
- // TODO for now we return the anchor if we are compensating in either axis.
- // This is not fully spec compliant, bug 1988034 tracks this.
- if (axes.isEmpty()) {
- return nullptr;
- }
-
- const auto* pos = aFrame->StylePosition();
- if (!pos->mPositionAnchor.IsIdent()) {
- return nullptr;
- }
-
- const nsAtom* defaultAnchorName = pos->mPositionAnchor.AsIdent().AsAtom();
- nsIFrame* anchor = const_cast<nsIFrame*>(
- aFrame->PresShell()->GetAnchorPosAnchor(defaultAnchorName, aFrame));
- // TODO Bug 1997026 We need to update the anchor finding code so this can't
- // happen. For now we just detect it and reject it.
- if (anchor && !nsLayoutUtils::IsProperAncestorFrameConsideringContinuations(
- aFrame->GetParent(), anchor)) {
- return nullptr;
- }
- return anchor;
-}
-
} // namespace mozilla
diff --git a/layout/base/AnchorPositioningUtils.h b/layout/base/AnchorPositioningUtils.h
@@ -309,12 +309,6 @@ struct AnchorPositioningUtils {
const ContainingBlockInfo& aContainingBlockInfo,
const nsIFrame* aPositioned,
const AnchorPosReferenceData* aReferenceData);
-
- /**
- * If aFrame is positioned using CSS anchor positioning, and it scrolls with
- * its anchor this function returns the anchor. Otherwise null.
- */
- static nsIFrame* GetAnchorThatFrameScrollsWith(nsIFrame* aFrame);
};
} // namespace mozilla
diff --git a/layout/base/DisplayPortUtils.cpp b/layout/base/DisplayPortUtils.cpp
@@ -10,7 +10,6 @@
#include "FrameMetrics.h"
#include "RetainedDisplayListBuilder.h"
-#include "StickyScrollContainer.h"
#include "WindowRenderer.h"
#include "mozilla/PresShell.h"
#include "mozilla/ScrollContainerFrame.h"
@@ -734,22 +733,6 @@ void DisplayPortUtils::RemoveDisplayPort(nsIContent* aContent) {
aContent->RemoveProperty(nsGkAtoms::DisplayPortMargins);
}
-void DisplayPortUtils::SetMinimalDisplayPortDuringPainting(
- nsIContent* aContent, PresShell* aPresShell) {
- // SetDisplayPortMargins calls TriggerDisplayPortExpiration which starts a
- // display port expiry timer for display ports that do expire. However
- // minimal display ports do not expire, so the display port has to be
- // marked before the SetDisplayPortMargins call so the expiry timer
- // doesn't get started.
- aContent->SetProperty(nsGkAtoms::MinimalDisplayPort,
- reinterpret_cast<void*>(true));
-
- DisplayPortUtils::SetDisplayPortMargins(
- aContent, aPresShell, DisplayPortMargins::Empty(aContent),
- DisplayPortUtils::ClearMinimalDisplayPortProperty::No, 0,
- DisplayPortUtils::RepaintMode::DoNotRepaint);
-}
-
bool DisplayPortUtils::ViewportHasDisplayPort(nsPresContext* aPresContext) {
nsIFrame* rootScrollContainerFrame =
aPresContext->PresShell()->GetRootScrollContainerFrame();
@@ -851,18 +834,9 @@ bool DisplayPortUtils::MaybeCreateDisplayPort(
nsIFrame* DisplayPortUtils::OneStepInAsyncScrollableAncestorChain(
nsIFrame* aFrame) {
- // This mirrors one iteration of GetNearestScrollableOrOverflowClipFrame in
- // nsLayoutUtils.cpp as called by
- // nsLayoutUtils::GetAsyncScrollableAncestorFrame. They should be kept in
- // sync. See that function for comments about the structure of this code.
if (aFrame->IsMenuPopupFrame()) {
return nullptr;
}
- nsIFrame* anchor = nullptr;
- while ((anchor =
- AnchorPositioningUtils::GetAnchorThatFrameScrollsWith(aFrame))) {
- aFrame = anchor;
- }
if (aFrame->StyleDisplay()->mPosition == StylePositionProperty::Fixed &&
nsLayoutUtils::IsReallyFixedPos(aFrame)) {
if (nsIFrame* root = aFrame->PresShell()->GetRootScrollContainerFrame()) {
@@ -872,32 +846,6 @@ nsIFrame* DisplayPortUtils::OneStepInAsyncScrollableAncestorChain(
return nsLayoutUtils::GetCrossDocParentFrameInProcess(aFrame);
}
-nsIFrame* DisplayPortUtils::OneStepInASRChain(
- nsIFrame* aFrame, nsIFrame* aLimitAncestor /* = nullptr */) {
- // This mirrors one iteration of GetNearestScrollableOrOverflowClipFrame in
- // nsLayoutUtils.cpp as called by nsLayoutUtils::GetASRAncestorFrame. They
- // should be kept in sync. See that function for comments about the structure
- // of this code.
- if (aFrame->IsMenuPopupFrame()) {
- return nullptr;
- }
- nsIFrame* anchor = nullptr;
- while ((anchor =
- AnchorPositioningUtils::GetAnchorThatFrameScrollsWith(aFrame))) {
- MOZ_ASSERT_IF(aLimitAncestor,
- nsLayoutUtils::IsProperAncestorFrameConsideringContinuations(
- aLimitAncestor, anchor));
- aFrame = anchor;
- }
- nsIFrame* parent = nsLayoutUtils::GetCrossDocParentFrameInProcess(aFrame);
- if (aLimitAncestor && parent &&
- (parent == aLimitAncestor ||
- parent->FirstContinuation() == aLimitAncestor->FirstContinuation())) {
- return nullptr;
- }
- return parent;
-}
-
void DisplayPortUtils::SetZeroMarginDisplayPortOnAsyncScrollableAncestors(
nsIFrame* aFrame) {
nsIFrame* frame = aFrame;
@@ -1062,127 +1010,4 @@ bool DisplayPortUtils::WillUseEmptyDisplayPortMargins(nsIContent* aContent) {
nsLayoutUtils::ShouldDisableApzForElement(aContent);
}
-// This first checks if aFrame is a scroll frame, if so it then tries to
-// activate it. Then this function returns true if aFrame generates a scroll ASR
-// (ie its an active scroll frame).
-static bool ActivatePotentialScrollASR(nsIFrame* aFrame,
- nsDisplayListBuilder* aBuilder) {
- ScrollContainerFrame* scrollContainerFrame = do_QueryFrame(aFrame);
- if (!scrollContainerFrame) {
- return false;
- }
- return scrollContainerFrame->DecideScrollableLayerEnsureDisplayport(aBuilder);
-}
-
-// This first checks if aFrame is sticky pos, if so it then tries to activate
-// the associate scroll frame. Then this function returns true if aFrame
-// generates a sticky ASR (ie its sticky pos and its associated scroll frame is
-// active).
-static bool ActivatePotentialStickyASR(nsIFrame* aFrame,
- nsDisplayListBuilder* aBuilder) {
- if (aFrame->StyleDisplay()->mPosition != StylePositionProperty::Sticky) {
- return false;
- }
- auto* ssc = StickyScrollContainer::GetOrCreateForFrame(aFrame);
- if (!ssc) {
- return false;
- }
- return ssc->ScrollContainer()->DecideScrollableLayerEnsureDisplayport(
- aBuilder);
-}
-
-struct FrameAndASRKind {
- nsIFrame* mFrame;
- ActiveScrolledRoot::ASRKind mASRKind;
-};
-
-const ActiveScrolledRoot* DisplayPortUtils::ActivateDisplayportOnASRAncestors(
- nsIFrame* aAnchor, nsIFrame* aLimitAncestor,
- const ActiveScrolledRoot* aASRofLimitAncestor,
- nsDisplayListBuilder* aBuilder) {
- MOZ_ASSERT(ScrollContainerFrame::ShouldActivateAllScrollFrames(
- aBuilder, aLimitAncestor));
-
- MOZ_ASSERT((aASRofLimitAncestor ? aASRofLimitAncestor->mFrame : nullptr) ==
- nsLayoutUtils::GetASRAncestorFrame(aLimitAncestor, aBuilder));
-
- MOZ_ASSERT(nsLayoutUtils::IsProperAncestorFrameConsideringContinuations(
- aLimitAncestor, aAnchor));
-
- AutoTArray<FrameAndASRKind, 4> ASRframes;
- nsIFrame* frame = aAnchor;
-
- // The passed in frame is the anchor, if it is a scroll frame we do not scroll
- // with that scroll frame (we are "outside" of it) but if it is sticky pos
- // then we do move with the sticky ASR.
- if (ActivatePotentialStickyASR(frame, aBuilder)) {
- ASRframes.EmplaceBack(frame, ActiveScrolledRoot::ASRKind::Sticky);
- }
- frame = OneStepInASRChain(frame, aLimitAncestor);
- while (frame && frame != aLimitAncestor &&
- (!aLimitAncestor ||
- frame->FirstContinuation() != aLimitAncestor->FirstContinuation())) {
- // We check if each frame encountered generates an ASR. It can either
- // generate a scroll asr or a sticky asr, or both! If it generates both then
- // the sticky asr is the outer (parent) asr. So we check for scroll ASRs
- // first.
-
- // We intentionally call this on all scroll frames encountered, not just the
- // ones that WantAsyncScroll. This is because scroll frames with
- // WantAsyncScroll == false can have a display port (say if they had
- // non-zero scroll range and had a display port but then their scroll range
- // shrank to zero then the displayport would still stick around), hence
- // mWillBuildScrollableLayer would be true on them and we need to make sure
- // mWillBuildScrollableLayer is up to date (if the scroll frame was
- // temporarily inside a view transition mWillBuildScrollableLayer would
- // temporarily get set to false).
-
- // In this loop we are looking for any scroll frame that will generate an
- // ASR. This corresponds to scroll frames with mWillBuildScrollableLayer ==
- // true. This is different from scroll frames that return true from
- // WantAsyncScroll (both because of what was explained above and because not
- // every scroll frame that WantAsyncScroll will have a displayport), and
- // hence it's also different from what GetAsyncScrollableAncestorFrame will
- // return.
- if (ActivatePotentialScrollASR(frame, aBuilder)) {
- ASRframes.EmplaceBack(frame, ActiveScrolledRoot::ASRKind::Scroll);
- }
-
- // Then check if it's a sticky ASR.
- if (ActivatePotentialStickyASR(frame, aBuilder)) {
- ASRframes.EmplaceBack(frame, ActiveScrolledRoot::ASRKind::Sticky);
- }
-
- frame = OneStepInASRChain(frame, aLimitAncestor);
- }
-
- const ActiveScrolledRoot* asr = aASRofLimitAncestor;
-
- // Iterate array in reverse order (top down in the frame/asr tree) creating
- // the asr structs.
- for (auto asrFrame : Reversed(ASRframes)) {
- MOZ_ASSERT(nsLayoutUtils::IsProperAncestorFrameConsideringContinuations(
- aLimitAncestor, asrFrame.mFrame));
-
-#ifdef DEBUG
- if (asr && (asr->mFrame == asrFrame.mFrame)) {
- MOZ_ASSERT(asr->mKind == ActiveScrolledRoot::ASRKind::Sticky);
- MOZ_ASSERT(asrFrame.mASRKind == ActiveScrolledRoot::ASRKind::Scroll);
- } else {
- MOZ_ASSERT((asr ? asr->mFrame : nullptr) ==
- nsLayoutUtils::GetASRAncestorFrame(
- OneStepInASRChain(asrFrame.mFrame), aBuilder));
- }
-#endif
-
- asr = (asrFrame.mASRKind == ActiveScrolledRoot::ASRKind::Scroll)
- ? aBuilder->GetOrCreateActiveScrolledRoot(
- asr, static_cast<ScrollContainerFrame*>(
- do_QueryFrame(asrFrame.mFrame)))
- : aBuilder->GetOrCreateActiveScrolledRootForSticky(
- asr, asrFrame.mFrame);
- }
- return asr;
-}
-
} // namespace mozilla
diff --git a/layout/base/DisplayPortUtils.h b/layout/base/DisplayPortUtils.h
@@ -238,12 +238,6 @@ class DisplayPortUtils {
static void RemoveDisplayPort(nsIContent* aContent);
/**
- * Set minimal display port margins during painting.
- */
- static void SetMinimalDisplayPortDuringPainting(nsIContent* aContent,
- PresShell* aPresShell);
-
- /**
* Return true if aPresContext's viewport has a displayport.
*/
static bool ViewportHasDisplayPort(nsPresContext* aPresContext);
@@ -295,18 +289,6 @@ class DisplayPortUtils {
static nsIFrame* OneStepInAsyncScrollableAncestorChain(nsIFrame* aFrame);
/**
- * Step up one frame in the ASR chain, to be used in conjunction with
- * GetASRAncestorFrame to walk the ASR chain. Note this doesn't go from one
- * ASR frame to the next. Rather this walks all frame types, taking only one
- * ancestor step per call. Note that a frame returned from this function could
- * generate two ASRs: an inner one corresponding to an activated scroll frame,
- * and an outer one corresponding to sticky pos. Returns null if we hit
- * aLimitAncestor.
- */
- static nsIFrame* OneStepInASRChain(nsIFrame* aFrame,
- nsIFrame* aLimitAncestor = nullptr);
-
- /**
* Sets a zero margin display port on all proper ancestors of aFrame that
* are async scrollable.
*/
@@ -338,23 +320,6 @@ class DisplayPortUtils {
* of displayports.
*/
static bool WillUseEmptyDisplayPortMargins(nsIContent* aContent);
-
- /**
- * Calls DecideScrollableLayerEnsureDisplayport on all proper ancestors of
- * aAnchor that are async scrollable up to but not including aLimitAncestor
- * (this creates a minimal display port on all async scrollable ancestors if
- * they don't have a display port) and makes sure that there is an ASR struct
- * created for all such async scrollable ancestors.
- * Returns the ASR of aAnchor.
- * This is a very specific function for anchor positioning and likely not
- * what you want. In that context, aAnchor is the anchor of an abspos frame f
- * (not passed to this function because it is not needed) and aLimitAncestor
- * is the parent/containing block of f.
- */
- static const ActiveScrolledRoot* ActivateDisplayportOnASRAncestors(
- nsIFrame* aAnchor, nsIFrame* aLimitAncestor,
- const ActiveScrolledRoot* aASRofLimitAncestor,
- nsDisplayListBuilder* aBuilder);
};
} // namespace mozilla
diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp
@@ -10,7 +10,6 @@
#include <limits>
#include "ActiveLayerTracker.h"
-#include "AnchorPositioningUtils.h"
#include "DisplayItemClip.h"
#include "ImageContainer.h"
#include "ImageOps.h"
@@ -1318,11 +1317,6 @@ static nsIFrame* GetNearestScrollableOrOverflowClipFrame(
MOZ_ASSERT(
aFrame,
"GetNearestScrollableOrOverflowClipFrame expects a non-null frame");
- // Only one of these two flags can be set at a time.
- MOZ_ASSERT_IF(aFlags & nsLayoutUtils::SCROLLABLE_ONLY_ASYNC_SCROLLABLE,
- !(aFlags & nsLayoutUtils::SCROLLABLE_ONLY_ASRS));
- MOZ_ASSERT_IF(aFlags & nsLayoutUtils::SCROLLABLE_ONLY_ASRS,
- !(aFlags & nsLayoutUtils::SCROLLABLE_ONLY_ASYNC_SCROLLABLE));
auto GetNextFrame = [aFlags](const nsIFrame* aFrame) -> nsIFrame* {
return (aFlags & nsLayoutUtils::SCROLLABLE_SAME_DOC)
@@ -1330,9 +1324,6 @@ static nsIFrame* GetNearestScrollableOrOverflowClipFrame(
: nsLayoutUtils::GetCrossDocParentFrameInProcess(aFrame);
};
- // This should be kept in sync with
- // DisplayPortUtils::OneStepInAsyncScrollableAncestorChain and
- // DisplayPortUtils::OneStepInASRChain.
for (nsIFrame* f = aFrame; f; f = GetNextFrame(f)) {
if (aClipFrameCheck && aClipFrameCheck(f)) {
return f;
@@ -1344,8 +1335,7 @@ static nsIFrame* GetNearestScrollableOrOverflowClipFrame(
// TODO: We should also stop at popup frames other than
// SCROLLABLE_ONLY_ASYNC_SCROLLABLE cases.
- if ((aFlags & (nsLayoutUtils::SCROLLABLE_ONLY_ASYNC_SCROLLABLE |
- nsLayoutUtils::SCROLLABLE_ONLY_ASRS)) &&
+ if ((aFlags & nsLayoutUtils::SCROLLABLE_ONLY_ASYNC_SCROLLABLE) &&
f->IsMenuPopupFrame()) {
break;
}
@@ -1355,10 +1345,6 @@ static nsIFrame* GetNearestScrollableOrOverflowClipFrame(
if (scrollContainerFrame->WantAsyncScroll()) {
return f;
}
- } else if (aFlags & nsLayoutUtils::SCROLLABLE_ONLY_ASRS) {
- if (scrollContainerFrame->IsMaybeAsynchronouslyScrolled()) {
- return f;
- }
} else {
ScrollStyles ss = scrollContainerFrame->GetScrollStyles();
if ((aFlags & nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN) ||
@@ -1376,45 +1362,6 @@ static nsIFrame* GetNearestScrollableOrOverflowClipFrame(
}
}
}
-
- nsIFrame* anchor = nullptr;
- // If the current frame also happens to be fixed then we want to check if it
- // scrolls with its anchor before the special fixed behaviour below because
- // scrolling with its anchor overrides that behaviour and is higher
- // priority.
-
- // This needs to be a while loop because anchors can chain, and we don't
- // want to consider each frame in this loop separately (as a potential
- // scrollable ancestor) because they are all equivalent in the scrollable
- // ancestor chain: they all scroll together. We are not walking up the async
- // scrollable ancestor chain, but rather we are move sideways. And when we
- // exit this loop we want to move up one because we haven't yet ascended
- // (because of that same reason), and that moving up one will happen either
- // via the special fixed pos behaviour below or the next iteration of the
- // outer for loop.
- if (aFlags & (nsLayoutUtils::SCROLLABLE_ONLY_ASYNC_SCROLLABLE |
- nsLayoutUtils::SCROLLABLE_ONLY_ASRS)) {
- while (
- (anchor = AnchorPositioningUtils::GetAnchorThatFrameScrollsWith(f))) {
- f = anchor;
- }
- }
-
- // Note that the order of checking for anchors and sticky pos is significant
- // even though a frame can't be both sticky pos and anchored (because
- // anchoring requires abs pos). However, if we follow an anchor, the anchor
- // could be an active sticky pos, so that would generate an ASR and we want
- // to return that rather than do another iteration of the outer for loop
- // which moves on to the (crossdoc) parent frame.
- if (aFlags & nsLayoutUtils::SCROLLABLE_ONLY_ASRS) {
- if (f->StyleDisplay()->mPosition == StylePositionProperty::Sticky) {
- auto* ssc = StickyScrollContainer::GetOrCreateForFrame(f);
- if (ssc && ssc->ScrollContainer()->IsMaybeAsynchronouslyScrolled()) {
- return f;
- }
- }
- }
-
if ((aFlags & nsLayoutUtils::SCROLLABLE_FIXEDPOS_FINDS_ROOT) &&
f->StyleDisplay()->mPosition == StylePositionProperty::Fixed &&
nsLayoutUtils::IsReallyFixedPos(f)) {
@@ -1429,10 +1376,6 @@ static nsIFrame* GetNearestScrollableOrOverflowClipFrame(
// static
ScrollContainerFrame* nsLayoutUtils::GetNearestScrollContainerFrame(
nsIFrame* aFrame, uint32_t aFlags) {
- // Not suitable to use SCROLLABLE_ONLY_ASRS here because it needs to return
- // non-scroll frames.
- MOZ_ASSERT(!(aFlags & SCROLLABLE_ONLY_ASRS),
- "can't use SCROLLABLE_ONLY_ASRS flag");
nsIFrame* found = GetNearestScrollableOrOverflowClipFrame(aFrame, aFlags);
if (!found) {
return nullptr;
@@ -2653,29 +2596,12 @@ FrameMetrics nsLayoutUtils::CalculateBasicFrameMetrics(
ScrollContainerFrame* nsLayoutUtils::GetAsyncScrollableAncestorFrame(
nsIFrame* aTarget) {
- // This should be kept in sync with
- // DisplayPortUtils::OneStepInAsyncScrollableAncestorChain.
uint32_t flags = nsLayoutUtils::SCROLLABLE_ALWAYS_MATCH_ROOT |
nsLayoutUtils::SCROLLABLE_ONLY_ASYNC_SCROLLABLE |
nsLayoutUtils::SCROLLABLE_FIXEDPOS_FINDS_ROOT;
return nsLayoutUtils::GetNearestScrollContainerFrame(aTarget, flags);
}
-nsIFrame* nsLayoutUtils::GetASRAncestorFrame(nsIFrame* aTarget,
- nsDisplayListBuilder* aBuilder) {
- MOZ_ASSERT(aBuilder->IsPaintingToWindow());
- // We use different flags from GetAsyncScrollableAncestorFrame above because
- // the ASR tree is different from the "async scrollable ancestor chain". We
- // don't want SCROLLABLE_ALWAYS_MATCH_ROOT because we only want to match the
- // root if it generates an ASR. We don't want SCROLLABLE_FIXEDPOS_FINDS_ROOT
- // because the ASR tree does not jump from fixed pos to root (that behaviour
- // exists so that fixed pos in the root document in the process can find some
- // apzc, ASRs have no such need and that would be incorrect).
- // This should be kept in sync with DisplayPortUtils::OneStepInASRChain.
- uint32_t flags = nsLayoutUtils::SCROLLABLE_ONLY_ASRS;
- return GetNearestScrollableOrOverflowClipFrame(aTarget, flags);
-}
-
void nsLayoutUtils::AddExtraBackgroundItems(nsDisplayListBuilder* aBuilder,
nsDisplayList* aList,
nsIFrame* aFrame,
diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h
@@ -603,22 +603,12 @@ class nsLayoutUtils {
*/
SCROLLABLE_FIXEDPOS_FINDS_ROOT = 0x10,
/**
- * If the SCROLLABLE_ONLY_ASRS flag is set, then we only want to return
- * frames that will generate an ASR. This means that they are either
- * scrollable frames for which IsMaybeAsynchronouslyScrolled() returns true
- * (aka mWillBuildScrollableLayer == true) or they are sticky position
- * frames for which their corresponding scroll frame will generate an ASR.
- * This is an internal only flag, you cannot pass it to
- * GetNearestScrollContainerFrame since that can only return scroll frames.
- */
- SCROLLABLE_ONLY_ASRS = 0x20,
- /**
* If the SCROLLABLE_STOP_AT_PAGE flag is set, then we stop searching
* for scrollable ancestors when seeing a nsPageFrame. This can be used
* to avoid finding the viewport scroll frame in Print Preview (which
* would be undesirable as a 'position:sticky' container for content).
*/
- SCROLLABLE_STOP_AT_PAGE = 0x40,
+ SCROLLABLE_STOP_AT_PAGE = 0x20,
};
/**
* GetNearestScrollContainerFrame locates the first ancestor of aFrame
@@ -2900,35 +2890,8 @@ class nsLayoutUtils {
static FrameMetrics CalculateBasicFrameMetrics(
mozilla::ScrollContainerFrame* aScrollContainerFrame);
- /**
- * Follows the async scrollable ancestor chain of scroll frames to find
- * scroll frames that WantAsyncScroll(). This is used when activating scroll
- * frames and finding APZCs.
- */
static mozilla::ScrollContainerFrame* GetAsyncScrollableAncestorFrame(
nsIFrame* aTarget);
- /**
- * Follows the ASR (ActiveScrolledRoot) chain of frames, so that if
- * f is the frame of an ASR A, then calling this function on
- * OneStepInASRChain(f) will return the frame of parent ASR of A. Frames that
- * generate an ASR are scroll frames for which IsMaybeAsynchronouslyScrolled()
- * returns true (aka mWillBuildScrollableLayer == true) or they are sticky
- * position frames for which their corresponding scroll frame will generate an
- * ASR. This function is different from GetAsyncScrollableAncestorFrame above
- * because GetAsyncScrollableAncestorFrame looks only for scroll frames that
- * WantAsyncScroll that that function walks from fixed pos to the root scroll
- * frame. Because that status (ie mWillBuildScrollableLayer) can change this
- * should only be called during a paint to the window after BuildDisplayList
- * has been called on aTarget so that mWillBuildScrollableLayer will have been
- * updated for this paint already for any frame we need to consult. Or for
- * some other reason you know that mWillBuildScrollableLayer is up to date for
- * this paint for any frame that might need to be consulted, ie you just
- * updated them yourself. Note that a frame returned from this function could
- * generate two ASRs: an inner one corresponding to an activated scroll frame,
- * and an outer one corresponding to sticky pos.
- */
- static nsIFrame* GetASRAncestorFrame(nsIFrame* aTarget,
- nsDisplayListBuilder* aBuilder);
static void SetBSizeFromFontMetrics(
const nsIFrame* aFrame, mozilla::ReflowOutput& aMetrics,
diff --git a/layout/generic/ScrollContainerFrame.cpp b/layout/generic/ScrollContainerFrame.cpp
@@ -4340,26 +4340,7 @@ nsRect ScrollContainerFrame::RestrictToRootDisplayPort(
FissionAutostart()) {
return true;
}
- return StaticPrefs::apz_async_scroll_css_anchor_pos_AtStartup() &&
- aFrame->PresShell()->GetRootPresShell()->HasSeenAnchorPos();
-}
-
-bool ScrollContainerFrame::DecideScrollableLayerEnsureDisplayport(
- nsDisplayListBuilder* aBuilder) {
- MOZ_ASSERT(ShouldActivateAllScrollFrames(aBuilder, this));
- nsIContent* content = GetContent();
- bool hasDisplayPort = DisplayPortUtils::HasDisplayPort(content);
-
- // Note this intentionally differs from DecideScrollableLayer below by not
- // checking ShouldActivateAllScrollFrames.
- if (!hasDisplayPort && aBuilder->IsPaintingToWindow() &&
- nsLayoutUtils::AsyncPanZoomEnabled(this) && WantAsyncScroll()) {
- DisplayPortUtils::SetMinimalDisplayPortDuringPainting(content, PresShell());
- hasDisplayPort = true;
- }
-
- mWillBuildScrollableLayer = hasDisplayPort || mZoomableByAPZ;
- return mWillBuildScrollableLayer;
+ return aFrame->PresShell()->GetRootPresShell()->HasSeenAnchorPos();
}
bool ScrollContainerFrame::DecideScrollableLayer(
@@ -4381,7 +4362,18 @@ bool ScrollContainerFrame::DecideScrollableLayer(
if (aSetBase && !hasDisplayPort && aBuilder->IsPaintingToWindow() &&
ShouldActivateAllScrollFrames(aBuilder, this) &&
nsLayoutUtils::AsyncPanZoomEnabled(this) && WantAsyncScroll()) {
- DisplayPortUtils::SetMinimalDisplayPortDuringPainting(content, PresShell());
+ // SetDisplayPortMargins calls TriggerDisplayPortExpiration which starts a
+ // display port expiry timer for display ports that do expire. However
+ // minimal display ports do not expire, so the display port has to be
+ // marked before the SetDisplayPortMargins call so the expiry timer
+ // doesn't get started.
+ content->SetProperty(nsGkAtoms::MinimalDisplayPort,
+ reinterpret_cast<void*>(true));
+
+ DisplayPortUtils::SetDisplayPortMargins(
+ content, PresShell(), DisplayPortMargins::Empty(content),
+ DisplayPortUtils::ClearMinimalDisplayPortProperty::No, 0,
+ DisplayPortUtils::RepaintMode::DoNotRepaint);
hasDisplayPort = true;
}
diff --git a/layout/generic/ScrollContainerFrame.h b/layout/generic/ScrollContainerFrame.h
@@ -738,16 +738,6 @@ class ScrollContainerFrame : public nsContainerFrame,
}
/**
- * Like DecideScrollableLayer but skips computing dirty/visible rects and
- * setting the base rect. In addition, this always ensures a display port is
- * set if this scroll frame could async scroll. DecideScrollableLayer only
- * sets a display port in that situation if ShouldActivateAllScrollFrames
- * returns true. However you should only call this function is
- * ShouldActivateAllScrollFrames returns true anyways.
- * */
- bool DecideScrollableLayerEnsureDisplayport(nsDisplayListBuilder* aBuilder);
-
- /**
* Notify the scrollframe that the current scroll offset and origin have been
* sent over in a layers transaction.
*
diff --git a/layout/generic/nsIFrame.cpp b/layout/generic/nsIFrame.cpp
@@ -4421,74 +4421,6 @@ void nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
if (savedOutOfFlowData) {
aBuilder->SetBuildingInvisibleItems(false);
- nsIFrame* scrollsWithAnchor = nullptr;
- if (aBuilder->IsPaintingToWindow() &&
- // If we are in view transition capture we get a null asr no matter
- // what, so don't bother checking for async scrolling with a CSS anchor
- // pos anchor.
- !aBuilder->IsInViewTransitionCapture() &&
- child->IsAbsolutelyPositioned(disp) &&
- // If there is an active view transition in this document it is tricky
- // to determine what will be an active scroll frame outside of that
- // frame's BuildDisplayList, so don't bother to async scroll with an
- // anchor in that case. Bug 2001861 tracks removing this check.
- !PresContext()->Document()->GetActiveViewTransition()) {
- scrollsWithAnchor =
- AnchorPositioningUtils::GetAnchorThatFrameScrollsWith(child);
-
- if (scrollsWithAnchor && aBuilder->IsRetainingDisplayList()) {
- if (aBuilder->IsPartialUpdate()) {
- aBuilder->SetPartialBuildFailed(true);
- } else {
- aBuilder->SetDisablePartialUpdates(true);
- }
- }
- }
-
- const ActiveScrolledRoot* asr =
- savedOutOfFlowData->mContainingBlockActiveScrolledRoot;
-
-#ifdef DEBUG
- if (aBuilder->IsPaintingToWindow()) {
- // Assert that the asr is as expected.
- if (savedOutOfFlowData->mContainingBlockInViewTransitionCapture) {
- MOZ_ASSERT(asr == nullptr);
- MOZ_ASSERT(aBuilder->IsInViewTransitionCapture());
- } else if ((asr ? asr->mFrame : nullptr) !=
- nsLayoutUtils::GetASRAncestorFrame(child->GetParent(),
- aBuilder)) {
- // A weird case for native anonymous content in the custom content
- // container when the root is captured by a view transition. This
- // content is built outside of the view transition capture but the
- // containing block (the canvas frame) was built inside the capture, so
- // savedOutOfFlowData is saved as if we are inside the capture while we
- // are outside it (bug 2002160).
- MOZ_ASSERT(asr == nullptr);
- MOZ_ASSERT(PresContext()->Document()->GetActiveViewTransition());
- MOZ_ASSERT(
- child->GetParent()->GetContent()->IsInNativeAnonymousSubtree());
- bool inTopLayer = false;
- nsIFrame* curr = child->GetParent();
- while (curr) {
- if (curr->StyleDisplay()->mTopLayer == StyleTopLayer::Auto) {
- inTopLayer = true;
- break;
- }
- curr = curr->GetParent();
- }
- MOZ_ASSERT(inTopLayer);
- }
- }
-#endif
-
- if (scrollsWithAnchor) {
- asr = DisplayPortUtils::ActivateDisplayportOnASRAncestors(
- scrollsWithAnchor, child->GetParent(), asr, aBuilder);
-
- // TODO should we set the scroll parent id too?
- // https://github.com/w3c/csswg-drafts/issues/12042
- }
-
if (aBuilder->IsInViewTransitionCapture()) {
if (!savedOutOfFlowData->mContainingBlockInViewTransitionCapture) {
clipState.Clear();
@@ -4500,7 +4432,8 @@ void nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
} else {
clipState.SetClipChainForContainingBlockDescendants(
savedOutOfFlowData->mContainingBlockClipChain);
- asrSetter.SetCurrentActiveScrolledRoot(asr);
+ asrSetter.SetCurrentActiveScrolledRoot(
+ savedOutOfFlowData->mContainingBlockActiveScrolledRoot);
asrSetter.SetCurrentScrollParentId(savedOutOfFlowData->mScrollParentId);
}
MOZ_ASSERT(awayFromCommonPath,
diff --git a/layout/reftests/async-scrolling/anchor-pos-1-ref.html b/layout/reftests/async-scrolling/anchor-pos-1-ref.html
@@ -1,14 +0,0 @@
-<!DOCTYPE html>
-<html>
-<style>
-.anchored {
- position: absolute;
- width: 50px;
- height: 50px;
- background: yellow;
- left: 50px;
- top: 0;
-}
-</style>
-<div class="anchored"></div>
-</html>
diff --git a/layout/reftests/async-scrolling/anchor-pos-1.html b/layout/reftests/async-scrolling/anchor-pos-1.html
@@ -1,47 +0,0 @@
-<!DOCTYPE html>
-<html reftest-async-scroll>
-<style>
-.container {
- position: absolute;
- left: 0;
- top: 0;
-}
-.scroller {
- position: absolute;
- overflow: auto;
- scrollbar-width: none;
- width: 100px;
- height: 100px;
-}
-.spacer {
- width: 1px;
- height: 500px;
-}
-.anchor {
- width: 50px;
- height: 50px;
- background: blue;
- anchor-name: --my-anchor;
-}
-.anchored {
- position: absolute;
- position-anchor: --my-anchor;
- position-visibility: always;
- width: 50px;
- height: 50px;
- background: yellow;
- left: anchor(right);
- top: anchor(bottom);
-}
-</style>
-<div class="container">
- <div class="scroller"
- reftest-displayport-x="0" reftest-displayport-y="0"
- reftest-displayport-w="100" reftest-displayport-h="500"
- reftest-async-scroll-y="50">
- <div class="anchor"></div>
- <div class="spacer"></div>
- </div>
- <div class="anchored"></div>
-</div>
-</html>
diff --git a/layout/reftests/async-scrolling/anchor-pos-2-ref.html b/layout/reftests/async-scrolling/anchor-pos-2-ref.html
@@ -1,23 +0,0 @@
-<!DOCTYPE html>
-<html>
-<style>
-.anchor1 {
- position: absolute;
- width: 50px;
- height: 50px;
- background: blue;
- left: 50px;
- top: 0;
-}
-.anchored {
- position: absolute;
- width: 50px;
- height: 50px;
- background: yellow;
- left: 100px;
- top: 50px;
-}
-</style>
-<div class="anchor1"></div>
-<div class="anchored"></div>
-</html>
diff --git a/layout/reftests/async-scrolling/anchor-pos-2.html b/layout/reftests/async-scrolling/anchor-pos-2.html
@@ -1,64 +0,0 @@
-<!DOCTYPE html>
-<html reftest-async-scroll>
-<style>
-.container {
- position: absolute;
- left: 0;
- top: 0;
-}
-.scroller {
- position: absolute;
- overflow: auto;
- scrollbar-width: none;
- width: 150px;
- height: 100px;
-}
-.spacer {
- width: 1px;
- height: 500px;
-}
-.anchor1 {
- width: 50px;
- height: 50px;
- background: blue;
- anchor-name: --my-anchor1;
- position: absolute;
- position-anchor: --my-anchor2;
- position-visibility: always;
- left: anchor(right);
- top: anchor(bottom);
-}
-.anchor2 {
- width: 50px;
- height: 50px;
- background: pink;
- anchor-name: --my-anchor2;
-}
-.anchored {
- position: absolute;
- position-anchor: --my-anchor1;
- position-visibility: always;
- width: 50px;
- height: 50px;
- background: yellow;
- left: anchor(right);
- top: anchor(bottom);
-}
-</style>
-<div class="container">
- <div class="scroller"
- reftest-displayport-x="0" reftest-displayport-y="0"
- reftest-displayport-w="150" reftest-displayport-h="500">
- <div class="scroller"
- reftest-displayport-x="0" reftest-displayport-y="0"
- reftest-displayport-w="150" reftest-displayport-h="500"
- reftest-async-scroll-y="50">
- <div class="anchor2"></div>
- <div class="spacer"></div>
- </div>
- <div class="anchor1"></div>
- <div class="spacer"></div>
- </div>
- <div class="anchored"></div>
-</div>
-</html>
diff --git a/layout/reftests/async-scrolling/anchor-pos-sticky-1-ref.html b/layout/reftests/async-scrolling/anchor-pos-sticky-1-ref.html
@@ -1,22 +0,0 @@
-<html>
-<style>
-.anchor {
- position: absolute;
- width: 50px;
- height: 50px;
- background: blue;
- left: 0;
- top: 50px;
-}
-.anchored {
- position: absolute;
- width: 50px;
- height: 50px;
- background: yellow;
- left: 50px;
- top: 100px;
-}
-</style>
-<div class="anchor"></div>
-<div class="anchored"></div>
-</html>
diff --git a/layout/reftests/async-scrolling/anchor-pos-sticky-1.html b/layout/reftests/async-scrolling/anchor-pos-sticky-1.html
@@ -1,52 +0,0 @@
-<html reftest-async-scroll>
-<style>
-.container {
- position: absolute;
- left: 0;
- top: 0;
-}
-.scroller {
- position: absolute;
- overflow: auto;
- scrollbar-width: none;
- width: 100px;
- height: 100px;
-}
-.spacer {
- width: 1px;
- height: 100px;
-}
-.largespacer {
- width: 1px;
- height: 500px;
-}
-.anchor {
- position: sticky;
- top: 0;
- width: 50px;
- height: 50px;
- background: blue;
- anchor-name: --my-anchor;
-}
-.anchored {
- position: absolute;
- position-anchor: --my-anchor;
- position-visibility: always;
- width: 50px;
- height: 50px;
- background: yellow;
- left: anchor(right);
- top: anchor(bottom);
-}
-</style>
-<div class="container">
- <div class="scroller"
- reftest-displayport-x="0" reftest-displayport-y="0"
- reftest-displayport-w="100" reftest-displayport-h="500"
- reftest-async-scroll-y="50">
- <div class="spacer"></div>
- <div class="anchor"></div>
- <div class="largespacer"></div>
- </div>
- <div class="anchored"></div>
-</html>
diff --git a/layout/reftests/async-scrolling/anchor-pos-sticky-2-ref.html b/layout/reftests/async-scrolling/anchor-pos-sticky-2-ref.html
@@ -1,22 +0,0 @@
-<html>
-<style>
-.anchor {
- position: absolute;
- width: 50px;
- height: 50px;
- background: blue;
- left: 0;
- top: 0;
-}
-.anchored {
- position: absolute;
- width: 50px;
- height: 50px;
- background: yellow;
- left: 50px;
- top: 50px;
-}
-</style>
-<div class="anchor"></div>
-<div class="anchored"></div>
-</html>
diff --git a/layout/reftests/async-scrolling/anchor-pos-sticky-2.html b/layout/reftests/async-scrolling/anchor-pos-sticky-2.html
@@ -1,52 +0,0 @@
-<html reftest-async-scroll>
-<style>
-.container {
- position: absolute;
- left: 0;
- top: 0;
-}
-.scroller {
- position: absolute;
- overflow: auto;
- scrollbar-width: none;
- width: 100px;
- height: 100px;
-}
-.spacer {
- width: 1px;
- height: 100px;
-}
-.largespacer {
- width: 1px;
- height: 500px;
-}
-.anchor {
- position: sticky;
- top: 0;
- width: 50px;
- height: 50px;
- background: blue;
- anchor-name: --my-anchor;
-}
-.anchored {
- position: absolute;
- position-anchor: --my-anchor;
- position-visibility: always;
- width: 50px;
- height: 50px;
- background: yellow;
- left: anchor(right);
- top: anchor(bottom);
-}
-</style>
-<div class="container">
- <div class="scroller"
- reftest-displayport-x="0" reftest-displayport-y="0"
- reftest-displayport-w="100" reftest-displayport-h="500"
- reftest-async-scroll-y="250">
- <div class="spacer"></div>
- <div class="anchor"></div>
- <div class="largespacer"></div>
- </div>
- <div class="anchored"></div>
-</html>
diff --git a/layout/reftests/async-scrolling/reftest.list b/layout/reftests/async-scrolling/reftest.list
@@ -189,8 +189,3 @@ defaults pref(apz.allow_zooming,true) test-pref(apz.fixed-margin-override.enable
== dynamic-toolbar-sticky-6b.html dynamic-toolbar-sticky-6-ref.html
== dynamic-toolbar-sticky-6c.html dynamic-toolbar-sticky-6-ref.html
defaults
-
-== anchor-pos-1.html anchor-pos-1-ref.html
-== anchor-pos-2.html anchor-pos-2-ref.html
-== anchor-pos-sticky-1.html anchor-pos-sticky-1-ref.html
-== anchor-pos-sticky-2.html anchor-pos-sticky-2-ref.html
diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml
@@ -953,12 +953,6 @@
value: false
mirror: always
-# Whether to async scroll CSS anchor pos.
-- name: apz.async_scroll_css_anchor_pos
- type: bool
- value: true
- mirror: once
-
#---------------------------------------------------------------------------
# Prefs starting with "beacon."
#---------------------------------------------------------------------------
diff --git a/testing/web-platform/tests/css/css-anchor-position/anchor-loop-crash.html b/testing/web-platform/tests/css/css-anchor-position/anchor-loop-crash.html
@@ -1,70 +0,0 @@
-<!DOCTYPE html>
-<html reftest-async-scroll>
-<style>
-.container {
- position: absolute;
- left: 0;
- top: 0;
-}
-.scroller {
- position: absolute;
- overflow: auto;
- scrollbar-width: none;
- width: 150px;
- height: 100px;
-}
-.spacer {
- width: 1px;
- height: 500px;
-}
-.anchor1 {
- width: 50px;
- height: 50px;
- background: blue;
- anchor-name: --my-anchor1;
- position: absolute;
- position-anchor: --my-anchor2;
- position-visibility: always;
- left: anchor(right);
- top: anchor(bottom);
-}
-.anchor2 {
- width: 50px;
- height: 50px;
- background: pink;
- anchor-name: --my-anchor2;
- position: absolute;
- position-anchor: --my-anchor3;
- position-visibility: always;
- left: anchor(right);
- top: anchor(bottom);
-}
-.anchored {
- position: absolute;
- position-anchor: --my-anchor1;
- position-visibility: always;
- width: 50px;
- height: 50px;
- background: yellow;
- left: anchor(right);
- top: anchor(bottom);
- anchor-name: --my-anchor3;
-}
-</style>
-<div class="container">
- <div class="scroller"
- reftest-displayport-x="0" reftest-displayport-y="0"
- reftest-displayport-w="150" reftest-displayport-h="500">
- <div class="scroller"
- reftest-displayport-x="0" reftest-displayport-y="0"
- reftest-displayport-w="150" reftest-displayport-h="500"
- reftest-async-scroll-y="50">
- <div class="anchor2"></div>
- <div class="spacer"></div>
- </div>
- <div class="anchor1"></div>
- <div class="spacer"></div>
- </div>
- <div class="anchored"></div>
-</div>
-</html>