Bug 1379458 - The ScrollParentId should match the ASR tree. r=botond,tnikkel,mstange

Make the ScrollMetadata's mScrollParentId match what is found in the active
scroll root tree.

Depends on D148662

Differential Revision: https://phabricator.services.mozilla.com/D149925
This commit is contained in:
Dan Robertson 2022-12-27 14:08:51 +00:00
Родитель 7dac5c1755
Коммит 8b358b41b7
10 изменённых файлов: 63 добавлений и 68 удалений

Просмотреть файл

@ -3310,6 +3310,9 @@ void nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
autoRecording;
ViewID id = ScrollableLayerGuid::NULL_SCROLL_ID;
nsDisplayListBuilder::AutoCurrentActiveScrolledRootSetter asrSetter(
builder);
if (presShell->GetDocument() &&
presShell->GetDocument()->IsRootDisplayDocument() &&
!presShell->GetRootScrollFrame()) {
@ -3342,7 +3345,7 @@ void nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
}
}
nsDisplayListBuilder::AutoCurrentScrollParentIdSetter idSetter(builder, id);
asrSetter.SetCurrentScrollParentId(id);
builder->SetVisibleRect(visibleRect);
builder->SetIsBuilding(true);

Просмотреть файл

@ -120,6 +120,7 @@ static void BuildDisplayListForTopLayerFrame(nsDisplayListBuilder* aBuilder,
savedOutOfFlowData->mCombinedClipChain);
asrSetter.SetCurrentActiveScrolledRoot(
savedOutOfFlowData->mContainingBlockActiveScrolledRoot);
asrSetter.SetCurrentScrollParentId(savedOutOfFlowData->mScrollParentId);
}
nsDisplayListBuilder::AutoBuildingDisplayList buildingForChild(
aBuilder, aFrame, visible, dirty);

Просмотреть файл

@ -510,6 +510,7 @@ void nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
displayData->mContainingBlockClipChain);
asrSetter.SetCurrentActiveScrolledRoot(
displayData->mContainingBlockActiveScrolledRoot);
asrSetter.SetCurrentScrollParentId(displayData->mScrollParentId);
thisItemASR = displayData->mContainingBlockActiveScrolledRoot;
}
nsDisplayCanvasBackgroundImage* bgItem = nullptr;

Просмотреть файл

@ -4195,18 +4195,8 @@ void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
{
// Note that setting the current scroll parent id here means that positioned
// children of this scroll info layer will pick up the scroll info layer as
// their scroll handoff parent. This is intentional because that is what
// happens for positioned children of scroll layers, and we want to maintain
// consistent behaviour between scroll layers and scroll info layers.
nsDisplayListBuilder::AutoCurrentScrollParentIdSetter idSetter(
aBuilder,
couldBuildLayer && mScrolledFrame->GetContent()
? nsLayoutUtils::FindOrCreateIDFor(mScrolledFrame->GetContent())
: aBuilder->GetCurrentScrollParentId());
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
// If we're building an async zoom container, clip the contents inside
// to the layout viewport (scrollPortClip). The composition bounds clip
// (clipRect) will be applied to the zoom container itself in
@ -4233,10 +4223,16 @@ void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
nsDisplayListBuilder::AutoCurrentActiveScrolledRootSetter asrSetter(
aBuilder);
if (mWillBuildScrollableLayer && aBuilder->IsPaintingToWindow()) {
asrSetter.EnterScrollFrame(sf);
}
if (couldBuildLayer && mScrolledFrame->GetContent()) {
asrSetter.SetCurrentScrollParentId(
nsLayoutUtils::FindOrCreateIDFor(mScrolledFrame->GetContent()));
}
if (mWillBuildScrollableLayer && aBuilder->BuildCompositorHitTestInfo()) {
// Create a hit test info item for the scrolled content that's not
// clipped to the displayport. This ensures that within the bounds
@ -4339,13 +4335,14 @@ void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
if (aBuilder->IsPaintingToWindow()) {
mIsParentToActiveScrollFrames =
ShouldActivateAllScrollFrames()
? idSetter.GetContainsNonMinimalDisplayPort()
: idSetter.ShouldForceLayerForScrollParent();
? asrSetter.GetContainsNonMinimalDisplayPort()
: asrSetter.ShouldForceLayerForScrollParent();
}
if (idSetter.ShouldForceLayerForScrollParent()) {
if (asrSetter.ShouldForceLayerForScrollParent()) {
// Note that forcing layerization of scroll parents follows the scroll
// handoff chain which is subject to the out-of-flow-frames caveat noted
// above (where the idSetter variable is created).
// above (where the asrSetter variable is created).
MOZ_ASSERT(couldBuildLayer && mScrolledFrame->GetContent() &&
aBuilder->IsPaintingToWindow());
if (!mWillBuildScrollableLayer) {

Просмотреть файл

@ -4243,6 +4243,7 @@ void nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
savedOutOfFlowData->mContainingBlockClipChain);
asrSetter.SetCurrentActiveScrolledRoot(
savedOutOfFlowData->mContainingBlockActiveScrolledRoot);
asrSetter.SetCurrentScrollParentId(savedOutOfFlowData->mScrollParentId);
MOZ_ASSERT(awayFromCommonPath,
"It is impossible when savedOutOfFlowData is true");
} else if (HasAnyStateBits(NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) &&

Просмотреть файл

@ -463,14 +463,6 @@ void nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
visible, dirty);
if (subdocRootFrame) {
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
nsDisplayListBuilder::AutoCurrentScrollParentIdSetter idSetter(
aBuilder,
ignoreViewportScrolling && rootScrollFrame &&
rootScrollFrame->GetContent()
? nsLayoutUtils::FindOrCreateIDFor(rootScrollFrame->GetContent())
: aBuilder->GetCurrentScrollParentId());
bool hasDocumentLevelListenersForApzAwareEvents =
gfxPlatform::AsyncPanZoomEnabled() &&
nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(presShell);

Просмотреть файл

@ -1364,7 +1364,8 @@ void nsDisplayListBuilder::MarkFramesForDisplayList(
const ActiveScrolledRoot* asr = mCurrentActiveScrolledRoot;
OutOfFlowDisplayData* data = new OutOfFlowDisplayData(
clipChain, combinedClipChain, asr, visibleRect, dirtyRect);
clipChain, combinedClipChain, asr, this->mCurrentScrollParentId,
visibleRect, dirtyRect);
aDirtyFrame->SetProperty(
nsDisplayListBuilder::OutOfFlowDisplayDataProperty(), data);
mFramesWithOOFData.AppendElement(aDirtyFrame);
@ -1386,7 +1387,8 @@ void nsDisplayListBuilder::MarkFramesForDisplayList(
mClipState.GetCurrentCombinedClipChain(this);
const ActiveScrolledRoot* asr = mCurrentActiveScrolledRoot;
CurrentPresShellState()->mFixedBackgroundDisplayData.emplace(
clipChain, combinedClipChain, asr, GetVisibleRect(), GetDirtyRect());
clipChain, combinedClipChain, asr, this->mCurrentScrollParentId,
GetVisibleRect(), GetDirtyRect());
}
}
@ -3303,6 +3305,7 @@ AppendedBackgroundType nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
if (displayData) {
asrSetter.SetCurrentActiveScrolledRoot(
displayData->mContainingBlockActiveScrolledRoot);
asrSetter.SetCurrentScrollParentId(displayData->mScrollParentId);
if (nsLayoutUtils::UsesAsyncScrolling(aFrame)) {
// Override the dirty rect on the builder to be the dirty rect of
// the viewport.

Просмотреть файл

@ -1101,25 +1101,34 @@ class nsDisplayListBuilder {
};
/**
* A helper class to temporarily set the value of mCurrentScrollParentId.
* Used to update the current active scrolled root on the display list
* builder, and to create new active scrolled roots.
*/
class AutoCurrentScrollParentIdSetter {
class AutoCurrentActiveScrolledRootSetter {
public:
AutoCurrentScrollParentIdSetter(nsDisplayListBuilder* aBuilder,
ViewID aScrollId)
explicit AutoCurrentActiveScrolledRootSetter(nsDisplayListBuilder* aBuilder)
: mBuilder(aBuilder),
mOldValue(aBuilder->mCurrentScrollParentId),
mSavedActiveScrolledRoot(aBuilder->mCurrentActiveScrolledRoot),
mContentClipASR(aBuilder->ClipState().GetContentClipASR()),
mDescendantsStartIndex(aBuilder->mActiveScrolledRoots.Length()),
mUsed(false),
mOldScrollParentId(aBuilder->mCurrentScrollParentId),
mOldForceLayer(aBuilder->mForceLayerForScrollParent),
mOldContainsNonMinimalDisplayPort(
mBuilder->mContainsNonMinimalDisplayPort) {
// If this AutoCurrentScrollParentIdSetter has the same scrollId as the
// previous one on the stack, then that means the scrollframe that
mBuilder->mContainsNonMinimalDisplayPort),
mCanBeScrollParent(false) {}
void SetCurrentScrollParentId(ViewID aScrollId) {
// Update the old scroll parent id.
mOldScrollParentId = mBuilder->mCurrentScrollParentId;
// If this AutoCurrentActiveScrolledRootSetter has the same aScrollId as
// the previous one on the stack, then that means the scrollframe that
// created this isn't actually scrollable and cannot participate in
// scroll handoff. We set mCanBeScrollParent to false to indicate this.
mCanBeScrollParent = (mOldValue != aScrollId);
aBuilder->mCurrentScrollParentId = aScrollId;
aBuilder->mForceLayerForScrollParent = false;
aBuilder->mContainsNonMinimalDisplayPort = false;
mCanBeScrollParent = (mOldScrollParentId != aScrollId);
mBuilder->mCurrentScrollParentId = aScrollId;
mBuilder->mForceLayerForScrollParent = false;
mBuilder->mContainsNonMinimalDisplayPort = false;
}
bool ShouldForceLayerForScrollParent() const {
@ -1134,8 +1143,9 @@ class nsDisplayListBuilder {
return mCanBeScrollParent && mBuilder->mContainsNonMinimalDisplayPort;
}
~AutoCurrentScrollParentIdSetter() {
mBuilder->mCurrentScrollParentId = mOldValue;
~AutoCurrentActiveScrolledRootSetter() {
mBuilder->mCurrentActiveScrolledRoot = mSavedActiveScrolledRoot;
mBuilder->mCurrentScrollParentId = mOldScrollParentId;
if (mCanBeScrollParent) {
// If this flag is set, caller code is responsible for having dealt
// with the current value of mBuilder->mForceLayerForScrollParent, so
@ -1151,31 +1161,6 @@ class nsDisplayListBuilder {
mOldContainsNonMinimalDisplayPort;
}
private:
nsDisplayListBuilder* mBuilder;
ViewID mOldValue;
bool mOldForceLayer;
bool mOldContainsNonMinimalDisplayPort;
bool mCanBeScrollParent;
};
/**
* Used to update the current active scrolled root on the display list
* builder, and to create new active scrolled roots.
*/
class AutoCurrentActiveScrolledRootSetter {
public:
explicit AutoCurrentActiveScrolledRootSetter(nsDisplayListBuilder* aBuilder)
: mBuilder(aBuilder),
mSavedActiveScrolledRoot(aBuilder->mCurrentActiveScrolledRoot),
mContentClipASR(aBuilder->ClipState().GetContentClipASR()),
mDescendantsStartIndex(aBuilder->mActiveScrolledRoots.Length()),
mUsed(false) {}
~AutoCurrentActiveScrolledRootSetter() {
mBuilder->mCurrentActiveScrolledRoot = mSavedActiveScrolledRoot;
}
void SetCurrentActiveScrolledRoot(
const ActiveScrolledRoot* aActiveScrolledRoot);
@ -1215,6 +1200,10 @@ class nsDisplayListBuilder {
* class.
*/
bool mUsed;
ViewID mOldScrollParentId;
bool mOldForceLayer;
bool mOldContainsNonMinimalDisplayPort;
bool mCanBeScrollParent;
};
/**
@ -1378,13 +1367,15 @@ class nsDisplayListBuilder {
const DisplayItemClipChain* aContainingBlockClipChain,
const DisplayItemClipChain* aCombinedClipChain,
const ActiveScrolledRoot* aContainingBlockActiveScrolledRoot,
const nsRect& aVisibleRect, const nsRect& aDirtyRect)
const ViewID& aScrollParentId, const nsRect& aVisibleRect,
const nsRect& aDirtyRect)
: mContainingBlockClipChain(aContainingBlockClipChain),
mCombinedClipChain(aCombinedClipChain),
mContainingBlockActiveScrolledRoot(
aContainingBlockActiveScrolledRoot),
mVisibleRect(aVisibleRect),
mDirtyRect(aDirtyRect) {}
mDirtyRect(aDirtyRect),
mScrollParentId(aScrollParentId) {}
const DisplayItemClipChain* mContainingBlockClipChain;
const DisplayItemClipChain*
mCombinedClipChain; // only necessary for the special case of top layer
@ -1397,6 +1388,7 @@ class nsDisplayListBuilder {
// such a case returns a quantity in layout coordinates.
nsRect mVisibleRect;
nsRect mDirtyRect;
ViewID mScrollParentId;
static nsRect ComputeVisibleRectForFrame(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,

Просмотреть файл

@ -7459,7 +7459,8 @@ nsDisplayTableBackgroundSet::nsDisplayTableBackgroundSet(
nsDisplayListBuilder* aBuilder, nsIFrame* aTable)
: mBuilder(aBuilder),
mColGroupBackgrounds(aBuilder),
mColBackgrounds(aBuilder) {
mColBackgrounds(aBuilder),
mCurrentScrollParentId(aBuilder->GetCurrentScrollParentId()) {
mPrevTableBackgroundSet = mBuilder->SetTableBackgroundSet(this);
mozilla::DebugOnly<const nsIFrame*> reference =
mBuilder->FindReferenceFrameFor(aTable, &mToReferenceFrame);

Просмотреть файл

@ -85,6 +85,9 @@ class nsDisplayTableBackgroundSet {
}
const ActiveScrolledRoot* GetTableASR() { return mTableASR; }
layers::ScrollableLayerGuid::ViewID GetScrollParentId() {
return mCurrentScrollParentId;
}
private:
// This class is only used on stack, so we don't have to worry about leaking
@ -101,6 +104,7 @@ class nsDisplayTableBackgroundSet {
nsTArray<nsTableColFrame*> mColumns;
nsPoint mToReferenceFrame;
nsRect mDirtyRect;
layers::ScrollableLayerGuid::ViewID mCurrentScrollParentId;
const DisplayItemClipChain* mCombinedTableClipChain;
const ActiveScrolledRoot* mTableASR;