From 683c8233a4f26e4db2494c41b56fd5f04b7b7fba Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Tue, 11 Oct 2022 06:59:52 +0000 Subject: [PATCH] Bug 1794415 - Force reflow of fewer anonymous children of `content-visibility: hidden` r=emilio Reflow fewer types of anonymous children (only anonymous blocks) of `content-visibility: hidden` elements. This reduces the number of reflows for skipped content. This also adjusts to the implementation of IsHiddenByContentVisibilityOnAnyAncestor() to match the implementation of IsHiddenByContentVisibilityOfInFlowParentForLayout() in only skipping one layer of anonymous content. Differential Revision: https://phabricator.services.mozilla.com/D158961 --- layout/generic/nsIFrame.cpp | 19 ++++---- ...sibility-hidden-document-reflow-count.html | 44 +++++++++++++++++++ 2 files changed, 54 insertions(+), 9 deletions(-) create mode 100644 testing/web-platform/mozilla/tests/css/css-contain/content-visibility-hidden-document-reflow-count.html diff --git a/layout/generic/nsIFrame.cpp b/layout/generic/nsIFrame.cpp index f53ac5f88423..fee977c59c92 100644 --- a/layout/generic/nsIFrame.cpp +++ b/layout/generic/nsIFrame.cpp @@ -6734,6 +6734,7 @@ void nsIFrame::DidReflow(nsPresContext* aPresContext, NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, ("nsIFrame::DidReflow")); if (IsHiddenByContentVisibilityOfInFlowParentForLayout()) { + RemoveStateBits(NS_FRAME_IN_REFLOW | NS_FRAME_FIRST_REFLOW); return; } @@ -6855,7 +6856,8 @@ bool nsIFrame::HidesContentForLayout() const { bool nsIFrame::IsHiddenByContentVisibilityOfInFlowParentForLayout() const { const auto* parent = GetInFlowParent(); - return parent && parent->HidesContentForLayout() && !Style()->IsAnonBox(); + return parent && parent->HidesContentForLayout() && + !(Style()->IsAnonBox() && !IsFrameOfType(nsIFrame::eLineParticipant)); } bool nsIFrame::IsHiddenByContentVisibilityOnAnyAncestor() const { @@ -6863,18 +6865,17 @@ bool nsIFrame::IsHiddenByContentVisibilityOnAnyAncestor() const { return false; } - bool isAnonymousBox = Style()->IsAnonBox(); + bool isAnonymousBlock = + Style()->IsAnonBox() && !IsFrameOfType(nsIFrame::eLineParticipant); for (nsIFrame* cur = GetInFlowParent(); cur; cur = cur->GetInFlowParent()) { + if (!isAnonymousBlock && cur->HidesContent()) { + return true; + } + // Anonymous boxes are not hidden by the content-visibility of their first // non-anonymous ancestor, but can be hidden by ancestors further up the // tree. - if (isAnonymousBox && !cur->Style()->IsAnonBox()) { - isAnonymousBox = false; - } - - if (!isAnonymousBox && cur->HidesContent()) { - return true; - } + isAnonymousBlock = false; } return false; diff --git a/testing/web-platform/mozilla/tests/css/css-contain/content-visibility-hidden-document-reflow-count.html b/testing/web-platform/mozilla/tests/css/css-contain/content-visibility-hidden-document-reflow-count.html new file mode 100644 index 000000000000..69c1c4b7ddcf --- /dev/null +++ b/testing/web-platform/mozilla/tests/css/css-contain/content-visibility-hidden-document-reflow-count.html @@ -0,0 +1,44 @@ + + + + CSS Contain: Test content-visibility:hidden reflow counts + + + + + + + hello + + + +