perf(layout): keep grid and table scratch outside layout boxes

Store resolved grid tracks and collapsed-border records only for actual owners in the pass-local world. Freeze the same canonical grid results and consume the same table geometry during paint.

Completes the shared scratch extraction from 96cc04d1e8, after sparse numeric cache allocation.
This commit is contained in:
ldm0
2026-10-17 20:06:22 +08:00
committed by Donough Liu
parent 412f6c5d38
commit 4e453f261f
7 changed files with 21 additions and 23 deletions
+1 -1
View File
@@ -253,7 +253,7 @@ where
if !layout_box.style.is_visible() {
return PaintCullBounds::Empty;
}
let Some(borders) = layout_box.collapsed_table_borders.as_ref() else {
let Some(borders) = projection.world.collapsed_table_borders.get(&id) else {
return PaintCullBounds::Empty;
};
let mut bounds = PaintCullBounds::Empty;
+1 -1
View File
@@ -20,7 +20,7 @@ pub(super) fn project_collapsed_table_borders<N>(
if !layout_box.style.is_visible() {
return;
}
let Some(borders) = layout_box.collapsed_table_borders.as_ref() else {
let Some(borders) = projection.world.collapsed_table_borders.get(&id) else {
return;
};
let geometry = &projection.boxes[id.index()];
+4 -1
View File
@@ -969,7 +969,10 @@ where
},
horizontal: layout_box.style.uses_horizontal_writing_mode(),
});
let resolved_grid_tracks = layout_box.resolved_grid_tracks.clone();
let resolved_grid_tracks = world
.resolved_grid_tracks
.get(&LayoutBoxId::from_index(geometry.id.index()))
.cloned();
FrozenLayoutBox {
geometry,
scroll_extent,
+2 -2
View File
@@ -113,7 +113,7 @@ fn emit_context<N>(
kind: UnitKind::Contents,
sequence: next_sequence(sequence),
});
if world.boxes[root.index()].collapsed_table_borders.is_some() {
if world.collapsed_table_borders.contains_key(&root) {
collection.table_collapsed_borders.push(PaintUnit {
id: root,
kind: UnitKind::TableCollapsedBorders,
@@ -240,7 +240,7 @@ fn collect_subtree<N>(
for child in ordered_children(world, id) {
collect_subtree(world, child, descendant_group, sequence, collection);
}
if layout_box.collapsed_table_borders.is_some() {
if world.collapsed_table_borders.contains_key(&id) {
push_unit(
collection,
group,
+2 -2
View File
@@ -468,7 +468,7 @@ where
{
world.boxes[part.index()].collapsed_table_border_part = true;
}
world.boxes[root.index()].collapsed_table_borders = Some(borders);
world.collapsed_table_borders.insert(root, borders);
}
pub(super) fn set_collapsed_border_geometry<N>(
@@ -479,7 +479,7 @@ pub(super) fn set_collapsed_border_geometry<N>(
) where
N: Copy + Debug + Eq + Hash,
{
if let Some(borders) = world.boxes[root.index()].collapsed_table_borders.as_mut() {
if let Some(borders) = world.collapsed_table_borders.get_mut(&root) {
borders.set_geometry(columns, rows);
}
}
+3 -3
View File
@@ -138,6 +138,7 @@ pub(crate) fn prepare_world_layout<N>(
where
N: Copy + Debug + Eq + Hash,
{
world.resolved_grid_tracks.clear();
for index in 0..world.boxes.len() {
world.clear_layout_caches(LayoutBoxId::from_index(index));
let layout_box = &mut world.boxes[index];
@@ -147,7 +148,6 @@ where
layout_box.layout_children.clear();
layout_box.positioned_containing_block = None;
layout_box.inline_static_position = None;
layout_box.resolved_grid_tracks = None;
}
world.viewport_layout.children.clear();
@@ -1880,8 +1880,8 @@ where
else {
return;
};
self.boxes[LayoutBoxId::from_taffy(node_id).index()].resolved_grid_tracks =
Some(resolved_grid_tracks);
self.resolved_grid_tracks
.insert(LayoutBoxId::from_taffy(node_id), resolved_grid_tracks);
}
}
+8 -13
View File
@@ -263,22 +263,11 @@ pub struct LayoutBox<N> {
pub(crate) replaced_context: Option<ReplacedContext>,
pub(crate) replaced_image: Option<crate::LayoutImageResource>,
pub(crate) css_images: crate::source::LayoutCssImageResources,
/// Winning collapsed-table edges owned by the table wrapper for this pass.
///
/// The record contains only resolved numeric/color/style data. It is
/// produced before Taffy sizing, completed with grid-line geometry after
/// sizing, and consumed once by immutable paint projection.
pub(crate) collapsed_table_borders: Option<crate::table::CollapsedTableBorders>,
/// Suppresses ordinary per-box border paint for parts participating in a
/// collapsed table. Their authored borders have already entered the table
/// owner's conflict-resolution grid.
pub(crate) collapsed_table_border_part: bool,
pub(crate) inline_formatting_context: bool,
/// Used Grid tracks produced by the numeric layout pass.
///
/// This is browser-owned canonical geometry rather than a retained Taffy
/// object. It is frozen with the rest of the layout tree for CSSOM reads.
pub(crate) resolved_grid_tracks: Option<LayoutResolvedGridTracks>,
pub(crate) table_measure_cache: Option<Box<crate::table::TableMeasureCache>>,
pub(crate) unrounded_layout: Layout,
pub(crate) final_layout: Layout,
@@ -644,6 +633,12 @@ where
pub(crate) box_caches: Vec<Cache>,
/// Box-indexed lookup into compact cache storage; usize::MAX is absent.
pub(crate) box_cache_slots: Vec<usize>,
/// Winning collapsed-table edges, computed and consumed in this pass.
/// Empty slots are not embedded in boxes that do not own a table.
pub(crate) collapsed_table_borders: HashMap<LayoutBoxId, crate::table::CollapsedTableBorders>,
/// Used Grid tracks for actual owners. Their canonical result is frozen
/// for CSSOM before this pass-local map is released.
pub(crate) resolved_grid_tracks: HashMap<LayoutBoxId, LayoutResolvedGridTracks>,
pub(crate) source_mapping: HashMap<N, LayoutBoxId>,
pub(crate) display_contents_mapping: HashMap<N, Vec<LayoutBoxId>>,
pub(crate) root: LayoutBoxId,
@@ -673,6 +668,8 @@ where
boxes: vec![root],
box_caches: Vec::new(),
box_cache_slots: Vec::new(),
collapsed_table_borders: HashMap::new(),
resolved_grid_tracks: HashMap::new(),
source_mapping: HashMap::new(),
display_contents_mapping: HashMap::new(),
root: LayoutBoxId::from_index(0),
@@ -1242,10 +1239,8 @@ where
replaced_context: None,
replaced_image: None,
css_images: crate::source::LayoutCssImageResources::default(),
collapsed_table_borders: None,
collapsed_table_border_part: false,
inline_formatting_context: false,
resolved_grid_tracks: None,
table_measure_cache: None,
unrounded_layout: Layout::with_order(0),
final_layout: Layout::with_order(0),