ferroui_base/rendering/composition/server/server_composition_visual/
computed_properties.rs1use super::ServerCompositionVisual;
2use crate::platform::LtrbRect;
3use crate::Matrix;
4
5impl ServerCompositionVisual {
6 pub fn own_transform(&self) -> Option<Matrix> {
7 self.own_transform.get()
8 }
9
10 pub fn sub_tree_bounds(&self) -> Option<LtrbRect> {
11 self.sub_tree_bounds.get()
12 }
13
14 pub fn transformed_sub_tree_bounds(&self) -> Option<LtrbRect> {
15 self.transformed_sub_tree_bounds.get()
16 }
17
18 pub fn compute_own_content_bounds(&self) -> Option<LtrbRect> {
19 self.content.compute_own_content_bounds(self)
20 }
21
22 pub fn combined_transform_matrix(&self) -> Matrix {
23 self.combined_transform_matrix.get()
24 }
25
26 pub fn has_pending_render_changes(&self) -> bool {
30 self.is_dirty_for_render.get()
31 || self.is_dirty_for_render_in_subgraph.get()
32 || self.needs_bounding_box_update.get()
33 || self.needs_to_add_extra_dirty_rect_to_dirty_region.get()
34 }
35
36 pub(super) fn propagate_flags(
66 &self,
67 needs_bounding_box_update: bool,
68 dirty_for_render: bool,
69 additional_dirty_region: bool,
70 ) {
71 if let Some(root) = self.root() {
72 root.request_update();
73 }
74
75 let mut parent = self.parent();
76 let set_is_dirty_for_render_in_subgraph = additional_dirty_region || dirty_for_render;
77 while let Some(p) = parent {
78 if !((needs_bounding_box_update && !p.needs_bounding_box_update.get())
79 || (set_is_dirty_for_render_in_subgraph && !p.is_dirty_for_render_in_subgraph.get()))
80 {
81 break;
82 }
83 p.needs_bounding_box_update.set(p.needs_bounding_box_update.get() | needs_bounding_box_update);
84 p.is_dirty_for_render_in_subgraph
85 .set(p.is_dirty_for_render_in_subgraph.get() | set_is_dirty_for_render_in_subgraph);
86 parent = p.parent();
87 }
88
89 self.needs_bounding_box_update.set(self.needs_bounding_box_update.get() | needs_bounding_box_update);
90 self.is_dirty_for_render.set(self.is_dirty_for_render.get() | dirty_for_render);
91
92 self.needs_to_add_extra_dirty_rect_to_dirty_region.set(
94 !dirty_for_render && (self.needs_to_add_extra_dirty_rect_to_dirty_region.get() || additional_dirty_region),
95 );
96 }
97
98 pub fn recompute_own_properties(&self) {
99 let mut set_dirty_bounds = self.content_changed.get() || self.delay_propagate_needs_bounds_update.get();
100 let mut set_dirty_for_render = self.content_changed.get() || self.delay_propagate_is_dirty_for_render.get();
101 let set_has_extra_dirty_rect = self.delay_propagate_has_extra_dirty_rects.get();
102
103 self.delay_propagate_is_dirty_for_render.set(false);
105 self.delay_propagate_has_extra_dirty_rects.set(false);
106
107 self.enqueued_for_own_properties_recompute.set(false);
108 if self.own_bounds_dirty.get() {
109 self.own_content_bounds
110 .set(self.compute_own_content_bounds().and_then(LtrbRect::null_if_zero_size));
111 set_dirty_for_render = true;
112 set_dirty_bounds = true;
113 }
114
115 if self.clip_size_dirty.get() {
116 let mut clip: Option<LtrbRect> = None;
117 if let Some(geometry) = self.clip() {
118 clip = Some(LtrbRect::from_rect(geometry.bounds()));
119 }
120 if self.clip_to_bounds() {
121 let size = self.size();
122 let bounds = LtrbRect::new(0.0, 0.0, size.x, size.y);
123 clip = Some(match clip {
124 Some(clip) => clip.intersect_or_empty(bounds),
125 None => bounds,
126 });
127 }
128 if let Some(shape) = self.composition_clip_shape() {
131 let bounds = shape.bounds();
132 clip = Some(match clip {
133 Some(clip) => clip.intersect_or_empty(bounds),
134 None => bounds,
135 });
136 }
137
138 if self.own_clip_rect.get() != clip {
139 self.own_clip_rect.set(clip);
140 set_dirty_for_render = true;
141 set_dirty_bounds = true;
142 }
143 }
144
145 if self.combined_transform_dirty.get() {
146 self.own_transform.set(self.compute_own_transform_from_properties(self.transform_matrix()));
150 if self.parent_for_transform().is_some() {
151 self.adorner_helper_enqueue_for_adorner_update();
152 }
153
154 set_dirty_for_render = true;
155 set_dirty_bounds = true;
156
157 self.att_helper_combined_transform_changed();
158 }
159
160 set_dirty_for_render |= self.composition_fields_dirty.get();
161
162 self.own_bounds_dirty.set(false);
163 self.clip_size_dirty.set(false);
164 self.combined_transform_dirty.set(false);
165 self.composition_fields_dirty.set(false);
166 self.propagate_flags(set_dirty_bounds, set_dirty_for_render, set_has_extra_dirty_rect);
167 }
168}