Bug 1672527 - Don't update overflow on frames that haven't been reflowed yet. r=emilio

This adds NS_FRAME_FIRST_REFLOW to the frame state flags
we're NOT updating overflow for.  This is a minor performance
optimization.

Differential Revision: https://phabricator.services.mozilla.com/D94395
This commit is contained in:
Mats Palmgren 2020-10-22 19:15:56 +00:00
Родитель 3cf334a80a
Коммит b4d4471b6e
1 изменённых файлов: 12 добавлений и 13 удалений

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

@ -1247,6 +1247,14 @@ static nsIContent* NextSiblingWhichMayHaveFrame(nsIContent* aContent) {
return nullptr;
}
// If |aFrame| is dirty or has dirty children, or has never been reflowed,
// then we can skip updating overflows since that will happen when it's
// reflowed.
static inline bool CanSkipOverflowUpdates(const nsIFrame* aFrame) {
return aFrame->HasAnyStateBits(
NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN | NS_FRAME_FIRST_REFLOW);
}
void RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList) {
NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
"Someone forgot a script blocker");
@ -1484,7 +1492,7 @@ void RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList) {
} else {
NS_ASSERTION(frame, "This shouldn't happen");
if (!frame->FrameMaintainsOverflow()) {
if (!frame->FrameMaintainsOverflow() || CanSkipOverflowUpdates(frame)) {
// frame does not maintain overflow rects, so avoid calling
// FinishAndStoreOverflow on it:
hint &=
@ -1637,10 +1645,7 @@ void RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList) {
// the outer svg's anonymous child frame (instead of to the
// anonymous child's children).
// If |hintFrame| is dirty or has dirty children, we don't bother
// updating overflows since that will happen when it's reflowed.
if (!hintFrame->HasAnyStateBits(NS_FRAME_IS_DIRTY |
NS_FRAME_HAS_DIRTY_CHILDREN)) {
if (!CanSkipOverflowUpdates(hintFrame)) {
mOverflowChangedTracker.AddFrame(
hintFrame, OverflowChangedTracker::CHILDREN_CHANGED);
}
@ -1651,10 +1656,7 @@ void RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList) {
for (; childFrame; childFrame = childFrame->GetNextSibling()) {
MOZ_ASSERT(childFrame->IsFrameOfType(nsIFrame::eSVG),
"Not expecting non-SVG children");
// If |childFrame| is dirty or has dirty children, we don't bother
// updating overflows since that will happen when it's reflowed.
if (!childFrame->HasAnyStateBits(NS_FRAME_IS_DIRTY |
NS_FRAME_HAS_DIRTY_CHILDREN)) {
if (!CanSkipOverflowUpdates(childFrame)) {
mOverflowChangedTracker.AddFrame(
childFrame, OverflowChangedTracker::CHILDREN_CHANGED);
}
@ -1668,10 +1670,7 @@ void RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList) {
}
}
}
// If |frame| is dirty or has dirty children, we don't bother updating
// overflows since that will happen when it's reflowed.
if (!frame->HasAnyStateBits(NS_FRAME_IS_DIRTY |
NS_FRAME_HAS_DIRTY_CHILDREN)) {
if (!CanSkipOverflowUpdates(frame)) {
if (hint & (nsChangeHint_UpdateOverflow |
nsChangeHint_UpdatePostTransformOverflow)) {
OverflowChangedTracker::ChangeKind changeKind;