mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
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:
parent
f055964792
commit
e16291f14e
1 changed files with 84 additions and 71 deletions
|
@ -6,6 +6,7 @@ use std::ops::Range;
|
||||||
|
|
||||||
use app_units::{Au, MAX_AU};
|
use app_units::{Au, MAX_AU};
|
||||||
use log::warn;
|
use log::warn;
|
||||||
|
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use style::computed_values::border_collapse::T as BorderCollapse;
|
use style::computed_values::border_collapse::T as BorderCollapse;
|
||||||
use style::computed_values::box_sizing::T as BoxSizing;
|
use style::computed_values::box_sizing::T as BoxSizing;
|
||||||
|
@ -1004,94 +1005,106 @@ impl<'a> TableLayout<'a> {
|
||||||
containing_block_for_table: &ContainingBlock,
|
containing_block_for_table: &ContainingBlock,
|
||||||
parent_positioning_context: &mut PositioningContext,
|
parent_positioning_context: &mut PositioningContext,
|
||||||
) {
|
) {
|
||||||
for row_index in 0..self.table.slots.len() {
|
self.cells_laid_out = self
|
||||||
// When building the PositioningContext for this cell, we want it to have the same
|
.table
|
||||||
// configuration for whatever PositioningContext the contents are ultimately added to.
|
.slots
|
||||||
let collect_for_nearest_positioned_ancestor = parent_positioning_context
|
.par_iter()
|
||||||
.collects_for_nearest_positioned_ancestor() ||
|
.enumerate()
|
||||||
self.table.rows.get(row_index).map_or(false, |row| {
|
.map(|(row_index, row_slots)| {
|
||||||
let row_group_collects_for_nearest_positioned_ancestor =
|
// When building the PositioningContext for this cell, we want it to have the same
|
||||||
row.group_index.map_or(false, |group_index| {
|
// configuration for whatever PositioningContext the contents are ultimately added to.
|
||||||
self.table.row_groups[group_index]
|
let collect_for_nearest_positioned_ancestor = parent_positioning_context
|
||||||
.style
|
.collects_for_nearest_positioned_ancestor() ||
|
||||||
|
self.table.rows.get(row_index).map_or(false, |row| {
|
||||||
|
let row_group_collects_for_nearest_positioned_ancestor =
|
||||||
|
row.group_index.map_or(false, |group_index| {
|
||||||
|
self.table.row_groups[group_index]
|
||||||
|
.style
|
||||||
|
.establishes_containing_block_for_absolute_descendants(
|
||||||
|
FragmentFlags::empty(),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
row_group_collects_for_nearest_positioned_ancestor ||
|
||||||
|
row.style
|
||||||
.establishes_containing_block_for_absolute_descendants(
|
.establishes_containing_block_for_absolute_descendants(
|
||||||
FragmentFlags::empty(),
|
FragmentFlags::empty(),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
row_group_collects_for_nearest_positioned_ancestor ||
|
|
||||||
row.style
|
|
||||||
.establishes_containing_block_for_absolute_descendants(
|
|
||||||
FragmentFlags::empty(),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut cells_laid_out_row = Vec::new();
|
row_slots
|
||||||
let slots = &self.table.slots[row_index];
|
.par_iter()
|
||||||
for (column_index, slot) in slots.iter().enumerate() {
|
.enumerate()
|
||||||
let cell = match slot {
|
.map(|(column_index, slot)| {
|
||||||
TableSlot::Cell(cell) => cell,
|
let TableSlot::Cell(ref cell) = slot else {
|
||||||
_ => {
|
return None;
|
||||||
cells_laid_out_row.push(None);
|
};
|
||||||
continue;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut total_width = Au::zero();
|
let coordinates = TableSlotCoordinates::new(column_index, row_index);
|
||||||
for width_index in column_index..column_index + cell.colspan {
|
let border: LogicalSides<Au> = self
|
||||||
total_width += self.distributed_column_widths[width_index];
|
.get_collapsed_borders_for_cell(cell, coordinates)
|
||||||
}
|
.unwrap_or_else(|| {
|
||||||
|
cell.style
|
||||||
|
.border_width(containing_block_for_table.style.writing_mode)
|
||||||
|
})
|
||||||
|
.into();
|
||||||
|
|
||||||
let border: LogicalSides<Au> = self
|
let padding: LogicalSides<Au> = cell
|
||||||
.get_collapsed_borders_for_cell(
|
.style
|
||||||
cell,
|
.padding(containing_block_for_table.style.writing_mode)
|
||||||
TableSlotCoordinates::new(column_index, row_index),
|
.percentages_relative_to(self.basis_for_cell_padding_percentage.into())
|
||||||
)
|
.into();
|
||||||
.unwrap_or_else(|| {
|
let inline_border_padding_sum = border.inline_sum() + padding.inline_sum();
|
||||||
cell.style
|
|
||||||
.border_width(containing_block_for_table.style.writing_mode)
|
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_cell_width,
|
||||||
|
block_size: AuOrAuto::Auto,
|
||||||
|
style: &cell.style,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut positioning_context = PositioningContext::new_for_subtree(
|
||||||
|
collect_for_nearest_positioned_ancestor,
|
||||||
|
);
|
||||||
|
|
||||||
|
let layout = cell.contents.layout(
|
||||||
|
layout_context,
|
||||||
|
&mut positioning_context,
|
||||||
|
&containing_block_for_children,
|
||||||
|
);
|
||||||
|
|
||||||
|
Some(CellLayout {
|
||||||
|
layout,
|
||||||
|
padding: padding.clone(),
|
||||||
|
border: border.clone(),
|
||||||
|
positioning_context,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.into();
|
.collect()
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
let padding: LogicalSides<Au> = cell
|
// Now go through all cells laid out and update the cell measure based on the size
|
||||||
.style
|
// determined during layout.
|
||||||
.padding(containing_block_for_table.style.writing_mode)
|
for row_index in 0..self.table.size.height {
|
||||||
.percentages_relative_to(self.basis_for_cell_padding_percentage.into())
|
for column_index in 0..self.table.size.width {
|
||||||
.into();
|
let Some(layout) = &self.cells_laid_out[row_index][column_index] else {
|
||||||
let inline_border_padding_sum = border.inline_sum() + padding.inline_sum();
|
continue;
|
||||||
let total_width = (total_width - inline_border_padding_sum).max(Au::zero());
|
|
||||||
|
|
||||||
let containing_block_for_children = ContainingBlock {
|
|
||||||
inline_size: total_width,
|
|
||||||
block_size: AuOrAuto::Auto,
|
|
||||||
style: &cell.style,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut positioning_context =
|
|
||||||
PositioningContext::new_for_subtree(collect_for_nearest_positioned_ancestor);
|
|
||||||
|
|
||||||
let layout = cell.contents.layout(
|
|
||||||
layout_context,
|
|
||||||
&mut positioning_context,
|
|
||||||
&containing_block_for_children,
|
|
||||||
);
|
|
||||||
|
|
||||||
let content_size_from_layout = ContentSizes {
|
let content_size_from_layout = ContentSizes {
|
||||||
min_content: layout.content_block_size,
|
min_content: layout.layout.content_block_size,
|
||||||
max_content: layout.content_block_size,
|
max_content: layout.layout.content_block_size,
|
||||||
};
|
};
|
||||||
self.cell_measures[row_index][column_index]
|
self.cell_measures[row_index][column_index]
|
||||||
.block
|
.block
|
||||||
.content_sizes
|
.content_sizes
|
||||||
.max_assign(content_size_from_layout);
|
.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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue