Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

optimization: collect composition effects before applying them #925

Open
Tropix126 opened this issue Sep 26, 2024 · 0 comments
Open

optimization: collect composition effects before applying them #925

Tropix126 opened this issue Sep 26, 2024 · 0 comments
Labels
enhancement 🔥 New feature or request

Comments

@Tropix126
Copy link
Contributor

Tropix126 commented Sep 26, 2024

Certain properties such as opacity and transform are applied to an element based on the state of its parents. For example, a parent with opacity: 0.5 must propagate its opacity down to children.

Normally this effect is achieved through creating a new canvas layer with a certain opacity when a parent node has opacity < 1.0, then merging that layer back into the canvas after rendering the children, but this isn't possible with Freya's compositor due to the layering system resulting children of a parent node being potentially rendered after other siblings of the parent are drawn (freya draws layers from the bottom up rather than recursively drawing parent -> child).

To get around this, we currently propagate a list of opacity/rotation values down the node tree in TransformState as a Vec<f32>. This is then looped over in the rendering pipeline and applied to each child manually.

// Apply inherited opacity effects
for opacity in &node_transform.opacities {
dirty_canvas.save_layer_alpha_f(
Rect::new(
self.canvas_area.min_x(),
self.canvas_area.min_y(),
self.canvas_area.max_x(),
self.canvas_area.max_y(),
),
*opacity,
);
}

The potential problem here is that a new canvas layer is created for each parent opacity value, which has some potential overhead (i'm not sure exactly how much, but each layer save requires skia to perform compositing). Rather than saving a new layer for each parent node's opacity, we can instead do one of the following:

  • Option A (less efficient, but easier): Calculate the final opacity of the child node ahead of time, and only save a single layer per child with that opacity once.
  • Option B (more efficient, requires possible refactor): Ensure that children of a parent node are rendered immediately after the parent if they are on the same layer. Call save_layer_alpha_f() when the parent is drawn, then restore() after drawing the last child, which will prevent the need to allocate a Vec<f32> for each node and also cut down on layer saves by only requiring one for the parent rather than one for each child.
    • This would require a refactor to how layers are assigned. Children would need to be on the same layer as the parent unless otherwise specified and rely on NodeId ordering to be drawn later.
@marc2332 marc2332 added the enhancement 🔥 New feature or request label Sep 26, 2024
@marc2332 marc2332 moved this to Idea in Freya Planning Sep 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement 🔥 New feature or request
Projects
Status: Idea
Development

No branches or pull requests

2 participants