Bug 1494676 - Always consider scrollframes with will-change: scroll active r=tnikkel

This bypasses will-change budgeting for frames will-change: scroll.

Differential Revision: https://phabricator.services.mozilla.com/D118373
This commit is contained in:
Miko Mynttinen 2021-06-23 13:10:15 +00:00
parent 37538d847e
commit c948d7c6a9
7 changed files with 22 additions and 63 deletions

View File

@ -3327,7 +3327,7 @@ void ScrollFrameHelper::AppendScrollPartsTo(nsDisplayListBuilder* aBuilder,
// This means that we will build scroll bar layers for out of budget
// will-change: scroll position.
const mozilla::layers::ScrollableLayerGuid::ViewID scrollTargetId =
IsMaybeScrollingActive()
IsScrollingActive()
? nsLayoutUtils::FindOrCreateIDFor(mScrolledFrame->GetContent())
: mozilla::layers::ScrollableLayerGuid::NULL_SCROLL_ID;
@ -3598,7 +3598,7 @@ void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
mOuter->DisplayBorderBackgroundOutline(aBuilder, aLists);
if (aBuilder->IsPaintingToWindow()) {
if (IsMaybeScrollingActive() && !gfxVars::UseWebRender()) {
if (IsScrollingActive() && !gfxVars::UseWebRender()) {
if (mScrollPosForLayerPixelAlignment == nsPoint(-1, -1)) {
mScrollPosForLayerPixelAlignment = GetScrollPosition();
}
@ -6020,7 +6020,7 @@ bool ScrollFrameHelper::IsScrollbarOnRight() const {
}
}
bool ScrollFrameHelper::IsMaybeScrollingActive() const {
bool ScrollFrameHelper::IsScrollingActive() const {
const nsStyleDisplay* disp = mOuter->StyleDisplay();
if (disp->mWillChange.bits & StyleWillChangeBits::SCROLL) {
return true;
@ -6032,25 +6032,9 @@ bool ScrollFrameHelper::IsMaybeScrollingActive() const {
nsContentUtils::HasScrollgrab(content);
}
bool ScrollFrameHelper::IsScrollingActive(
nsDisplayListBuilder* aBuilder) const {
bool ScrollFrameHelper::IsScrollingActiveNotMinimalDisplayPort() const {
const nsStyleDisplay* disp = mOuter->StyleDisplay();
if (disp->mWillChange.bits & StyleWillChangeBits::SCROLL &&
aBuilder->IsInWillChangeBudget(mOuter, GetVisualViewportSize())) {
return true;
}
nsIContent* content = mOuter->GetContent();
return mHasBeenScrolledRecently || IsAlwaysActive() ||
DisplayPortUtils::HasDisplayPort(content) ||
nsContentUtils::HasScrollgrab(content);
}
bool ScrollFrameHelper::IsScrollingActiveNotMinimalDisplayPort(
nsDisplayListBuilder* aBuilder) const {
const nsStyleDisplay* disp = mOuter->StyleDisplay();
if (disp->mWillChange.bits & StyleWillChangeBits::SCROLL &&
aBuilder->IsInWillChangeBudget(mOuter, GetVisualViewportSize())) {
if (disp->mWillChange.bits & StyleWillChangeBits::SCROLL) {
return true;
}

View File

@ -377,15 +377,14 @@ class ScrollFrameHelper : public nsIReflowCallback {
public:
bool IsScrollbarOnRight() const;
bool IsScrollingActive(nsDisplayListBuilder* aBuilder) const;
bool IsScrollingActiveNotMinimalDisplayPort(
nsDisplayListBuilder* aBuilder) const;
bool IsScrollingActive() const;
bool IsScrollingActiveNotMinimalDisplayPort() const;
bool IsMaybeAsynchronouslyScrolled() const {
// If this is true, then we'll build an ASR, and that's what we want
// to know I think.
return mWillBuildScrollableLayer;
}
bool IsMaybeScrollingActive() const;
void ResetScrollPositionForLayerPixelAlignment() {
mScrollPosForLayerPixelAlignment = GetScrollPosition();
}
@ -1046,15 +1045,9 @@ class nsHTMLScrollFrame : public nsContainerFrame,
mHelper.PostScrolledAreaEvent();
return NS_OK;
}
bool IsScrollingActive(nsDisplayListBuilder* aBuilder) final {
return mHelper.IsScrollingActive(aBuilder);
}
bool IsScrollingActiveNotMinimalDisplayPort(
nsDisplayListBuilder* aBuilder) final {
return mHelper.IsScrollingActiveNotMinimalDisplayPort(aBuilder);
}
bool IsMaybeScrollingActive() const final {
return mHelper.IsMaybeScrollingActive();
bool IsScrollingActive() final { return mHelper.IsScrollingActive(); }
bool IsScrollingActiveNotMinimalDisplayPort() final {
return mHelper.IsScrollingActiveNotMinimalDisplayPort();
}
bool IsMaybeAsynchronouslyScrolled() final {
return mHelper.IsMaybeAsynchronouslyScrolled();
@ -1538,15 +1531,9 @@ class nsXULScrollFrame final : public nsBoxFrame,
mHelper.PostScrolledAreaEvent();
return NS_OK;
}
bool IsScrollingActive(nsDisplayListBuilder* aBuilder) final {
return mHelper.IsScrollingActive(aBuilder);
}
bool IsScrollingActiveNotMinimalDisplayPort(
nsDisplayListBuilder* aBuilder) final {
return mHelper.IsScrollingActiveNotMinimalDisplayPort(aBuilder);
}
bool IsMaybeScrollingActive() const final {
return mHelper.IsMaybeScrollingActive();
bool IsScrollingActive() final { return mHelper.IsScrollingActive(); }
bool IsScrollingActiveNotMinimalDisplayPort() final {
return mHelper.IsScrollingActiveNotMinimalDisplayPort();
}
bool IsMaybeAsynchronouslyScrolled() final {
return mHelper.IsMaybeAsynchronouslyScrolled();

View File

@ -2775,7 +2775,7 @@ static void DisplayDebugBorders(nsDisplayListBuilder* aBuilder,
static bool IsScrollFrameActive(nsDisplayListBuilder* aBuilder,
nsIScrollableFrame* aScrollableFrame) {
return aScrollableFrame && aScrollableFrame->IsScrollingActive(aBuilder);
return aScrollableFrame && aScrollableFrame->IsScrollingActive();
}
/**

View File

@ -379,14 +379,13 @@ class nsIScrollableFrame : public nsIScrollbarMediator {
* This basically means that we should allocate resources in the
* expectation that scrolling is going to happen.
*/
virtual bool IsScrollingActive(nsDisplayListBuilder* aBuilder) = 0;
virtual bool IsScrollingActive() = 0;
/**
* The same as IsScrollingActive but minimal display ports are not considered
* active.
*/
virtual bool IsScrollingActiveNotMinimalDisplayPort(
nsDisplayListBuilder* aBuilder) = 0;
virtual bool IsScrollingActiveNotMinimalDisplayPort() = 0;
/**
* Returns true if this scroll frame might be scrolled
@ -394,11 +393,6 @@ class nsIScrollableFrame : public nsIScrollbarMediator {
*/
virtual bool IsMaybeAsynchronouslyScrolled() = 0;
/**
* Same as the above except doesn't take into account will-change budget,
* which means that it can be called during display list building.
*/
virtual bool IsMaybeScrollingActive() const = 0;
/**
* Call this when the layer(s) induced by active scrolling are being
* completely redrawn.

View File

@ -435,7 +435,7 @@ void nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
bool constructZoomItem = subdocRootFrame && parentAPD != subdocAPD;
bool needsOwnLayer = false;
if (constructZoomItem || presContext->IsRootContentDocument() ||
(sf && sf->IsScrollingActive(aBuilder))) {
(sf && sf->IsScrollingActive())) {
needsOwnLayer = true;
}

View File

@ -418,9 +418,7 @@ static bool CheckScrollInducedActivity(
nsIScrollableFrame* scrollFrame =
do_QueryFrame(aLayerActivity->mAnimatingScrollHandlerFrame.GetFrame());
if (scrollFrame &&
(!aBuilder ||
scrollFrame->IsScrollingActiveNotMinimalDisplayPort(aBuilder))) {
if (scrollFrame && scrollFrame->IsScrollingActiveNotMinimalDisplayPort()) {
return true;
}

View File

@ -1594,7 +1594,7 @@ static bool IsStickyFrameActive(nsDisplayListBuilder* aBuilder,
return false;
}
return sf->IsScrollingActive(aBuilder);
return sf->IsScrollingActive();
}
nsDisplayListBuilder::AGRState nsDisplayListBuilder::IsAnimatedGeometryRoot(
@ -1637,7 +1637,7 @@ nsDisplayListBuilder::AGRState nsDisplayListBuilder::IsAnimatedGeometryRoot(
if (parentType == LayoutFrameType::Scroll ||
parentType == LayoutFrameType::ListControl) {
nsIScrollableFrame* sf = do_QueryFrame(parent);
if (sf->GetScrolledFrame() == aFrame && sf->IsScrollingActive(this)) {
if (sf->GetScrolledFrame() == aFrame && sf->IsScrollingActive()) {
MOZ_ASSERT(!aFrame->IsTransformed());
aIsAsync = sf->IsMaybeAsynchronouslyScrolled();
return AGR_YES;
@ -1648,11 +1648,7 @@ nsDisplayListBuilder::AGRState nsDisplayListBuilder::IsAnimatedGeometryRoot(
// its own layer so that it can move without repainting.
if (parentType == LayoutFrameType::Slider) {
auto* sf = static_cast<nsSliderFrame*>(parent)->GetScrollFrame();
// The word "Maybe" in IsMaybeScrollingActive might be confusing but we do
// indeed need to always consider scroll thumbs as AGRs if
// IsMaybeScrollingActive is true because that is the same condition we use
// in ScrollFrameHelper::AppendScrollPartsTo to layerize scroll thumbs.
if (sf && sf->IsMaybeScrollingActive()) {
if (sf && sf->IsScrollingActive()) {
return AGR_YES;
}
}