You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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.
The text was updated successfully, but these errors were encountered:
Certain properties such as
opacity
andtransform
are applied to an element based on the state of its parents. For example, a parent withopacity: 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 aVec<f32>
. This is then looped over in the rendering pipeline and applied to each child manually.freya/crates/core/src/render/pipeline.rs
Lines 220 to 231 in dab3178
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:
save_layer_alpha_f()
when the parent is drawn, thenrestore()
after drawing the last child, which will prevent the need to allocate aVec<f32>
for each node and also cut down on layer saves by only requiring one for the parent rather than one for each child.NodeId
ordering to be drawn later.The text was updated successfully, but these errors were encountered: