Revert "layout: Add incremental box tree construction for inline floats and abspos" (#37888)

This reverts commit 19ceccc8eb due to a
significant increase in resident memory usage (See
https://github.com/servo/servo/issues/37887).

Testing: This is a revert due to a regression

Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
This commit is contained in:
Jonathan Schwender 2025-07-05 11:45:58 +08:00 committed by GitHub
parent e1a891ea96
commit c65cd1eadd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 28 additions and 66 deletions

View file

@ -136,20 +136,6 @@ impl LayoutBox {
.repair_style(context, node, new_style), .repair_style(context, node, new_style),
} }
} }
/// If this [`LayoutBox`] represents an unsplit (due to inline-block splits) inline
/// level item, unwrap and return it. If not, return `None`.
pub(crate) fn unsplit_inline_level_layout_box(self) -> Option<ArcRefCell<InlineItem>> {
let LayoutBox::InlineLevel(inline_level_boxes) = self else {
return None;
};
// If this element box has been subject to inline-block splitting, ignore it. It's
// not useful currently for incremental box tree construction.
if inline_level_boxes.len() != 1 {
return None;
}
inline_level_boxes.into_iter().next()
}
} }
/// A wrapper for [`InnerDOMLayoutData`]. This is necessary to give the entire data /// A wrapper for [`InnerDOMLayoutData`]. This is necessary to give the entire data

View file

@ -604,17 +604,13 @@ impl<'dom> BlockContainerBuilder<'dom, '_> {
) { ) {
if let Some(builder) = self.inline_formatting_context_builder.as_mut() { if let Some(builder) = self.inline_formatting_context_builder.as_mut() {
if !builder.is_empty() { if !builder.is_empty() {
let constructor = || { let inline_level_box =
ArcRefCell::new(AbsolutelyPositionedBox::construct( builder.push_absolutely_positioned_box(AbsolutelyPositionedBox::construct(
self.context, self.context,
info, info,
display_inside, display_inside,
contents, contents,
)) ));
};
let old_layout_box = box_slot.take_layout_box_if_undamaged(info.damage);
let inline_level_box =
builder.push_absolutely_positioned_box(constructor, old_layout_box);
box_slot.set(LayoutBox::InlineLevel(vec![inline_level_box])); box_slot.set(LayoutBox::InlineLevel(vec![inline_level_box]));
return; return;
} }
@ -641,17 +637,13 @@ impl<'dom> BlockContainerBuilder<'dom, '_> {
) { ) {
if let Some(builder) = self.inline_formatting_context_builder.as_mut() { if let Some(builder) = self.inline_formatting_context_builder.as_mut() {
if !builder.is_empty() { if !builder.is_empty() {
let constructor = || { let inline_level_box = builder.push_float_box(FloatBox::construct(
ArcRefCell::new(FloatBox::construct( self.context,
self.context, info,
info, display_inside,
display_inside, contents,
contents, self.propagated_data,
self.propagated_data, ));
))
};
let old_layout_box = box_slot.take_layout_box_if_undamaged(info.damage);
let inline_level_box = builder.push_float_box(constructor, old_layout_box);
box_slot.set(LayoutBox::InlineLevel(vec![inline_level_box])); box_slot.set(LayoutBox::InlineLevel(vec![inline_level_box]));
return; return;
} }

View file

@ -160,10 +160,19 @@ impl InlineFormattingContextBuilder {
) -> ArcRefCell<InlineItem> { ) -> ArcRefCell<InlineItem> {
// If there is an existing undamaged layout box that's compatible, use that. // If there is an existing undamaged layout box that's compatible, use that.
let independent_formatting_context = old_layout_box let independent_formatting_context = old_layout_box
.and_then(LayoutBox::unsplit_inline_level_layout_box) .and_then(|layout_box| {
.and_then(|inline_item| match &*inline_item.borrow() { let LayoutBox::InlineLevel(inline_level_boxes) = layout_box else {
InlineItem::Atomic(atomic, ..) => Some(atomic.clone()), return None;
_ => None, };
// If there's an existing box, it should be a compatible atomic inline and should
// not have been subject to inline-block splitting.
assert_eq!(inline_level_boxes.len(), 1);
let first_box = inline_level_boxes.into_iter().next()?;
match &*first_box.borrow() {
InlineItem::Atomic(atomic, ..) => Some(atomic.clone()),
_ => None,
}
}) })
.unwrap_or_else(independent_formatting_context_creator); .unwrap_or_else(independent_formatting_context_creator);
@ -186,20 +195,9 @@ impl InlineFormattingContextBuilder {
pub(crate) fn push_absolutely_positioned_box( pub(crate) fn push_absolutely_positioned_box(
&mut self, &mut self,
absolutely_positioned_box_creator: impl FnOnce() -> ArcRefCell<AbsolutelyPositionedBox>, absolutely_positioned_box: AbsolutelyPositionedBox,
old_layout_box: Option<LayoutBox>,
) -> ArcRefCell<InlineItem> { ) -> ArcRefCell<InlineItem> {
let absolutely_positioned_box = old_layout_box let absolutely_positioned_box = ArcRefCell::new(absolutely_positioned_box);
.and_then(LayoutBox::unsplit_inline_level_layout_box)
.and_then(|inline_item| match &*inline_item.borrow() {
InlineItem::OutOfFlowAbsolutelyPositionedBox(positioned_box, ..) => {
Some(positioned_box.clone())
},
_ => None,
})
.unwrap_or_else(absolutely_positioned_box_creator);
// We cannot just reuse the old inline item, because the `current_text_offset` may have changed.
let inline_level_box = ArcRefCell::new(InlineItem::OutOfFlowAbsolutelyPositionedBox( let inline_level_box = ArcRefCell::new(InlineItem::OutOfFlowAbsolutelyPositionedBox(
absolutely_positioned_box, absolutely_positioned_box,
self.current_text_offset, self.current_text_offset,
@ -209,23 +207,9 @@ impl InlineFormattingContextBuilder {
inline_level_box inline_level_box
} }
pub(crate) fn push_float_box( pub(crate) fn push_float_box(&mut self, float_box: FloatBox) -> ArcRefCell<InlineItem> {
&mut self, let inline_level_box =
float_box_creator: impl FnOnce() -> ArcRefCell<FloatBox>, ArcRefCell::new(InlineItem::OutOfFlowFloatBox(ArcRefCell::new(float_box)));
old_layout_box: Option<LayoutBox>,
) -> ArcRefCell<InlineItem> {
let inline_level_box = old_layout_box
.and_then(LayoutBox::unsplit_inline_level_layout_box)
.unwrap_or_else(|| ArcRefCell::new(InlineItem::OutOfFlowFloatBox(float_box_creator())));
debug_assert!(
matches!(
&*inline_level_box.borrow(),
InlineItem::OutOfFlowFloatBox(..),
),
"Created float box with incompatible `old_layout_box`"
);
self.inline_items.push(inline_level_box.clone()); self.inline_items.push(inline_level_box.clone());
self.contains_floats = true; self.contains_floats = true;
inline_level_box inline_level_box