Bug 1379344 - Avoid traversing the display list twice inside nsDisplayList::UpdateBounds(); r=mstange

This commit is contained in:
Ehsan Akhgari 2017-07-28 02:08:44 -04:00
Родитель 061d437c9e
Коммит eefe461ec1
2 изменённых файлов: 15 добавлений и 4 удалений

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

@ -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;

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

@ -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<nsIFrame*> *aOutFrames) override;