mirror of
https://github.com/penpot/penpot.git
synced 2025-12-12 06:24:17 +01:00
✨ Improve ancestors modifiers performance
This commit is contained in:
committed by
Alonso Torres
parent
544bedf7c2
commit
551a25661f
@@ -32,6 +32,7 @@ use crate::wapi;
|
|||||||
|
|
||||||
use crate::math;
|
use crate::math;
|
||||||
use crate::math::bools;
|
use crate::math::bools;
|
||||||
|
use indexmap::IndexSet;
|
||||||
|
|
||||||
pub use fonts::*;
|
pub use fonts::*;
|
||||||
pub use images::*;
|
pub use images::*;
|
||||||
@@ -1716,28 +1717,47 @@ impl RenderState {
|
|||||||
performance::end_measure!("rebuild_tiles");
|
performance::end_measure!("rebuild_tiles");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Invalidates extended rectangles and updates tiles for a set of shapes
|
||||||
|
///
|
||||||
|
/// This function takes a set of shape IDs and for each one:
|
||||||
|
/// 1. Invalidates the extrect cache
|
||||||
|
/// 2. Updates the tiles to ensure proper rendering
|
||||||
|
///
|
||||||
|
/// This is useful when you have a pre-computed set of shape IDs that need to be refreshed,
|
||||||
|
/// regardless of their relationship to other shapes (e.g., ancestors, descendants, or any other collection).
|
||||||
|
pub fn invalidate_and_update_tiles(
|
||||||
|
&mut self,
|
||||||
|
shape_ids: &IndexSet<Uuid>,
|
||||||
|
tree: &mut ShapesPool,
|
||||||
|
modifiers: &HashMap<Uuid, Matrix>,
|
||||||
|
) {
|
||||||
|
for shape_id in shape_ids {
|
||||||
|
if let Some(shape) = tree.get_mut(shape_id) {
|
||||||
|
shape.invalidate_extrect();
|
||||||
|
}
|
||||||
|
if let Some(shape) = tree.get(shape_id) {
|
||||||
|
if !shape.id.is_nil() {
|
||||||
|
self.update_tile_for(shape, tree, modifiers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Processes all ancestors of a shape, invalidating their extended rectangles and updating their tiles
|
/// Processes all ancestors of a shape, invalidating their extended rectangles and updating their tiles
|
||||||
///
|
///
|
||||||
/// When a shape changes, all its ancestors need to have their extended rectangles recalculated
|
/// When a shape changes, all its ancestors need to have their extended rectangles recalculated
|
||||||
/// because they may contain the changed shape. This function:
|
/// because they may contain the changed shape. This function:
|
||||||
/// 1. Invalidates the extrect cache for each ancestor
|
/// 1. Computes all ancestors of the shape
|
||||||
/// 2. Updates the tiles for each ancestor to ensure proper rendering
|
/// 2. Invalidates the extrect cache for each ancestor
|
||||||
|
/// 3. Updates the tiles for each ancestor to ensure proper rendering
|
||||||
pub fn process_shape_ancestors(
|
pub fn process_shape_ancestors(
|
||||||
&mut self,
|
&mut self,
|
||||||
shape: &Shape,
|
shape: &Shape,
|
||||||
tree: &mut ShapesPool,
|
tree: &mut ShapesPool,
|
||||||
modifiers: &HashMap<Uuid, Matrix>,
|
modifiers: &HashMap<Uuid, Matrix>,
|
||||||
) {
|
) {
|
||||||
for ancestor in shape.all_ancestors(tree, false) {
|
let ancestors = shape.all_ancestors(tree, false);
|
||||||
if let Some(ancestor) = tree.get_mut(&ancestor) {
|
self.invalidate_and_update_tiles(&ancestors, tree, modifiers);
|
||||||
ancestor.invalidate_extrect();
|
|
||||||
}
|
|
||||||
if let Some(ancestor) = tree.get(&ancestor) {
|
|
||||||
if !ancestor.id.is_nil() {
|
|
||||||
self.update_tile_for(ancestor, tree, modifiers);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rebuilds tiles for shapes with modifiers and processes their ancestors
|
/// Rebuilds tiles for shapes with modifiers and processes their ancestors
|
||||||
@@ -1751,18 +1771,21 @@ impl RenderState {
|
|||||||
tree: &mut ShapesPool,
|
tree: &mut ShapesPool,
|
||||||
modifiers: &HashMap<Uuid, Matrix>,
|
modifiers: &HashMap<Uuid, Matrix>,
|
||||||
) {
|
) {
|
||||||
|
let mut ancestors = IndexSet::new();
|
||||||
for (uuid, matrix) in modifiers {
|
for (uuid, matrix) in modifiers {
|
||||||
let mut shape = {
|
let mut shape = {
|
||||||
let Some(shape) = tree.get(uuid) else {
|
let Some(shape) = tree.get(uuid) else {
|
||||||
panic!("Invalid current shape")
|
panic!("Invalid current shape")
|
||||||
};
|
};
|
||||||
shape.clone()
|
let shape: Cow<Shape> = Cow::Borrowed(shape);
|
||||||
|
shape
|
||||||
};
|
};
|
||||||
|
|
||||||
shape.apply_transform(matrix);
|
shape.to_mut().apply_transform(matrix);
|
||||||
self.update_tile_for(&shape, tree, modifiers);
|
ancestors.insert(*uuid);
|
||||||
self.process_shape_ancestors(&shape, tree, modifiers);
|
ancestors.extend(shape.all_ancestors(tree, false));
|
||||||
}
|
}
|
||||||
|
self.invalidate_and_update_tiles(&ancestors, tree, modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_scale(&self) -> f32 {
|
pub fn get_scale(&self) -> f32 {
|
||||||
|
|||||||
Reference in New Issue
Block a user