layout: Enable parallel layout for tables (#32477)

This simply wraps row and column-based layout of table sells in a
`par_iter()` unconditionally enabling parallel layout for tables. In the
future we can choose to adjust the conditions under which layout is done
in parallel.
This commit is contained in:
Martin Robinson 2024-06-26 18:33:48 +02:00 committed by GitHub
parent f055964792
commit e16291f14e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -6,6 +6,7 @@ use std::ops::Range;
use app_units::{Au, MAX_AU};
use log::warn;
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
use servo_arc::Arc;
use style::computed_values::border_collapse::T as BorderCollapse;
use style::computed_values::box_sizing::T as BoxSizing;
@ -1004,7 +1005,12 @@ impl<'a> TableLayout<'a> {
containing_block_for_table: &ContainingBlock,
parent_positioning_context: &mut PositioningContext,
) {
for row_index in 0..self.table.slots.len() {
self.cells_laid_out = self
.table
.slots
.par_iter()
.enumerate()
.map(|(row_index, row_slots)| {
// When building the PositioningContext for this cell, we want it to have the same
// configuration for whatever PositioningContext the contents are ultimately added to.
let collect_for_nearest_positioned_ancestor = parent_positioning_context
@ -1025,27 +1031,17 @@ impl<'a> TableLayout<'a> {
)
});
let mut cells_laid_out_row = Vec::new();
let slots = &self.table.slots[row_index];
for (column_index, slot) in slots.iter().enumerate() {
let cell = match slot {
TableSlot::Cell(cell) => cell,
_ => {
cells_laid_out_row.push(None);
continue;
},
row_slots
.par_iter()
.enumerate()
.map(|(column_index, slot)| {
let TableSlot::Cell(ref cell) = slot else {
return None;
};
let mut total_width = Au::zero();
for width_index in column_index..column_index + cell.colspan {
total_width += self.distributed_column_widths[width_index];
}
let coordinates = TableSlotCoordinates::new(column_index, row_index);
let border: LogicalSides<Au> = self
.get_collapsed_borders_for_cell(
cell,
TableSlotCoordinates::new(column_index, row_index),
)
.get_collapsed_borders_for_cell(cell, coordinates)
.unwrap_or_else(|| {
cell.style
.border_width(containing_block_for_table.style.writing_mode)
@ -1058,16 +1054,22 @@ impl<'a> TableLayout<'a> {
.percentages_relative_to(self.basis_for_cell_padding_percentage.into())
.into();
let inline_border_padding_sum = border.inline_sum() + padding.inline_sum();
let total_width = (total_width - inline_border_padding_sum).max(Au::zero());
let mut total_cell_width: Au = (column_index..column_index + cell.colspan)
.map(|column_index| self.distributed_column_widths[column_index])
.sum::<Au>() -
inline_border_padding_sum;
total_cell_width = total_cell_width.max(Au::zero());
let containing_block_for_children = ContainingBlock {
inline_size: total_width,
inline_size: total_cell_width,
block_size: AuOrAuto::Auto,
style: &cell.style,
};
let mut positioning_context =
PositioningContext::new_for_subtree(collect_for_nearest_positioned_ancestor);
let mut positioning_context = PositioningContext::new_for_subtree(
collect_for_nearest_positioned_ancestor,
);
let layout = cell.contents.layout(
layout_context,
@ -1075,23 +1077,34 @@ impl<'a> TableLayout<'a> {
&containing_block_for_children,
);
Some(CellLayout {
layout,
padding: padding.clone(),
border: border.clone(),
positioning_context,
})
})
.collect()
})
.collect();
// Now go through all cells laid out and update the cell measure based on the size
// determined during layout.
for row_index in 0..self.table.size.height {
for column_index in 0..self.table.size.width {
let Some(layout) = &self.cells_laid_out[row_index][column_index] else {
continue;
};
let content_size_from_layout = ContentSizes {
min_content: layout.content_block_size,
max_content: layout.content_block_size,
min_content: layout.layout.content_block_size,
max_content: layout.layout.content_block_size,
};
self.cell_measures[row_index][column_index]
.block
.content_sizes
.max_assign(content_size_from_layout);
cells_laid_out_row.push(Some(CellLayout {
layout,
padding,
border,
positioning_context,
}));
}
self.cells_laid_out.push(cells_laid_out_row);
}
}