Make layout build a display list when the highlighted DOM node changed (#37501)

Highlights from the devtools trigger reflows. Previously, incremental
layout would notice that nothing about the box tree changed and skip
generating a new display list. This caused the highlights to never be
painted.

Forcing a new DL in this case makes reflows that happen *while* there is
a highlighted DOM node (which did not change since the last reflow)
slightly less efficient. We could check if the highlighted node changed
and only force a new display list if it did, but I'm not sure if
`OpaqueNode`s can be compared like that. It also seems like a very niche
issue.

Testing: This is hard to test for, so there are no tests.
Fixes https://github.com/servo/servo/issues/37500.

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This commit is contained in:
Simon Wülker 2025-06-17 13:14:41 +02:00 committed by GitHub
parent c0970ea655
commit f29eee5356
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -181,6 +181,11 @@ pub struct LayoutThread {
/// Debug options, copied from configuration to this `LayoutThread` in order
/// to avoid having to constantly access the thread-safe global options.
debug: DebugOptions,
/// Tracks the node that was highlighted by the devtools during the last reflow.
///
/// If this changed, then we need to create a new display list.
previously_highlighted_dom_node: Cell<Option<OpaqueNode>>,
}
pub struct LayoutFactoryImpl();
@ -555,6 +560,7 @@ impl LayoutThread {
stylist: Stylist::new(device, QuirksMode::NoQuirks),
resolved_images_cache: Default::default(),
debug: opts::get().debug.clone(),
previously_highlighted_dom_node: Cell::new(None),
}
}
@ -648,6 +654,12 @@ impl LayoutThread {
&snapshot_map,
);
if self.previously_highlighted_dom_node.get() != reflow_request.highlighted_dom_node {
// Need to manually force layout to build a new display list regardless of whether the box tree
// changed or not.
self.need_new_display_list.set(true);
}
let mut layout_context = LayoutContext {
id: self.id,
origin: reflow_request.origin.clone(),
@ -992,6 +1004,8 @@ impl LayoutThread {
self.have_ever_generated_display_list.set(true);
self.need_new_display_list.set(false);
self.previously_highlighted_dom_node
.set(reflow_request.highlighted_dom_node);
true
}