layout: Correct damage propagation and style repair for repaint-only layout (#37004)

When making last-minute changes to the repaint-only layout pass, damage
propagation was broken, meaning that full layout was always done. This
change fixes that, meaning that times in the `blaster.html` test case
now reflect those described in the original commit message from #36978.

In addition, some style repair is now fixed:
- `InlineFormattingContext`s now keep a `SharedInlineStyles` for the
root of the IFC
    which is updated during style repair.
 - `BlockFormattingContext`s now properly update their style.

These changes are verified by turning on repaint only layout for more
properties
in Stylo via servo/stylo#183.

Testing: Manual performance testing via `blaster.html`.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Martin Robinson 2025-05-19 12:17:49 +02:00 committed by GitHub
parent 89f7026cc8
commit 573663d502
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 91 additions and 48 deletions

View file

@ -91,6 +91,7 @@ use line_breaker::LineBreaker;
use malloc_size_of_derive::MallocSizeOf;
use range::Range;
use script::layout_dom::ServoLayoutNode;
use script_layout_interface::wrapper_traits::{LayoutNode, ThreadSafeLayoutNode};
use servo_arc::Arc;
use style::Zero;
use style::computed_values::text_wrap_mode::T as TextWrapMode;
@ -158,6 +159,10 @@ pub(crate) struct InlineFormattingContext {
/// context in order to avoid duplicating this information.
pub font_metrics: Vec<FontKeyAndMetrics>,
/// The [`SharedInlineStyles`] for the root of this [`InlineFormattingContext`] that are used to
/// share styles with all [`TextRun`] children.
pub(super) shared_inline_styles: SharedInlineStyles,
pub(super) text_decoration_line: TextDecorationLine,
/// Whether this IFC contains the 1st formatted line of an element:
@ -237,12 +242,14 @@ impl InlineItem {
InlineItem::OutOfFlowAbsolutelyPositionedBox(positioned_box, ..) => positioned_box
.borrow_mut()
.context
.repair_style(context, new_style),
.repair_style(context, node, new_style),
InlineItem::OutOfFlowFloatBox(float_box) => float_box
.borrow_mut()
.contents
.repair_style(context, new_style),
InlineItem::Atomic(atomic, ..) => atomic.borrow_mut().repair_style(context, new_style),
.repair_style(context, node, new_style),
InlineItem::Atomic(atomic, ..) => {
atomic.borrow_mut().repair_style(context, node, new_style)
},
}
}
@ -1699,6 +1706,11 @@ impl InlineFormattingContext {
inline_items: builder.inline_items,
inline_boxes: builder.inline_boxes,
font_metrics,
shared_inline_styles: builder
.shared_inline_styles_stack
.last()
.expect("Should have at least one SharedInlineStyle for the root of an IFC")
.clone(),
text_decoration_line: propagated_data.text_decoration,
has_first_formatted_line,
contains_floats: builder.contains_floats,
@ -1707,6 +1719,11 @@ impl InlineFormattingContext {
}
}
pub(crate) fn repair_style(&self, node: &ServoLayoutNode, new_style: &Arc<ComputedValues>) {
*self.shared_inline_styles.style.borrow_mut() = new_style.clone();
*self.shared_inline_styles.selected.borrow_mut() = node.to_threadsafe().selected_style();
}
pub(super) fn layout(
&self,
layout_context: &LayoutContext,