🐛 Fix paths and layout performance and rendering on boolean exclusions (#10778)

* 🐛 Skip identity transforms in layout reflow propagation

Layout reflow emitted identity transforms for unchanged children, which
fanned out through the whole subtree on every drag frame and froze large
files in the WASM renderer.

* 🐛 Fix exclude boolean rendering in render WASM
This commit is contained in:
Alejandro Alonso 2026-07-22 15:47:43 +02:00 committed by GitHub
parent e1f976aa2f
commit f21bd45893
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 22 additions and 8 deletions

View File

@ -705,16 +705,21 @@ impl Shape {
}
pub fn set_path_segments(&mut self, segments: Vec<Segment>) {
let path = Path::new(segments);
match &mut self.shape_type {
Type::Bool(Bool { bool_type, .. }) => {
let path = match bool_type {
// Exclusion booleans are computed with even-odd semantics but
// PathData uploads do not carry the fill rule.
BoolType::Exclusion => Path::new(segments).with_even_odd(true),
_ => Path::new(segments),
};
self.shape_type = Type::Bool(Bool {
bool_type: *bool_type,
path,
});
}
Type::Path(_) => {
self.shape_type = Type::Path(path);
self.shape_type = Type::Path(Path::new(segments));
}
_ => {}
};

View File

@ -667,9 +667,12 @@ pub fn reflow_flex_layout(
transform.post_concat(&Matrix::translate(delta_v));
}
result.push_back(Modifier::transform_propagate(child.id, transform));
if child.has_layout() {
result.push_back(Modifier::reflow(child.id, force_reflow));
// Skip identity: propagating it fans out through the whole subtree.
if !math::identitish(&transform) {
result.push_back(Modifier::transform_propagate(child.id, transform));
if child.has_layout() {
result.push_back(Modifier::reflow(child.id, force_reflow));
}
}
shape_anchor = next_anchor(

View File

@ -884,9 +884,12 @@ pub fn reflow_grid_layout(
transform.post_concat(&Matrix::translate(delta_v));
}
result.push_back(Modifier::transform_propagate(child.id, transform));
if child.has_layout() {
result.push_back(Modifier::reflow(child.id, force_reflow));
// Skip identity: propagating it fans out through the whole subtree.
if !math::identitish(&transform) {
result.push_back(Modifier::transform_propagate(child.id, transform));
if child.has_layout() {
result.push_back(Modifier::reflow(child.id, force_reflow));
}
}
}

View File

@ -251,6 +251,9 @@ impl Path {
pub fn to_skia_path(&self, svg_attrs: Option<&SvgAttrs>) -> skia::Path {
let mut path = self.skia_path.snapshot();
if self.is_even_odd() {
path.set_fill_type(skia::PathFillType::EvenOdd);
}
if let Some(attrs) = svg_attrs {
if attrs.fill_rule == FillRule::Evenodd {
path.set_fill_type(skia::PathFillType::EvenOdd);