Improve performance of group bounds

This commit is contained in:
alonso.torres
2025-10-22 11:30:59 +02:00
parent 7459239639
commit 513e7374cb
2 changed files with 72 additions and 23 deletions

View File

@@ -719,8 +719,7 @@ impl Shape {
}
pub fn bounds(&self) -> Bounds {
*self.bounds
.get_or_init(|| self.calculate_bounds())
*self.bounds.get_or_init(|| self.calculate_bounds())
}
pub fn selrect(&self) -> math::Rect {
@@ -947,6 +946,24 @@ impl Shape {
}
}
pub fn children_ids_iter(&self, include_hidden: bool) -> Box<dyn Iterator<Item = &Uuid> + '_> {
if include_hidden {
return Box::new(self.children.iter().rev());
}
if let Type::Bool(_) = self.shape_type {
Box::new([].iter())
} else if let Type::Group(group) = self.shape_type {
if group.masked {
Box::new(self.children.iter().rev().take(self.children.len() - 1))
} else {
Box::new(self.children.iter().rev())
}
} else {
Box::new(self.children.iter().rev())
}
}
pub fn all_children(
&self,
shapes: &ShapesPool,
@@ -1257,6 +1274,36 @@ impl Shape {
}
}
pub fn modified_children_ids_iter<'a>(
&'a self,
structure: Option<&'a Vec<StructureEntry>>,
include_hidden: bool,
) -> Box<dyn Iterator<Item = Cow<'a, Uuid>> + 'a> {
if let Some(structure) = structure {
let mut result: Vec<Cow<'a, Uuid>> = self
.children_ids_iter(include_hidden)
.map(Cow::Borrowed)
.collect();
let mut to_remove = HashSet::<Cow<'a, Uuid>>::new();
for st in structure {
match st.entry_type {
StructureEntryType::AddChild => {
result.insert(result.len() - st.index as usize, Cow::Owned(st.id));
}
StructureEntryType::RemoveChild => {
to_remove.insert(Cow::Owned(st.id));
}
_ => {}
}
}
Box::new(result.into_iter().filter(move |id| !to_remove.contains(id)))
} else {
Box::new(self.children_ids_iter(include_hidden).map(Cow::Borrowed))
}
}
pub fn drop_shadow_paints(&self) -> Vec<skia_safe::Paint> {
let drop_shadows: Vec<&Shadow> = self.drop_shadows_visible().collect();

View File

@@ -88,7 +88,6 @@ fn propagate_children(
result
}
// FIXME: PERFORMANCE
fn calculate_group_bounds(
shape: &Shape,
shapes: &ShapesPool,
@@ -98,16 +97,14 @@ fn calculate_group_bounds(
let shape_bounds = bounds.find(shape);
let mut result = Vec::<Point>::new();
let children_ids = shape.modified_children_ids(structure.get(&shape.id), true);
for child_id in children_ids.iter() {
let Some(child) = shapes.get(child_id) else {
for child_id in shape.modified_children_ids_iter(structure.get(&shape.id), true) {
let Some(child) = shapes.get(&child_id) else {
continue;
};
let child_bounds = bounds.find(child);
result.append(&mut child_bounds.points());
}
shape_bounds.with_points(result)
}
@@ -277,11 +274,14 @@ fn propagate_reflow(
let shapes = &state.shapes;
let mut reflow_parent = false;
if reflown.contains(&id) {
return;
}
match &shape.shape_type {
Type::Frame(Frame {
layout: Some(_), ..
}) => {
if !reflown.contains(id) {
let mut skip_reflow = false;
if shape.is_layout_horizontal_fill() || shape.is_layout_vertical_fill() {
if let Some(parent_id) = shape.parent_id {
@@ -302,7 +302,6 @@ fn propagate_reflow(
layout_reflows.push(*id);
}
}
}
Type::Group(Group { masked: true }) => {
let children_ids = shape.modified_children_ids(state.structure.get(&shape.id), true);
if let Some(child) = shapes.get(&children_ids[0]) {
@@ -310,6 +309,7 @@ fn propagate_reflow(
bounds.insert(shape.id, child_bounds);
reflow_parent = true;
}
reflown.insert(*id);
}
Type::Group(_) => {
if let Some(shape_bounds) =
@@ -318,6 +318,7 @@ fn propagate_reflow(
bounds.insert(shape.id, shape_bounds);
reflow_parent = true;
}
reflown.insert(*id);
}
Type::Bool(_) => {
if let Some(shape_bounds) =
@@ -326,6 +327,7 @@ fn propagate_reflow(
bounds.insert(shape.id, shape_bounds);
reflow_parent = true;
}
reflown.insert(*id);
}
_ => {
// Other shapes don't have to be reflown