diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp index 7db6055bde2e..87c7e76397d1 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -1892,7 +1892,8 @@ nsDisplayList::GetBounds(nsDisplayListBuilder* aBuilder) const { nsRect nsDisplayList::GetClippedBoundsWithRespectToASR(nsDisplayListBuilder* aBuilder, - const ActiveScrolledRoot* aASR) const { + const ActiveScrolledRoot* aASR, + nsRect* aVisibleRect) const { nsRect bounds; for (nsDisplayItem* i = GetBottom(); i != nullptr; i = i->GetAbove()) { nsRect r = i->GetClippedBounds(aBuilder); @@ -1908,6 +1909,9 @@ nsDisplayList::GetClippedBoundsWithRespectToASR(nsDisplayListBuilder* aBuilder, r = clip->GetClipRect(); } } + if (aVisibleRect) { + aVisibleRect->UnionRect(*aVisibleRect, i->GetVisibleRect()); + } bounds.UnionRect(bounds, r); } return bounds; diff --git a/layout/painting/nsDisplayList.h b/layout/painting/nsDisplayList.h index 529b54fa2584..8a2328c404ce 100644 --- a/layout/painting/nsDisplayList.h +++ b/layout/painting/nsDisplayList.h @@ -2517,9 +2517,14 @@ public: * If there is an item in this list which is not bounded with respect to * aASR (i.e. which does not have "finite bounds" with respect to aASR), * then this method trigger an assertion failure. + * The optional aVisibleRect out argument can be set to non-null if the + * caller is also interested to know the visible rect. This can be used + * to get the visible rect efficiently without traversing the display list + * twice. */ nsRect GetClippedBoundsWithRespectToASR(nsDisplayListBuilder* aBuilder, - const ActiveScrolledRoot* aASR) const; + const ActiveScrolledRoot* aASR, + nsRect* aVisibleRect = nullptr) const; /** * Find the topmost display item that returns a non-null frame, and return @@ -3822,7 +3827,9 @@ public: */ virtual void UpdateBounds(nsDisplayListBuilder* aBuilder) override { - mBounds = mList.GetClippedBoundsWithRespectToASR(aBuilder, mActiveScrolledRoot); + nsRect visibleRect; + mBounds = mList.GetClippedBoundsWithRespectToASR(aBuilder, mActiveScrolledRoot, + &visibleRect); // The display list may contain content that's visible outside the visible // rect (i.e. the current dirty rect) passed in when the item was created. // This happens when the dirty rect has been restricted to the visual @@ -3830,7 +3837,7 @@ public: // rects in nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay), but that // frame contains placeholders for out-of-flows that aren't descendants of // the frame. - mVisibleRect.UnionRect(mBaseVisibleRect, mList.GetVisibleRect()); + mVisibleRect.UnionRect(mBaseVisibleRect, visibleRect); } virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, HitTestState* aState, nsTArray *aOutFrames) override;