layout: Cache IndependentNonReplacedContents::layout() (#36082)

This replaces `IndependentLayout` with `CacheableLayoutResult` and
stores it in `LayoutBoxBase` so it can be reused when we need to lay out
a box multiple times.

This is a generalization of the caching that we had for flexbox, which
is now removed in favor of the new one.

With this, the number of runs per second in the Chromium perf test
`flexbox-deeply-nested-column-flow.html` are multiplied by 3.

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Oriol Brufau 2025-03-24 13:33:44 +01:00 committed by GitHub
parent efd6e86393
commit c09eed759b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 216 additions and 160 deletions

View file

@ -109,15 +109,17 @@ use unicode_bidi::{BidiInfo, Level};
use webrender_api::FontInstanceKey;
use xi_unicode::linebreak_property;
use super::IndependentFormattingContextContents;
use super::float::{Clear, PlacementAmongFloats};
use super::{
CacheableLayoutResult, IndependentFloatOrAtomicLayoutResult,
IndependentFormattingContextContents,
};
use crate::cell::ArcRefCell;
use crate::context::LayoutContext;
use crate::flow::CollapsibleWithParentStartMargin;
use crate::flow::float::{FloatBox, SequentialLayoutState};
use crate::flow::{CollapsibleWithParentStartMargin, FlowLayout};
use crate::formatting_contexts::{
Baselines, IndependentFormattingContext, IndependentLayoutResult,
IndependentNonReplacedContents,
Baselines, IndependentFormattingContext, IndependentNonReplacedContents,
};
use crate::fragment_tree::{
BoxFragment, CollapsedBlockMargins, CollapsedMargin, Fragment, FragmentFlags,
@ -1585,7 +1587,7 @@ impl InlineFormattingContext {
containing_block: &ContainingBlock,
sequential_layout_state: Option<&mut SequentialLayoutState>,
collapsible_with_parent_start_margin: CollapsibleWithParentStartMargin,
) -> FlowLayout {
) -> CacheableLayoutResult {
let first_line_inline_start = if self.has_first_formatted_line {
containing_block
.style
@ -1697,12 +1699,14 @@ impl InlineFormattingContext {
content_block_size == Au::zero() &&
collapsible_with_parent_start_margin.0;
FlowLayout {
CacheableLayoutResult {
fragments: layout.fragments,
content_block_size,
collapsible_margins_in_children,
baselines: layout.baselines,
depends_on_block_constraints: layout.depends_on_block_constraints,
content_inline_size_for_table: None,
specific_layout_info: None,
}
}
@ -1922,7 +1926,7 @@ impl IndependentFormattingContext {
// We need to know the inline size of the atomic before deciding whether to do the line break.
let mut child_positioning_context = PositioningContext::new_for_style(self.style())
.unwrap_or_else(|| PositioningContext::new_for_subtree(true));
let IndependentLayoutResult {
let IndependentFloatOrAtomicLayoutResult {
mut fragment,
baselines,
pbm_sums,