cranpose_render_common/
layer_composition.rs1use cranpose_ui_graphics::{BlendMode, CompositingStrategy, GraphicsLayer, RenderEffect};
2
3#[derive(Clone)]
5pub struct LayerIsolation {
6 pub effect: Option<RenderEffect>,
8 pub blend_mode: BlendMode,
10 pub composite_alpha: f32,
13}
14
15pub fn layer_requires_isolation(layer: &GraphicsLayer) -> bool {
18 let has_effect = layer.render_effect.is_some();
19 let has_layer_blend = layer.blend_mode != BlendMode::SrcOver;
20 match layer.compositing_strategy {
21 CompositingStrategy::Offscreen => true,
22 CompositingStrategy::Auto => has_effect || has_layer_blend || layer.alpha < 1.0,
23 CompositingStrategy::ModulateAlpha => has_effect || has_layer_blend,
24 }
25}
26
27fn isolation_composite_alpha(layer: &GraphicsLayer) -> f32 {
28 if layer.compositing_strategy == CompositingStrategy::ModulateAlpha {
29 1.0
30 } else {
31 GraphicsLayer::composite_alpha_8bit(layer.alpha)
32 }
33}
34
35pub fn folded_layer_alpha(layer: &GraphicsLayer) -> f32 {
38 if layer.compositing_strategy != CompositingStrategy::ModulateAlpha
39 && layer_requires_isolation(layer)
40 {
41 GraphicsLayer::composite_alpha_8bit(layer.alpha)
42 } else {
43 layer.alpha
44 }
45}
46
47pub fn effective_layer_isolation(layer: &GraphicsLayer) -> Option<LayerIsolation> {
50 layer_requires_isolation(layer).then(|| LayerIsolation {
51 effect: layer.render_effect.clone(),
52 blend_mode: layer.blend_mode,
53 composite_alpha: isolation_composite_alpha(layer),
54 })
55}
56
57pub fn layer_composite_params(layer: &GraphicsLayer) -> Option<(f32, BlendMode)> {
61 layer_requires_isolation(layer).then(|| (isolation_composite_alpha(layer), layer.blend_mode))
62}
63
64pub fn layer_for_content(
67 layer: &GraphicsLayer,
68 isolation: Option<&LayerIsolation>,
69) -> GraphicsLayer {
70 let mut content = layer.clone();
71 if isolation.is_some() && layer.compositing_strategy != CompositingStrategy::ModulateAlpha {
72 content.alpha = 1.0;
73 }
74 content
75}
76
77pub fn local_content_layer_for(layer: &GraphicsLayer) -> GraphicsLayer {
84 let alpha = if layer.compositing_strategy != CompositingStrategy::ModulateAlpha
85 && layer_requires_isolation(layer)
86 {
87 1.0
88 } else {
89 layer.alpha
90 };
91 GraphicsLayer {
92 alpha,
93 color_filter: layer.color_filter,
94 ..GraphicsLayer::default()
95 }
96}
97
98#[cfg(test)]
99#[path = "tests/layer_composition_tests.rs"]
100mod tests;