Merge pull request #6671 from penpot/azazeln28-refactor-minor-perf-issues

♻️ Refactor some minor perf issues
This commit is contained in:
Alejandro Alonso 2025-06-17 11:30:43 +02:00 committed by GitHub
commit 8c6a80829f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -49,6 +49,10 @@ pub struct NodeRenderState {
} }
impl NodeRenderState { impl NodeRenderState {
pub fn is_root(&self) -> bool {
self.id.is_nil()
}
pub fn get_children_clip_bounds( pub fn get_children_clip_bounds(
&self, &self,
element: &Shape, element: &Shape,
@ -629,6 +633,7 @@ impl RenderState {
&& performance::get_time() - timestamp > MAX_BLOCKING_TIME_MS && performance::get_time() - timestamp > MAX_BLOCKING_TIME_MS
} }
#[inline]
pub fn render_shape_enter(&mut self, element: &mut Shape, mask: bool) { pub fn render_shape_enter(&mut self, element: &mut Shape, mask: bool) {
// Masked groups needs two rendering passes, the first one rendering // Masked groups needs two rendering passes, the first one rendering
// the content and the second one rendering the mask so we need to do // the content and the second one rendering the mask so we need to do
@ -672,6 +677,7 @@ impl RenderState {
.save_layer(&layer_rec); .save_layer(&layer_rec);
} }
#[inline]
pub fn render_shape_exit(&mut self, element: &mut Shape, visited_mask: bool) { pub fn render_shape_exit(&mut self, element: &mut Shape, visited_mask: bool) {
if visited_mask { if visited_mask {
// Because masked groups needs two rendering passes (first drawing // Because masked groups needs two rendering passes (first drawing
@ -682,6 +688,33 @@ impl RenderState {
self.surfaces.canvas(SurfaceId::Current).restore(); self.surfaces.canvas(SurfaceId::Current).restore();
} }
} }
} else {
// !visited_mask
if let Type::Group(group) = element.shape_type {
// When we're dealing with masked groups we need to
// do a separate extra step to draw the mask (the last
// element of a masked group) and blend (using
// the blend mode 'destination-in') the content
// of the group and the mask.
if group.masked {
self.pending_nodes.push(NodeRenderState {
id: element.id,
visited_children: true,
clip_bounds: None,
visited_mask: true,
mask: false,
});
if let Some(&mask_id) = element.mask_id() {
self.pending_nodes.push(NodeRenderState {
id: mask_id,
visited_children: false,
clip_bounds: None,
visited_mask: false,
mask: true,
});
}
}
}
} }
if let Type::Group(_) = element.shape_type { if let Type::Group(_) = element.shape_type {
self.nested_fills.pop(); self.nested_fills.pop();
@ -757,38 +790,11 @@ impl RenderState {
} }
if visited_children { if visited_children {
if !visited_mask {
if let Type::Group(group) = element.shape_type {
// When we're dealing with masked groups we need to
// do a separate extra step to draw the mask (the last
// element of a masked group) and blend (using
// the blend mode 'destination-in') the content
// of the group and the mask.
if group.masked {
self.pending_nodes.push(NodeRenderState {
id: node_id,
visited_children: true,
clip_bounds: None,
visited_mask: true,
mask: false,
});
if let Some(&mask_id) = element.mask_id() {
self.pending_nodes.push(NodeRenderState {
id: mask_id,
visited_children: false,
clip_bounds: None,
visited_mask: false,
mask: true,
});
}
}
}
}
self.render_shape_exit(element, visited_mask); self.render_shape_exit(element, visited_mask);
continue; continue;
} }
if !node_render_state.id.is_nil() { if !node_render_state.is_root() {
let mut transformed_element: Cow<Shape> = Cow::Borrowed(element); let mut transformed_element: Cow<Shape> = Cow::Borrowed(element);
if let Some(modifier) = modifiers.get(&node_id) { if let Some(modifier) = modifiers.get(&node_id) {
@ -809,14 +815,14 @@ impl RenderState {
} }
self.render_shape_enter(element, mask); self.render_shape_enter(element, mask);
if !node_render_state.id.is_nil() { if !node_render_state.is_root() {
self.render_shape( self.render_shape(
element, element,
modifiers.get(&element.id), modifiers.get(&element.id),
scale_content.get(&element.id), scale_content.get(&element.id),
clip_bounds, clip_bounds,
); );
} else { } else if visited_children {
self.apply_drawing_to_render_canvas(Some(element)); self.apply_drawing_to_render_canvas(Some(element));
} }