1use crate::display_list::{BackdropKey, DisplayList, PaintCommand, SurfacePartitionId};
2use crate::effects::{
3 BlendMode, ColorFilter, DropShadowEffect, GaussianBlur, blur_bounds, drop_shadow_bounds,
4};
5use crate::geometry::{RRect, union_rect};
6use crate::gradients::Brush;
7use crate::paint::FillRule;
8use crate::paths::{Path, ellipse_as_path, fallback_tolerance, rect_as_path, rrect_as_path};
9use incular_core::finite_or_zero;
10use incular_core::{Arena, ArenaId, Offset, Rect, Size, Transform};
11use std::{
12 any::{Any, TypeId},
13 cell::RefCell,
14 collections::HashMap,
15 rc::Rc,
16 sync::Arc,
17};
18
19#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
22pub struct LayerId(ArenaId);
23
24impl LayerId {
25 #[must_use]
28 pub const fn raw(self) -> u64 {
29 ((self.0.generation() as u64) << 32) | self.0.index() as u64
30 }
31}
32
33#[must_use]
37pub fn normalize_opacity(alpha: f32) -> f32 {
38 if alpha.is_finite() {
39 alpha.clamp(0., 1.)
40 } else {
41 0.
42 }
43}
44
45#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
46pub struct CompositorDiagnostics {
47 pub layers: u64,
48 pub picture_layers_repainted: u64,
49 pub transform_updates: u64,
50 pub clip_updates: u64,
51 pub layers_culled: u64,
52 pub opacity_updates: u64,
53 pub leader_publish_passes: u64,
56 pub leaders_published: u64,
59}
60
61#[derive(Clone, Copy, Debug, PartialEq)]
65pub struct FlattenedPicture {
66 pub layer: LayerId,
67 pub local_bounds: Rect,
68 pub world_bounds: Rect,
69 pub active_clip: Option<Rect>,
70}
71
72#[derive(Clone)]
79pub struct Annotation {
80 value: Rc<dyn Any>,
81 type_id: TypeId,
82}
83impl Annotation {
84 #[must_use]
85 pub fn new<T: Any>(value: T) -> Self {
86 Self {
87 value: Rc::new(value),
88 type_id: TypeId::of::<T>(),
89 }
90 }
91 #[must_use]
92 pub const fn value_type_id(&self) -> TypeId {
93 self.type_id
94 }
95 #[must_use]
96 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
97 self.value.downcast_ref::<T>()
98 }
99 #[must_use]
100 pub fn cloned<T: Any + Clone>(&self) -> Option<T> {
101 self.downcast_ref::<T>().cloned()
102 }
103}
104impl std::fmt::Debug for Annotation {
105 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
106 formatter
107 .debug_struct("Annotation")
108 .field("type_id", &self.type_id)
109 .finish_non_exhaustive()
110 }
111}
112impl PartialEq for Annotation {
113 fn eq(&self, other: &Self) -> bool {
114 self.type_id == other.type_id && Rc::ptr_eq(&self.value, &other.value)
115 }
116}
117
118#[derive(Clone, Copy, Debug, Default, PartialEq)]
121pub struct LayerAnchor {
122 pub x: f32,
123 pub y: f32,
124}
125impl LayerAnchor {
126 pub const TOP_LEFT: Self = Self { x: -1., y: -1. };
127
128 #[must_use]
129 pub fn new(x: f32, y: f32) -> Self {
130 Self {
131 x: finite_or_zero(x),
132 y: finite_or_zero(y),
133 }
134 }
135 #[must_use]
136 pub const fn along_size(self, size: Size) -> Offset {
137 Offset::new(
138 size.width * (self.x + 1.) * 0.5,
139 size.height * (self.y + 1.) * 0.5,
140 )
141 }
142}
143
144fn clip_world_bounds(kind: &LayerKind, world_transform: Transform) -> Option<Rect> {
149 match kind {
150 LayerKind::ClipRect { rect, .. } => Some(world_transform.transform_rect_bbox(*rect)),
151 LayerKind::ClipRRect { rrect, .. } => Some(world_transform.transform_rect_bbox(rrect.rect)),
152 LayerKind::ClipOval { rect, .. } => Some(world_transform.transform_rect_bbox(*rect)),
153 LayerKind::ClipPath { path, .. } => path
154 .bounds()
155 .map(|bounds| world_transform.transform_rect_bbox(bounds)),
156 _ => None,
157 }
158}
159
160#[derive(Clone, Copy, Debug, PartialEq)]
164enum ClipSpace {
165 Translation,
166 Scale { x: f32, y: f32 },
167 General,
168}
169
170fn clip_space(world: Transform) -> ClipSpace {
171 let [a, b, c, d, _, _] = world.to_kurbo().as_coeffs();
172 if b == 0. && c == 0. {
173 if a == 1. && d == 1. {
174 ClipSpace::Translation
175 } else {
176 ClipSpace::Scale {
177 x: a as f32,
178 y: d as f32,
179 }
180 }
181 } else {
182 ClipSpace::General
183 }
184}
185
186#[must_use]
191pub fn resolve_follower_target(
192 leader_transform: Transform,
193 leader_size: Size,
194 target_anchor: LayerAnchor,
195 offset: Offset,
196) -> Offset {
197 let target_point = leader_transform.transform_point(target_anchor.along_size(leader_size));
198 let leader_origin = leader_transform.transform_point(Offset::ZERO);
199 target_point + (leader_transform.transform_point(offset) - leader_origin)
200}
201
202#[derive(Clone, Debug)]
208struct ResolvedClipPath {
209 world: Transform,
210 path: Arc<Path>,
211}
212
213#[derive(Clone, Debug)]
214struct LeaderData {
215 owner: PublisherIdentity,
216 transform: Transform,
217 size: Size,
218 generation: u64,
219}
220
221struct LeaderRecord {
225 id: LayerId,
226 link: LayerLink,
227 size: Size,
228 publisher: PublisherIdentity,
229 generation: u64,
230}
231
232#[derive(Clone, Copy, PartialEq, Eq)]
233enum PublishState {
234 InProgress,
235 Published,
236 Unresolvable,
237}
238
239#[derive(Clone, Debug)]
245pub struct PublisherIdentity(Rc<()>);
246impl PublisherIdentity {
247 pub(crate) fn new() -> Self {
248 Self(Rc::new(()))
249 }
250 #[must_use]
253 pub fn same_owner(&self, other: &Self) -> bool {
254 Rc::ptr_eq(&self.0, &other.0)
255 }
256}
257
258#[derive(Clone)]
261pub struct LayerLink(Rc<RefCell<Option<LeaderData>>>);
262impl Default for LayerLink {
263 fn default() -> Self {
264 Self::new()
265 }
266}
267impl std::fmt::Debug for LayerLink {
268 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
269 formatter
270 .debug_struct("LayerLink")
271 .field("linked", &self.is_linked())
272 .finish()
273 }
274}
275impl PartialEq for LayerLink {
276 fn eq(&self, other: &Self) -> bool {
277 Rc::ptr_eq(&self.0, &other.0)
278 }
279}
280impl LayerLink {
281 #[must_use]
282 pub fn new() -> Self {
283 Self(Rc::new(RefCell::new(None)))
284 }
285 #[must_use]
286 pub fn is_linked(&self) -> bool {
287 self.0.borrow().is_some()
288 }
289 #[must_use]
290 pub fn leader_size(&self) -> Option<Size> {
291 self.0.borrow().as_ref().map(|leader| leader.size)
292 }
293 #[must_use]
294 pub fn leader_transform(&self) -> Option<Transform> {
295 self.0.borrow().as_ref().map(|leader| leader.transform)
296 }
297 #[must_use]
298 pub fn leader_generation(&self) -> u64 {
299 self.0
300 .borrow()
301 .as_ref()
302 .map_or(0, |leader| leader.generation)
303 }
304 fn clear_if_owned_by(&self, owner: &PublisherIdentity) {
307 let mut state = self.0.borrow_mut();
308 if state
309 .as_ref()
310 .is_some_and(|leader| leader.owner.same_owner(owner))
311 {
312 *state = None;
313 }
314 }
315 fn clear_publication(&self) {
318 *self.0.borrow_mut() = None;
319 }
320 fn publish(&self, owner: PublisherIdentity, transform: Transform, size: Size, generation: u64) {
321 let mut state = self.0.borrow_mut();
325 if state.is_none() {
326 *state = Some(LeaderData {
327 owner,
328 transform,
329 size,
330 generation,
331 });
332 }
333 }
334}
335
336#[derive(Clone, Debug, PartialEq)]
340pub struct FlattenedAnnotation {
341 pub annotation: Annotation,
342 pub world_bounds: Option<Rect>,
343}
344
345#[derive(Clone, Debug)]
346pub enum LayerKind {
347 Picture {
348 display_list: Arc<DisplayList>,
349 bounds: Rect,
350 },
351 Transform {
352 transform: Transform,
353 },
354 ClipRect {
355 rect: Rect,
356 },
357 ClipRRect {
358 rrect: RRect,
359 },
360 ClipOval {
361 rect: Rect,
362 },
363 ClipPath {
364 path: Arc<Path>,
365 fill_rule: FillRule,
366 },
367 Opacity {
368 alpha: f32,
369 },
370 Blur {
371 blur: GaussianBlur,
372 },
373 DropShadow {
374 shadow: DropShadowEffect,
375 },
376 ColorFilter {
378 filter: Box<ColorFilter>,
379 },
380 Blend {
381 mode: BlendMode,
382 },
383 ShaderMask {
384 shader: Box<Brush>,
385 blend_mode: BlendMode,
386 mask_size: Size,
387 mask_transform: Box<Transform>,
388 },
389 BackdropFilter {
390 blur: GaussianBlur,
391 blend_mode: BlendMode,
392 enabled: bool,
393 matrix: Option<Transform>,
396 backdrop_key: Option<BackdropKey>,
398 },
399 AnnotatedRegion {
400 annotation: Annotation,
401 sized: bool,
402 size: Size,
403 },
404 Leader {
405 link: LayerLink,
406 size: Size,
407 publisher: PublisherIdentity,
408 },
409 Follower(FollowerLayer),
410}
411
412#[derive(Clone, Debug, PartialEq)]
414pub struct FollowerLayer {
415 pub link: LayerLink,
416 pub show_when_unlinked: bool,
417 pub offset: Offset,
418 pub target_anchor: LayerAnchor,
419 pub follower_anchor: LayerAnchor,
420 pub size: Size,
421}
422
423#[derive(Clone, Debug)]
424struct Layer {
425 kind: LayerKind,
426 children: Vec<LayerId>,
427 surface_partition: Option<SurfacePartitionId>,
428 generation: u64,
429 clip_cache: Option<Box<ResolvedClipPath>>,
433 parent: Option<LayerId>,
436 cull: CullBounds,
439}
440
441#[derive(Clone, Copy, Debug)]
445enum CullBounds {
446 Unknown,
447 Known {
448 bounds: Option<Rect>,
449 cullable: bool,
454 },
455}
456
457fn next_generation(counter: &mut u64) -> u64 {
459 let generation = *counter;
460 *counter = generation
461 .checked_add(1)
462 .expect("layer generation exhausted");
463 generation
464}
465
466pub struct LayerTree {
470 layers: Arena<Layer>,
471 root: Option<LayerId>,
472 diagnostics: CompositorDiagnostics,
473 flattened_pictures: Vec<FlattenedPicture>,
474 flattened_annotations: Vec<FlattenedAnnotation>,
475 next_generation: u64,
476 annotation_layers: usize,
479 leader_layers: usize,
482 partition_layers: usize,
485 child_stack: Vec<LayerId>,
488 flatten_scratch: DisplayList,
491 flatten_published: DisplayList,
494}
495impl Default for LayerTree {
496 fn default() -> Self {
497 Self::new()
498 }
499}
500impl LayerTree {
501 #[must_use]
502 pub fn new() -> Self {
503 Self {
504 layers: Arena::new(),
505 root: None,
506 diagnostics: CompositorDiagnostics::default(),
507 flattened_pictures: Vec::new(),
508 flattened_annotations: Vec::new(),
509 next_generation: 1,
510 annotation_layers: 0,
511 leader_layers: 0,
512 partition_layers: 0,
513 child_stack: Vec::new(),
514 flatten_scratch: DisplayList::new(),
515 flatten_published: DisplayList::new(),
516 }
517 }
518 #[must_use]
519 pub fn diagnostics(&self) -> CompositorDiagnostics {
520 self.diagnostics
521 }
522 #[must_use]
523 pub fn root(&self) -> Option<LayerId> {
524 self.root
525 }
526 #[must_use]
529 pub fn layer(&self, id: LayerId) -> Option<(&LayerKind, &[LayerId])> {
530 self.layers
531 .get(id.0)
532 .map(|layer| (&layer.kind, layer.children.as_slice()))
533 }
534 #[doc(hidden)]
535 #[must_use]
536 pub fn contains(&self, id: LayerId) -> bool {
537 self.layers.contains(id.0)
538 }
539 pub fn set_root(&mut self, root: LayerId) {
540 self.root = Some(root);
541 }
542
543 #[must_use]
551 pub fn scene_bounds(&self) -> Option<Rect> {
552 self.root
553 .and_then(|root| self.visual_subtree_bounds(root, Transform::IDENTITY))
554 }
555 pub fn create_picture(&mut self, display_list: DisplayList, bounds: Rect) -> LayerId {
556 self.insert(LayerKind::Picture {
557 display_list: Arc::new(display_list),
558 bounds,
559 })
560 }
561 pub fn create_transform(&mut self, transform: Transform) -> LayerId {
562 self.insert(LayerKind::Transform { transform })
563 }
564 pub fn create_clip_rect(&mut self, rect: Rect) -> LayerId {
565 self.insert(LayerKind::ClipRect { rect })
566 }
567 pub fn create_clip_rrect(&mut self, rrect: RRect) -> LayerId {
570 self.insert(LayerKind::ClipRRect { rrect })
571 }
572 pub fn create_clip_oval(&mut self, rect: Rect) -> LayerId {
575 self.insert(LayerKind::ClipOval { rect })
576 }
577 pub fn create_clip_path(&mut self, path: Arc<Path>, fill_rule: FillRule) -> LayerId {
580 self.insert(LayerKind::ClipPath { path, fill_rule })
581 }
582 pub fn create_opacity(&mut self, alpha: f32) -> LayerId {
585 self.insert(LayerKind::Opacity {
586 alpha: normalize_opacity(alpha),
587 })
588 }
589 pub fn create_blur(&mut self, blur: GaussianBlur) -> LayerId {
591 self.insert(LayerKind::Blur {
592 blur: GaussianBlur::new(blur.sigma_x, blur.sigma_y),
593 })
594 }
595 pub fn create_drop_shadow(&mut self, shadow: DropShadowEffect) -> LayerId {
597 self.insert(LayerKind::DropShadow {
598 shadow: DropShadowEffect::asymmetric(
599 shadow.offset,
600 shadow.sigma_x,
601 shadow.sigma_y,
602 shadow.color,
603 ),
604 })
605 }
606 pub fn create_color_filter(&mut self, filter: ColorFilter) -> LayerId {
609 self.insert(LayerKind::ColorFilter {
610 filter: Box::new(filter),
611 })
612 }
613 pub fn create_blend(&mut self, mode: BlendMode) -> LayerId {
616 self.insert(LayerKind::Blend { mode })
617 }
618 pub fn create_shader_mask(
622 &mut self,
623 shader: Brush,
624 blend_mode: BlendMode,
625 mask_size: Size,
626 mask_transform: Transform,
627 ) -> LayerId {
628 self.insert(LayerKind::ShaderMask {
629 shader: Box::new(shader),
630 blend_mode,
631 mask_size,
632 mask_transform: Box::new(mask_transform),
633 })
634 }
635 pub fn create_backdrop_filter(
639 &mut self,
640 blur: GaussianBlur,
641 blend_mode: BlendMode,
642 enabled: bool,
643 ) -> LayerId {
644 self.insert(LayerKind::BackdropFilter {
645 blur: GaussianBlur::new(blur.sigma_x, blur.sigma_y),
646 blend_mode,
647 enabled,
648 matrix: None,
649 backdrop_key: None,
650 })
651 }
652 pub fn update_backdrop_matrix(&mut self, id: LayerId, matrix: Option<Transform>) -> bool {
655 let Some(layer) = self.layers.get_mut(id.0) else {
656 return false;
657 };
658 let LayerKind::BackdropFilter {
659 matrix: current, ..
660 } = &mut layer.kind
661 else {
662 return false;
663 };
664 if *current == matrix {
665 return false;
666 }
667 *current = matrix;
668 layer.generation = next_generation(&mut self.next_generation);
669 true
670 }
671 pub fn update_backdrop_key(&mut self, id: LayerId, key: Option<BackdropKey>) -> bool {
674 let Some(layer) = self.layers.get_mut(id.0) else {
675 return false;
676 };
677 let LayerKind::BackdropFilter {
678 backdrop_key: current,
679 ..
680 } = &mut layer.kind
681 else {
682 return false;
683 };
684 if *current == key {
685 return false;
686 }
687 *current = key;
688 layer.generation = next_generation(&mut self.next_generation);
689 true
690 }
691 pub fn create_annotated_region(
692 &mut self,
693 annotation: Annotation,
694 sized: bool,
695 size: Size,
696 ) -> LayerId {
697 self.insert(LayerKind::AnnotatedRegion {
698 annotation,
699 sized,
700 size,
701 })
702 }
703 pub fn create_leader(&mut self, link: LayerLink, size: Size) -> LayerId {
704 self.insert(LayerKind::Leader {
705 link,
706 size,
707 publisher: PublisherIdentity::new(),
708 })
709 }
710 pub fn create_follower(&mut self, follower: FollowerLayer) -> LayerId {
711 self.insert(LayerKind::Follower(follower))
712 }
713 fn insert(&mut self, kind: LayerKind) -> LayerId {
714 self.annotation_layers += usize::from(matches!(kind, LayerKind::AnnotatedRegion { .. }));
715 self.leader_layers += usize::from(matches!(kind, LayerKind::Leader { .. }));
716 let generation = next_generation(&mut self.next_generation);
717 let id = LayerId(self.layers.insert(Layer {
718 kind,
719 children: Vec::new(),
720 surface_partition: None,
721 generation,
722 clip_cache: None,
723 parent: None,
724 cull: CullBounds::Unknown,
725 }));
726 self.diagnostics.layers += 1;
727 id
728 }
729 pub fn remove(&mut self, id: LayerId) {
730 if let Some(layer) = self.layers.remove(id.0) {
731 self.flatten_published = DisplayList::new();
734 self.annotation_layers -=
735 usize::from(matches!(layer.kind, LayerKind::AnnotatedRegion { .. }));
736 self.leader_layers -= usize::from(matches!(layer.kind, LayerKind::Leader { .. }));
737 if let LayerKind::Leader {
742 link, publisher, ..
743 } = &layer.kind
744 {
745 link.clear_if_owned_by(publisher);
746 }
747 self.diagnostics.layers -= 1;
748 self.partition_layers -= usize::from(layer.surface_partition.is_some());
749 if let Some(parent) = layer.parent {
750 self.reset_cull_bounds(parent);
751 }
752 if self.root == Some(id) {
753 self.root = None;
754 }
755 }
758 }
759 pub fn set_children(&mut self, id: LayerId, children: Vec<LayerId>) {
760 let Some(layer) = self.layers.get_mut(id.0) else {
761 return;
762 };
763 if layer.children == children {
764 return;
765 }
766 let previous = std::mem::replace(&mut layer.children, children);
767 layer.generation = next_generation(&mut self.next_generation);
768 for child in previous {
769 if let Some(child) = self.layers.get_mut(child.0)
770 && child.parent == Some(id)
771 {
772 child.parent = None;
773 }
774 }
775 for index in 0.. {
776 let Some(child) = self
777 .layers
778 .get(id.0)
779 .and_then(|layer| layer.children.get(index).copied())
780 else {
781 break;
782 };
783 let Some(child) = self.layers.get_mut(child.0) else {
784 continue;
785 };
786 if let Some(old) = child.parent.replace(id).filter(|old| *old != id) {
789 self.reset_cull_bounds(old);
790 }
791 }
792 self.reset_cull_bounds(id);
793 }
794
795 pub fn set_surface_partition(&mut self, id: LayerId, partition: Option<SurfacePartitionId>) {
799 let Some(layer) = self.layers.get_mut(id.0) else {
800 return;
801 };
802 if layer.surface_partition == partition {
803 return;
804 }
805 let had_partition = layer.surface_partition.is_some();
806 layer.surface_partition = partition;
807 if had_partition != partition.is_some() {
808 if had_partition {
809 self.partition_layers -= 1;
810 } else {
811 self.partition_layers += 1;
812 }
813 self.reset_cull_bounds(id);
814 }
815 }
816
817 pub fn clear_surface_partitions(&mut self) {
820 if self.partition_layers == 0 {
821 return;
822 }
823 let ids = self
824 .layers
825 .iter()
826 .filter_map(|(raw, layer)| layer.surface_partition.is_some().then_some(LayerId(raw)))
827 .collect::<Vec<_>>();
828 for id in ids {
829 self.set_surface_partition(id, None);
830 }
831 }
832 pub fn update_picture(&mut self, id: LayerId, display_list: DisplayList, bounds: Rect) {
833 if let Some(layer) = self.layers.get_mut(id.0)
834 && let LayerKind::Picture {
835 display_list: current,
836 bounds: current_bounds,
837 } = &mut layer.kind
838 {
839 *current = Arc::new(display_list);
840 let moved = *current_bounds != bounds;
841 *current_bounds = bounds;
842 layer.generation = next_generation(&mut self.next_generation);
843 self.diagnostics.picture_layers_repainted += 1;
844 if moved {
845 self.reset_cull_bounds(id);
846 }
847 }
848 }
849 pub fn update_picture_if_changed(
855 &mut self,
856 id: LayerId,
857 display_list: &DisplayList,
858 bounds: Rect,
859 ) -> bool {
860 let Some(layer) = self.layers.get_mut(id.0) else {
861 return false;
862 };
863 let LayerKind::Picture {
864 display_list: current,
865 bounds: current_bounds,
866 } = &mut layer.kind
867 else {
868 return false;
869 };
870 if **current == *display_list && *current_bounds == bounds {
871 return false;
872 }
873 self.update_picture(id, display_list.clone(), bounds);
874 true
875 }
876 pub fn update_transform(&mut self, id: LayerId, transform: Transform) -> bool {
877 let Some(layer) = self.layers.get_mut(id.0) else {
878 return false;
879 };
880 let LayerKind::Transform { transform: current } = &mut layer.kind else {
881 return false;
882 };
883 if *current == transform {
884 return false;
885 }
886 *current = transform;
887 layer.generation = next_generation(&mut self.next_generation);
888 self.diagnostics.transform_updates += 1;
889 self.reset_cull_bounds(id);
890 true
891 }
892 pub fn update_clip(&mut self, id: LayerId, rect: Rect) -> bool {
893 let Some(layer) = self.layers.get_mut(id.0) else {
894 return false;
895 };
896 let LayerKind::ClipRect { rect: current } = &mut layer.kind else {
897 return false;
898 };
899 if *current == rect {
900 return false;
901 }
902 *current = rect;
903 layer.clip_cache = None;
904 layer.generation = next_generation(&mut self.next_generation);
905 self.diagnostics.clip_updates += 1;
906 true
907 }
908 pub fn update_clip_rrect(&mut self, id: LayerId, rrect: RRect) -> bool {
909 let Some(layer) = self.layers.get_mut(id.0) else {
910 return false;
911 };
912 let LayerKind::ClipRRect { rrect: current } = &mut layer.kind else {
913 return false;
914 };
915 if *current == rrect {
916 return false;
917 }
918 *current = rrect;
919 layer.clip_cache = None;
920 layer.generation = next_generation(&mut self.next_generation);
921 self.diagnostics.clip_updates += 1;
922 true
923 }
924 pub fn update_clip_oval(&mut self, id: LayerId, rect: Rect) -> bool {
925 let Some(layer) = self.layers.get_mut(id.0) else {
926 return false;
927 };
928 let LayerKind::ClipOval { rect: current } = &mut layer.kind else {
929 return false;
930 };
931 if *current == rect {
932 return false;
933 }
934 *current = rect;
935 layer.clip_cache = None;
936 layer.generation = next_generation(&mut self.next_generation);
937 self.diagnostics.clip_updates += 1;
938 true
939 }
940 pub fn update_clip_path(&mut self, id: LayerId, path: Arc<Path>, fill_rule: FillRule) -> bool {
941 let Some(layer) = self.layers.get_mut(id.0) else {
942 return false;
943 };
944 let LayerKind::ClipPath {
945 path: current_path,
946 fill_rule: current_rule,
947 } = &mut layer.kind
948 else {
949 return false;
950 };
951 if **current_path == *path && *current_rule == fill_rule {
952 return false;
953 }
954 *current_path = path;
955 *current_rule = fill_rule;
956 layer.clip_cache = None;
957 layer.generation = next_generation(&mut self.next_generation);
958 self.diagnostics.clip_updates += 1;
959 true
960 }
961 pub fn update_opacity(&mut self, id: LayerId, alpha: f32) -> bool {
965 let Some(layer) = self.layers.get_mut(id.0) else {
966 return false;
967 };
968 let LayerKind::Opacity { alpha: current } = &mut layer.kind else {
969 return false;
970 };
971 let alpha = normalize_opacity(alpha);
972 if *current == alpha {
973 return false;
974 }
975 *current = alpha;
976 self.diagnostics.opacity_updates += 1;
977 true
978 }
979 pub fn update_blur(&mut self, id: LayerId, blur: GaussianBlur) -> bool {
982 let Some(layer) = self.layers.get_mut(id.0) else {
983 return false;
984 };
985 let LayerKind::Blur { blur: current } = &mut layer.kind else {
986 return false;
987 };
988 let blur = GaussianBlur::new(blur.sigma_x, blur.sigma_y);
989 if *current == blur {
990 return false;
991 }
992 *current = blur;
993 true
994 }
995 pub fn update_drop_shadow(&mut self, id: LayerId, shadow: DropShadowEffect) -> bool {
999 let Some(layer) = self.layers.get_mut(id.0) else {
1000 return false;
1001 };
1002 let LayerKind::DropShadow { shadow: current } = &mut layer.kind else {
1003 return false;
1004 };
1005 let shadow = DropShadowEffect::asymmetric(
1006 shadow.offset,
1007 shadow.sigma_x,
1008 shadow.sigma_y,
1009 shadow.color,
1010 );
1011 if *current == shadow {
1012 return false;
1013 }
1014 *current = shadow;
1015 true
1016 }
1017 pub fn update_color_filter(&mut self, id: LayerId, filter: ColorFilter) -> bool {
1018 let Some(layer) = self.layers.get_mut(id.0) else {
1019 return false;
1020 };
1021 let LayerKind::ColorFilter { filter: current } = &mut layer.kind else {
1022 return false;
1023 };
1024 if **current == filter {
1025 return false;
1026 }
1027 **current = filter;
1028 true
1029 }
1030 pub fn update_blend(&mut self, id: LayerId, mode: BlendMode) -> bool {
1031 let Some(layer) = self.layers.get_mut(id.0) else {
1032 return false;
1033 };
1034 let LayerKind::Blend { mode: current } = &mut layer.kind else {
1035 return false;
1036 };
1037 if *current == mode {
1038 return false;
1039 }
1040 *current = mode;
1041 true
1042 }
1043 pub fn update_shader_mask(
1044 &mut self,
1045 id: LayerId,
1046 shader: Brush,
1047 blend_mode: BlendMode,
1048 mask_size: Size,
1049 mask_transform: Transform,
1050 ) -> bool {
1051 let Some(layer) = self.layers.get_mut(id.0) else {
1052 return false;
1053 };
1054 let LayerKind::ShaderMask {
1055 shader: current_shader,
1056 blend_mode: current_mode,
1057 mask_size: current_size,
1058 mask_transform: current_transform,
1059 } = &mut layer.kind
1060 else {
1061 return false;
1062 };
1063 if **current_shader == shader
1064 && *current_mode == blend_mode
1065 && *current_size == mask_size
1066 && **current_transform == mask_transform
1067 {
1068 return false;
1069 }
1070 **current_shader = shader;
1071 *current_mode = blend_mode;
1072 *current_size = mask_size;
1073 **current_transform = mask_transform;
1074 layer.generation = next_generation(&mut self.next_generation);
1075 true
1076 }
1077 pub fn update_shader_mask_blend(&mut self, id: LayerId, blend_mode: BlendMode) -> bool {
1078 let Some(layer) = self.layers.get_mut(id.0) else {
1079 return false;
1080 };
1081 let LayerKind::ShaderMask {
1082 blend_mode: current,
1083 ..
1084 } = &mut layer.kind
1085 else {
1086 return false;
1087 };
1088 if *current == blend_mode {
1089 return false;
1090 }
1091 *current = blend_mode;
1092 layer.generation = next_generation(&mut self.next_generation);
1093 true
1094 }
1095 pub fn update_backdrop_filter(
1096 &mut self,
1097 id: LayerId,
1098 blur: GaussianBlur,
1099 blend_mode: BlendMode,
1100 enabled: bool,
1101 ) -> bool {
1102 let Some(layer) = self.layers.get_mut(id.0) else {
1103 return false;
1104 };
1105 let LayerKind::BackdropFilter {
1106 blur: current_blur,
1107 blend_mode: current_mode,
1108 enabled: current_enabled,
1109 ..
1110 } = &mut layer.kind
1111 else {
1112 return false;
1113 };
1114 let blur = GaussianBlur::new(blur.sigma_x, blur.sigma_y);
1115 if *current_blur == blur && *current_mode == blend_mode && *current_enabled == enabled {
1116 return false;
1117 }
1118 *current_blur = blur;
1119 *current_mode = blend_mode;
1120 *current_enabled = enabled;
1121 layer.generation = next_generation(&mut self.next_generation);
1122 true
1123 }
1124 pub fn update_annotated_region(
1125 &mut self,
1126 id: LayerId,
1127 annotation: Annotation,
1128 sized: bool,
1129 size: Size,
1130 ) -> bool {
1131 let Some(layer) = self.layers.get_mut(id.0) else {
1132 return false;
1133 };
1134 let LayerKind::AnnotatedRegion {
1135 annotation: current_annotation,
1136 sized: current_sized,
1137 size: current_size,
1138 } = &mut layer.kind
1139 else {
1140 return false;
1141 };
1142 if *current_annotation == annotation && *current_sized == sized && *current_size == size {
1143 return false;
1144 }
1145 *current_annotation = annotation;
1146 *current_sized = sized;
1147 *current_size = size;
1148 layer.generation = next_generation(&mut self.next_generation);
1149 true
1150 }
1151 pub fn update_leader(&mut self, id: LayerId, link: LayerLink, size: Size) -> bool {
1152 let Some(layer) = self.layers.get_mut(id.0) else {
1153 return false;
1154 };
1155 let LayerKind::Leader {
1156 link: current_link,
1157 size: current_size,
1158 publisher,
1159 } = &mut layer.kind
1160 else {
1161 return false;
1162 };
1163 if *current_link == link && *current_size == size {
1164 return false;
1165 }
1166 current_link.clear_if_owned_by(publisher);
1169 *current_link = link;
1170 *current_size = size;
1171 layer.generation = next_generation(&mut self.next_generation);
1172 true
1173 }
1174 pub fn update_leader_size(&mut self, id: LayerId, size: Size) -> bool {
1175 let Some(layer) = self.layers.get_mut(id.0) else {
1176 return false;
1177 };
1178 let LayerKind::Leader { size: current, .. } = &mut layer.kind else {
1179 return false;
1180 };
1181 if *current == size {
1182 return false;
1183 }
1184 *current = size;
1185 layer.generation = next_generation(&mut self.next_generation);
1186 true
1187 }
1188 pub fn update_follower(&mut self, id: LayerId, follower: FollowerLayer) -> bool {
1189 let Some(layer) = self.layers.get_mut(id.0) else {
1190 return false;
1191 };
1192 let LayerKind::Follower(current) = &mut layer.kind else {
1193 return false;
1194 };
1195 if *current == follower {
1196 return false;
1197 }
1198 *current = follower;
1199 layer.generation = next_generation(&mut self.next_generation);
1200 true
1201 }
1202 #[must_use]
1205 pub fn flattened_pictures(&self) -> &[FlattenedPicture] {
1206 &self.flattened_pictures
1207 }
1208 #[must_use]
1209 pub fn flattened_annotations(&self) -> &[FlattenedAnnotation] {
1210 &self.flattened_annotations
1211 }
1212 #[must_use]
1216 pub fn find_annotation<T: Any + Clone>(&self, point: Offset) -> Option<T> {
1217 self.flattened_annotations.iter().find_map(|entry| {
1218 let in_bounds = entry
1219 .world_bounds
1220 .is_none_or(|bounds| bounds.contains(point));
1221 in_bounds.then(|| entry.annotation.cloned::<T>()).flatten()
1222 })
1223 }
1224 #[must_use]
1225 pub fn find_annotations<T: Any + Clone>(&self, point: Offset) -> Vec<T> {
1226 self.flattened_annotations
1227 .iter()
1228 .filter_map(|entry| {
1229 let in_bounds = entry
1230 .world_bounds
1231 .is_none_or(|bounds| bounds.contains(point));
1232 in_bounds.then(|| entry.annotation.cloned::<T>()).flatten()
1233 })
1234 .collect()
1235 }
1236 #[must_use]
1237 pub fn flatten(&mut self) -> DisplayList {
1238 let mut out = std::mem::take(&mut self.flatten_scratch);
1239 out.clear();
1240 self.flattened_pictures.clear();
1241 self.flattened_annotations.clear();
1242 if let Some(root) = self.root {
1243 self.publish_leader_links();
1248 self.flatten_layer(root, Transform::IDENTITY, None, &mut out);
1249 if self.annotation_layers > 0 {
1250 self.collect_annotations(root, Transform::IDENTITY, None);
1251 }
1252 }
1253 if out != self.flatten_published {
1254 self.flatten_published = out.deep_copy();
1255 }
1256 out.clear();
1259 self.flatten_scratch = out;
1260 self.flatten_published.clone()
1261 }
1262 fn clip_command(&mut self, id: LayerId, kind: &LayerKind, world: Transform) -> PaintCommand {
1270 match kind {
1271 LayerKind::ClipRect { rect, .. } => match clip_space(world) {
1272 ClipSpace::Translation | ClipSpace::Scale { .. } => PaintCommand::PushClip {
1273 rect: world.transform_rect_bbox(*rect),
1274 },
1275 ClipSpace::General => {
1276 let rect = *rect;
1277 PaintCommand::PushClipPath {
1278 path: self.memoized_fallback_path(id, move || rect_as_path(rect), world),
1279 fill_rule: FillRule::NonZero,
1280 }
1281 }
1282 },
1283 LayerKind::ClipRRect { rrect, .. } => match clip_space(world) {
1284 ClipSpace::Translation => PaintCommand::PushClipRRect {
1285 rrect: RRect::new(world.transform_rect_bbox(rrect.rect), rrect.radii),
1286 },
1287 ClipSpace::Scale { x, y } if x > 0. && x == y => PaintCommand::PushClipRRect {
1291 rrect: RRect::new(world.transform_rect_bbox(rrect.rect), rrect.radii.scaled(x)),
1292 },
1293 _ => {
1294 let (rect, radii) = (rrect.rect, rrect.radii);
1295 PaintCommand::PushClipPath {
1296 path: self.memoized_fallback_path(
1297 id,
1298 move || rrect_as_path(rect, radii, fallback_tolerance(world)),
1299 world,
1300 ),
1301 fill_rule: FillRule::NonZero,
1302 }
1303 }
1304 },
1305 LayerKind::ClipOval { rect, .. } => match clip_space(world) {
1306 ClipSpace::Translation | ClipSpace::Scale { .. } => PaintCommand::PushClipOval {
1308 rect: world.transform_rect_bbox(*rect),
1309 },
1310 ClipSpace::General => {
1311 let rect = *rect;
1312 PaintCommand::PushClipPath {
1313 path: self.memoized_fallback_path(
1314 id,
1315 move || ellipse_as_path(rect, fallback_tolerance(world)),
1316 world,
1317 ),
1318 fill_rule: FillRule::NonZero,
1319 }
1320 }
1321 },
1322 LayerKind::ClipPath {
1323 path, fill_rule, ..
1324 } => PaintCommand::PushClipPath {
1325 path: self.memoized_clip_path(id, path, world),
1326 fill_rule: *fill_rule,
1327 },
1328 _ => unreachable!("clip emitter received a non-clip layer"),
1329 }
1330 }
1331 fn memoized_clip_path(&mut self, id: LayerId, path: &Arc<Path>, world: Transform) -> Arc<Path> {
1336 if world == Transform::IDENTITY {
1337 return path.clone();
1338 }
1339 let owned = path.clone();
1340 self.memoized_fallback_path(id, move || owned.as_ref().clone(), world)
1341 }
1342 fn memoized_fallback_path(
1349 &mut self,
1350 id: LayerId,
1351 build: impl FnOnce() -> Path,
1352 world: Transform,
1353 ) -> Arc<Path> {
1354 if let Some(layer) = self.layers.get(id.0)
1355 && let Some(memo) = layer.clip_cache.as_ref()
1356 && memo.world == world
1357 {
1358 return memo.path.clone();
1359 }
1360 let resolved = Arc::new(build().transformed(world));
1361 if let Some(layer) = self.layers.get_mut(id.0) {
1362 layer.clip_cache = Some(Box::new(ResolvedClipPath {
1363 world,
1364 path: resolved.clone(),
1365 }));
1366 }
1367 resolved
1368 }
1369 fn reset_cull_bounds(&mut self, id: LayerId) {
1371 let mut current = Some(id);
1372 while let Some(layer) = current.and_then(|id| self.layers.get_mut(id.0)) {
1373 if matches!(layer.cull, CullBounds::Unknown) {
1374 break;
1375 }
1376 layer.cull = CullBounds::Unknown;
1377 current = layer.parent;
1378 }
1379 }
1380
1381 fn cull_bounds(&mut self, id: LayerId) -> (Option<Rect>, bool) {
1386 let Some(layer) = self.layers.get(id.0) else {
1387 return (None, true);
1388 };
1389 if let CullBounds::Known { bounds, cullable } = layer.cull {
1390 return (bounds, cullable);
1391 }
1392 let own_cullable = layer.surface_partition.is_none()
1393 && !matches!(
1394 layer.kind,
1395 LayerKind::Follower(_) | LayerKind::BackdropFilter { .. }
1396 );
1397 let (local, own_bounds) = match &layer.kind {
1398 LayerKind::Picture { bounds, .. } => (Transform::IDENTITY, Some(*bounds)),
1399 LayerKind::Transform { transform } => (*transform, None),
1400 _ => (Transform::IDENTITY, None),
1401 };
1402 let mut bounds = own_bounds;
1403 let mut cullable = own_cullable;
1404 for index in 0.. {
1405 let Some(child) = self
1406 .layers
1407 .get(id.0)
1408 .and_then(|layer| layer.children.get(index).copied())
1409 else {
1410 break;
1411 };
1412 let (child_bounds, child_cullable) = self.cull_bounds(child);
1413 cullable &= child_cullable;
1414 if let Some(child_bounds) = child_bounds {
1415 let child_bounds = local.transform_rect_bbox(child_bounds);
1416 bounds =
1417 Some(bounds.map_or(child_bounds, |bounds| union_rect(bounds, child_bounds)));
1418 }
1419 }
1420 if let Some(layer) = self.layers.get_mut(id.0) {
1421 layer.cull = CullBounds::Known { bounds, cullable };
1422 }
1423 (bounds, cullable)
1424 }
1425
1426 fn flatten_layer(
1427 &mut self,
1428 id: LayerId,
1429 world_transform: Transform,
1430 clip: Option<Rect>,
1431 out: &mut DisplayList,
1432 ) {
1433 if let Some(active) = clip {
1436 let (bounds, cullable) = self.cull_bounds(id);
1437 if cullable
1438 && bounds.is_none_or(|bounds| {
1439 !active.intersects(world_transform.transform_rect_bbox(bounds))
1440 })
1441 {
1442 self.diagnostics.layers_culled += 1;
1443 return;
1444 }
1445 }
1446 let partition = self
1447 .layers
1448 .get(id.0)
1449 .and_then(|layer| layer.surface_partition);
1450 if let Some(id) = partition {
1451 out.push(PaintCommand::PushSurfacePartition { id });
1452 }
1453 self.flatten_layer_contents(id, world_transform, clip, out);
1454 if partition.is_some() {
1455 out.push(PaintCommand::PopSurfacePartition);
1456 }
1457 }
1458
1459 fn visit_children(
1463 &mut self,
1464 id: LayerId,
1465 reverse: bool,
1466 mut visit: impl FnMut(&mut Self, LayerId),
1467 ) {
1468 let start = self.child_stack.len();
1469 if let Some(layer) = self.layers.get(id.0) {
1470 self.child_stack.extend_from_slice(&layer.children);
1471 }
1472 let end = self.child_stack.len();
1473 for index in start..end {
1474 let child = self.child_stack[if reverse {
1475 start + end - 1 - index
1476 } else {
1477 index
1478 }];
1479 visit(self, child);
1480 }
1481 self.child_stack.truncate(start);
1482 }
1483
1484 fn flatten_layer_contents(
1485 &mut self,
1486 id: LayerId,
1487 world_transform: Transform,
1488 clip: Option<Rect>,
1489 out: &mut DisplayList,
1490 ) {
1491 let Some(kind) = self.layers.get(id.0).map(|layer| layer.kind.clone()) else {
1492 return;
1493 };
1494 match kind {
1495 LayerKind::Picture {
1496 display_list,
1497 bounds,
1498 } => {
1499 let world = world_transform.transform_rect_bbox(bounds);
1500 if clip.is_some_and(|active| !active.intersects(world)) {
1501 self.diagnostics.layers_culled += 1;
1502 return;
1503 }
1504 self.flattened_pictures.push(FlattenedPicture {
1505 layer: id,
1506 local_bounds: bounds,
1507 world_bounds: world,
1508 active_clip: clip,
1509 });
1510 out.push(PaintCommand::PushTransform {
1511 transform: world_transform,
1512 });
1513 out.extend_from(&display_list);
1514 out.push(PaintCommand::PopTransform);
1515 }
1516 LayerKind::Transform { transform: local } => {
1517 let next = world_transform.then(local);
1518 self.visit_children(id, false, |tree, child| {
1519 tree.flatten_layer(child, next, clip, out)
1520 });
1521 }
1522 LayerKind::ClipRect { .. }
1523 | LayerKind::ClipRRect { .. }
1524 | LayerKind::ClipOval { .. }
1525 | LayerKind::ClipPath { .. } => {
1526 let Some(shape_bounds) = clip_world_bounds(&kind, world_transform) else {
1530 self.diagnostics.layers_culled += 1;
1531 return;
1532 };
1533 let next_clip = match clip {
1534 Some(active) => active.intersection(shape_bounds),
1535 None => Some(shape_bounds),
1536 };
1537 if next_clip.is_none() {
1538 self.diagnostics.layers_culled += 1;
1539 return;
1540 }
1541 out.push(self.clip_command(id, &kind, world_transform));
1542 self.visit_children(id, false, |tree, child| {
1543 tree.flatten_layer(child, world_transform, next_clip, out)
1544 });
1545 out.push(PaintCommand::PopClip);
1546 }
1547 LayerKind::Opacity { alpha } => {
1548 let bounds = self
1549 .subtree_bounds(id, world_transform)
1550 .unwrap_or_else(|| Rect::from_origin_size(Offset::ZERO, Size::ZERO));
1551 out.push(PaintCommand::PushOpacity {
1552 layer: id,
1553 alpha,
1554 generation: self.subtree_generation(id),
1555 bounds,
1556 });
1557 self.visit_children(id, false, |tree, child| {
1558 tree.flatten_layer(child, world_transform, clip, out)
1559 });
1560 out.push(PaintCommand::PopOpacity);
1561 }
1562 LayerKind::Blur { blur } => {
1563 let bounds = self
1564 .subtree_bounds(id, world_transform)
1565 .unwrap_or_else(|| Rect::from_origin_size(Offset::ZERO, Size::ZERO));
1566 out.push(PaintCommand::PushBlur {
1567 layer: id,
1568 blur,
1569 generation: self.subtree_generation(id),
1570 bounds,
1571 });
1572 self.visit_children(id, false, |tree, child| {
1573 tree.flatten_layer(child, world_transform, clip, out)
1574 });
1575 out.push(PaintCommand::PopEffect);
1576 }
1577 LayerKind::DropShadow { shadow } => {
1578 let bounds = self
1579 .subtree_bounds(id, world_transform)
1580 .unwrap_or_else(|| Rect::from_origin_size(Offset::ZERO, Size::ZERO));
1581 out.push(PaintCommand::PushDropShadow {
1582 layer: id,
1583 shadow,
1584 generation: self.subtree_generation(id),
1585 bounds,
1586 });
1587 self.visit_children(id, false, |tree, child| {
1588 tree.flatten_layer(child, world_transform, clip, out)
1589 });
1590 out.push(PaintCommand::PopEffect);
1591 }
1592 LayerKind::ColorFilter { filter } => {
1593 let bounds = self
1594 .subtree_bounds(id, world_transform)
1595 .unwrap_or_else(|| Rect::from_origin_size(Offset::ZERO, Size::ZERO));
1596 out.push(PaintCommand::PushColorFilter {
1597 layer: id,
1598 filter: *filter,
1599 generation: self.subtree_generation(id),
1600 bounds,
1601 });
1602 self.visit_children(id, false, |tree, child| {
1603 tree.flatten_layer(child, world_transform, clip, out)
1604 });
1605 out.push(PaintCommand::PopEffect);
1606 }
1607 LayerKind::Blend { mode } => {
1608 let bounds = self
1609 .subtree_bounds(id, world_transform)
1610 .unwrap_or_else(|| Rect::from_origin_size(Offset::ZERO, Size::ZERO));
1611 out.push(PaintCommand::PushBlend {
1612 layer: id,
1613 mode,
1614 generation: self.subtree_generation(id),
1615 bounds,
1616 });
1617 self.visit_children(id, false, |tree, child| {
1618 tree.flatten_layer(child, world_transform, clip, out)
1619 });
1620 out.push(PaintCommand::PopEffect);
1621 }
1622 LayerKind::ShaderMask {
1623 shader,
1624 blend_mode,
1625 mask_size,
1626 mask_transform,
1627 } => {
1628 let bounds = self
1629 .subtree_bounds(id, world_transform)
1630 .unwrap_or_else(|| Rect::from_origin_size(Offset::ZERO, Size::ZERO));
1631 if !bounds.size.width.is_finite()
1632 || !bounds.size.height.is_finite()
1633 || bounds.size.width <= 0.
1634 || bounds.size.height <= 0.
1635 {
1636 return;
1637 }
1638 out.push(PaintCommand::PushShaderMask {
1639 layer: id,
1640 shader: *shader,
1641 blend_mode,
1642 mask_size,
1643 mask_transform: *mask_transform,
1644 generation: self.subtree_generation(id),
1645 bounds,
1646 });
1647 self.visit_children(id, false, |tree, child| {
1648 tree.flatten_layer(child, world_transform, clip, out)
1649 });
1650 out.push(PaintCommand::PopEffect);
1651 }
1652 LayerKind::BackdropFilter {
1653 blur,
1654 blend_mode,
1655 enabled,
1656 matrix,
1657 backdrop_key,
1658 } => {
1659 if !crate::backdrop_filter_is_active(blur, enabled, matrix) {
1660 self.visit_children(id, false, |tree, child| {
1661 tree.flatten_layer(child, world_transform, clip, out)
1662 });
1663 return;
1664 }
1665 let bounds = self
1666 .subtree_bounds(id, world_transform)
1667 .unwrap_or_else(|| Rect::from_origin_size(Offset::ZERO, Size::ZERO));
1668 out.push(PaintCommand::PushBackdropFilter {
1669 layer: id,
1670 blur,
1671 blend_mode,
1672 enabled,
1673 matrix,
1674 backdrop_key,
1675 generation: self.subtree_generation(id),
1676 bounds,
1677 });
1678 self.visit_children(id, false, |tree, child| {
1679 tree.flatten_layer(child, world_transform, clip, out)
1680 });
1681 out.push(PaintCommand::PopEffect);
1682 }
1683 LayerKind::AnnotatedRegion { .. } => {
1684 self.visit_children(id, false, |tree, child| {
1685 tree.flatten_layer(child, world_transform, clip, out)
1686 });
1687 }
1688 LayerKind::Leader { .. } => {
1689 self.visit_children(id, false, |tree, child| {
1692 tree.flatten_layer(child, world_transform, clip, out)
1693 });
1694 }
1695 LayerKind::Follower(follower) => {
1696 let Some(next_transform) = self.follower_transform(world_transform, &follower)
1697 else {
1698 return;
1699 };
1700 self.visit_children(id, false, |tree, child| {
1701 tree.flatten_layer(child, next_transform, clip, out)
1702 });
1703 }
1704 }
1705 }
1706 fn clear_link_states(&self, id: LayerId) {
1707 let Some(layer) = self.layers.get(id.0) else {
1708 return;
1709 };
1710 if let LayerKind::Leader { link, .. } = &layer.kind {
1711 link.clear_publication();
1712 }
1713 for child in layer.children.iter() {
1714 self.clear_link_states(*child);
1715 }
1716 }
1717 pub fn publish_leader_links(&mut self) {
1723 if self.leader_layers == 0 {
1724 return;
1725 }
1726 if let Some(root) = self.root {
1727 self.clear_link_states(root);
1728 self.publish_resolved_leaders(root);
1729 }
1730 }
1731 fn publish_resolved_leaders(&mut self, root: LayerId) {
1740 self.diagnostics.leader_publish_passes += 1;
1741 let mut parents = HashMap::new();
1742 let mut leaders = Vec::new();
1743 self.collect_publish_state(root, &mut parents, &mut leaders);
1744 if leaders.is_empty() {
1745 return;
1746 }
1747 let mut states = HashMap::new();
1748 let mut published = 0;
1749 for index in 0..leaders.len() {
1750 published += self.ensure_published(index, &leaders, &parents, &mut states) as u64;
1751 }
1752 self.diagnostics.leaders_published += published;
1753 }
1754 fn collect_publish_state(
1755 &self,
1756 id: LayerId,
1757 parents: &mut HashMap<LayerId, LayerId>,
1758 leaders: &mut Vec<LeaderRecord>,
1759 ) {
1760 let Some(layer) = self.layers.get(id.0) else {
1761 return;
1762 };
1763 if let LayerKind::Leader {
1764 link,
1765 size,
1766 publisher,
1767 } = &layer.kind
1768 {
1769 leaders.push(LeaderRecord {
1770 id,
1771 link: link.clone(),
1772 size: *size,
1773 publisher: publisher.clone(),
1774 generation: layer.generation,
1775 });
1776 }
1777 for child in layer.children.iter() {
1778 parents.entry(*child).or_insert(id);
1779 self.collect_publish_state(*child, parents, leaders);
1780 }
1781 }
1782 fn ensure_published(
1783 &self,
1784 index: usize,
1785 leaders: &[LeaderRecord],
1786 parents: &HashMap<LayerId, LayerId>,
1787 states: &mut HashMap<LayerId, PublishState>,
1788 ) -> bool {
1789 let id = leaders[index].id;
1790 match states.get(&id) {
1791 Some(PublishState::Published) => return true,
1792 Some(PublishState::Unresolvable) => return false,
1793 Some(PublishState::InProgress) => {
1799 states.insert(id, PublishState::Unresolvable);
1800 return false;
1801 }
1802 None => {}
1803 }
1804 states.insert(id, PublishState::InProgress);
1805 let published = match self.leader_context(index, leaders, parents, states) {
1806 Some(world) => {
1807 let record = &leaders[index];
1808 record.link.publish(
1809 record.publisher.clone(),
1810 world,
1811 record.size,
1812 record.generation,
1813 );
1814 true
1815 }
1816 None => false,
1817 };
1818 states.insert(
1819 id,
1820 if published {
1821 PublishState::Published
1822 } else {
1823 PublishState::Unresolvable
1824 },
1825 );
1826 published
1827 }
1828 fn leader_context(
1837 &self,
1838 index: usize,
1839 leaders: &[LeaderRecord],
1840 parents: &HashMap<LayerId, LayerId>,
1841 states: &mut HashMap<LayerId, PublishState>,
1842 ) -> Option<Transform> {
1843 let mut chain = vec![leaders[index].id];
1844 while let Some(parent) = chain.last().and_then(|id| parents.get(id)) {
1845 chain.push(*parent);
1846 }
1847 let mut world = Transform::IDENTITY;
1848 let mut clip: Option<Rect> = None;
1849 for node in chain.iter().rev() {
1850 let layer = self.layers.get(node.0)?;
1851 match &layer.kind {
1852 LayerKind::Transform { transform } => {
1853 world = world.then(*transform);
1854 }
1855 LayerKind::Follower(follower) => {
1856 let link = &follower.link;
1857 if link.leader_transform().is_none() {
1858 for dependency in 0..leaders.len() {
1862 if leaders[dependency].link == *link {
1863 self.ensure_published(dependency, leaders, parents, states);
1864 if link.leader_transform().is_some() {
1865 break;
1866 }
1867 }
1868 }
1869 }
1870 match link.leader_transform() {
1871 Some(_) => {
1872 world = self.follower_transform(world, follower)?;
1873 }
1874 None if follower.show_when_unlinked => {}
1875 None => return None,
1876 }
1877 }
1878 LayerKind::ClipRect { .. }
1879 | LayerKind::ClipRRect { .. }
1880 | LayerKind::ClipOval { .. }
1881 | LayerKind::ClipPath { .. } => {
1882 let shape = clip_world_bounds(&layer.kind, world)?;
1883 clip = match clip {
1884 Some(active) => active.intersection(shape),
1885 None => Some(shape),
1886 };
1887 clip?;
1890 }
1891 _ => {}
1892 }
1893 }
1894 Some(world)
1895 }
1896 fn follower_transform(
1897 &self,
1898 world_transform: Transform,
1899 follower: &FollowerLayer,
1900 ) -> Option<Transform> {
1901 let FollowerLayer {
1902 link,
1903 show_when_unlinked,
1904 offset,
1905 target_anchor,
1906 follower_anchor,
1907 size,
1908 } = follower;
1909 let Some(leader_transform) = link.leader_transform() else {
1910 return show_when_unlinked.then_some(world_transform);
1911 };
1912 let leader_size = link.leader_size().unwrap_or(Size::ZERO);
1913 let desired_anchor =
1914 resolve_follower_target(leader_transform, leader_size, *target_anchor, *offset);
1915 let desired_local = world_transform.inverse_transform_point(desired_anchor)?;
1916 let local_delta = desired_local - follower_anchor.along_size(*size);
1917 Some(world_transform.then(Transform::translation(local_delta)))
1918 }
1919 fn collect_annotations(&mut self, id: LayerId, world_transform: Transform, clip: Option<Rect>) {
1920 let Some(kind) = self.layers.get(id.0).map(|layer| layer.kind.clone()) else {
1921 return;
1922 };
1923 match kind {
1924 LayerKind::Transform { transform } => {
1925 let next = world_transform.then(transform);
1926 self.visit_children(id, false, |tree, child| {
1927 tree.collect_annotations(child, next, clip)
1928 });
1929 }
1930 LayerKind::ClipRect { rect, .. } => {
1931 let world = world_transform.transform_rect_bbox(rect);
1932 let next_clip = match clip {
1933 Some(current) => current.intersection(world),
1934 None => Some(world),
1935 };
1936 if next_clip.is_none() {
1937 return;
1938 }
1939 self.visit_children(id, false, |tree, child| {
1940 tree.collect_annotations(child, world_transform, next_clip)
1941 });
1942 }
1943 LayerKind::ClipRRect { .. }
1944 | LayerKind::ClipOval { .. }
1945 | LayerKind::ClipPath { .. } => {
1946 let Some(world) = clip_world_bounds(&kind, world_transform) else {
1947 return;
1948 };
1949 let next_clip = match clip {
1950 Some(current) => current.intersection(world),
1951 None => Some(world),
1952 };
1953 if next_clip.is_none() {
1954 return;
1955 }
1956 self.visit_children(id, false, |tree, child| {
1957 tree.collect_annotations(child, world_transform, next_clip)
1958 });
1959 }
1960 LayerKind::Follower(follower) => {
1961 let Some(next) = self.follower_transform(world_transform, &follower) else {
1962 return;
1963 };
1964 self.visit_children(id, false, |tree, child| {
1965 tree.collect_annotations(child, next, clip)
1966 });
1967 }
1968 LayerKind::AnnotatedRegion {
1969 annotation,
1970 sized,
1971 size,
1972 } => {
1973 self.visit_children(id, true, |tree, child| {
1977 tree.collect_annotations(child, world_transform, clip)
1978 });
1979 let region =
1980 world_transform.transform_rect_bbox(Rect::from_origin_size(Offset::ZERO, size));
1981 let world_bounds = if sized {
1982 match clip {
1983 Some(active) => active.intersection(region),
1984 None => Some(region),
1985 }
1986 } else {
1987 clip
1988 };
1989 if world_bounds
1990 .is_none_or(|bounds| bounds.size.width > 0. && bounds.size.height > 0.)
1991 {
1992 self.flattened_annotations.push(FlattenedAnnotation {
1993 annotation,
1994 world_bounds,
1995 });
1996 }
1997 }
1998 LayerKind::Picture { .. }
1999 | LayerKind::Opacity { .. }
2000 | LayerKind::Blur { .. }
2001 | LayerKind::DropShadow { .. }
2002 | LayerKind::ColorFilter { .. }
2003 | LayerKind::Blend { .. }
2004 | LayerKind::ShaderMask { .. }
2005 | LayerKind::BackdropFilter { .. }
2006 | LayerKind::Leader { .. } => {
2007 self.visit_children(id, false, |tree, child| {
2008 tree.collect_annotations(child, world_transform, clip)
2009 });
2010 }
2011 }
2012 }
2013 fn subtree_generation(&self, id: LayerId) -> u64 {
2014 let Some(layer) = self.layers.get(id.0) else {
2015 return 0;
2016 };
2017 let mut value = layer.generation.wrapping_mul(0x9e37_79b9_7f4a_7c15);
2018 for child in &layer.children {
2019 if let Some(child_layer) = self.layers.get(child.0)
2027 && let LayerKind::Opacity { alpha } = &child_layer.kind
2028 {
2029 value = value.rotate_left(11) ^ u64::from(alpha.to_bits());
2030 }
2031 if let Some(child_layer) = self.layers.get(child.0) {
2032 match &child_layer.kind {
2033 LayerKind::Blur { blur } => {
2034 value = value.rotate_left(13)
2035 ^ u64::from(blur.sigma_x.to_bits())
2036 ^ u64::from(blur.sigma_y.to_bits()).rotate_left(17);
2037 }
2038 LayerKind::DropShadow { shadow } => {
2039 value = value.rotate_left(13)
2040 ^ u64::from(shadow.offset.x.to_bits())
2041 ^ u64::from(shadow.offset.y.to_bits()).rotate_left(7)
2042 ^ u64::from(shadow.sigma_x.to_bits()).rotate_left(17)
2043 ^ u64::from(shadow.sigma_y.to_bits()).rotate_left(23)
2044 ^ u64::from(shadow.color.red)
2045 ^ (u64::from(shadow.color.green) << 8)
2046 ^ (u64::from(shadow.color.blue) << 16)
2047 ^ (u64::from(shadow.color.alpha) << 24);
2048 }
2049 LayerKind::ColorFilter { filter } => {
2050 for (index, bits) in filter.to_matrix().map(f32::to_bits).iter().enumerate()
2051 {
2052 value ^= u64::from(*bits).rotate_left((index as u32 % 31) + 1);
2053 }
2054 }
2055 LayerKind::Blend { mode } => {
2056 value = value.rotate_left(13) ^ u64::from(mode.code());
2057 }
2058 LayerKind::ShaderMask {
2059 shader,
2060 blend_mode,
2061 mask_size,
2062 mask_transform,
2063 } => {
2064 value = value.rotate_left(13)
2065 ^ brush_generation(shader)
2066 ^ u64::from(blend_mode.code())
2067 ^ u64::from(mask_size.width.to_bits()).rotate_left(9)
2068 ^ u64::from(mask_size.height.to_bits()).rotate_left(15)
2069 ^ transform_generation(**mask_transform);
2070 }
2071 LayerKind::BackdropFilter {
2072 blur,
2073 blend_mode,
2074 enabled,
2075 matrix,
2076 backdrop_key: _,
2077 } => {
2078 value = value.rotate_left(13)
2079 ^ u64::from(blur.sigma_x.to_bits())
2080 ^ u64::from(blur.sigma_y.to_bits()).rotate_left(7)
2081 ^ u64::from(blend_mode.code())
2082 ^ u64::from(*enabled as u8);
2083 if let Some(matrix) = matrix {
2084 value ^= transform_generation(*matrix).rotate_left(21);
2085 }
2086 }
2087 LayerKind::AnnotatedRegion {
2088 annotation: _,
2089 sized,
2090 size,
2091 } => {
2092 value = value.rotate_left(13)
2093 ^ u64::from(*sized as u8)
2094 ^ u64::from(size.width.to_bits()).rotate_left(9)
2095 ^ u64::from(size.height.to_bits()).rotate_left(15);
2096 }
2097 LayerKind::Leader { link, size, .. } => {
2098 value = value.rotate_left(13)
2099 ^ link.leader_generation()
2100 ^ u64::from(size.width.to_bits()).rotate_left(9)
2101 ^ u64::from(size.height.to_bits()).rotate_left(15);
2102 }
2103 LayerKind::Follower(follower) => {
2104 value = value.rotate_left(13)
2105 ^ follower.link.leader_generation()
2106 ^ u64::from(follower.show_when_unlinked as u8)
2107 ^ u64::from(follower.offset.x.to_bits())
2108 ^ u64::from(follower.offset.y.to_bits()).rotate_left(7)
2109 ^ u64::from(follower.target_anchor.x.to_bits()).rotate_left(13)
2110 ^ u64::from(follower.target_anchor.y.to_bits()).rotate_left(17)
2111 ^ u64::from(follower.follower_anchor.x.to_bits()).rotate_left(21)
2112 ^ u64::from(follower.follower_anchor.y.to_bits()).rotate_left(25)
2113 ^ u64::from(follower.size.width.to_bits()).rotate_left(29)
2114 ^ u64::from(follower.size.height.to_bits()).rotate_left(31);
2115 }
2116 _ => {}
2117 }
2118 }
2119 value = value.rotate_left(7) ^ self.subtree_generation(*child);
2120 }
2121 value
2122 }
2123 fn subtree_bounds(&self, id: LayerId, world_transform: Transform) -> Option<Rect> {
2124 let layer = self.layers.get(id.0)?;
2125 match &layer.kind {
2126 LayerKind::Picture { bounds, .. } => Some(world_transform.transform_rect_bbox(*bounds)),
2127 LayerKind::Transform { transform: local } => layer
2128 .children
2129 .iter()
2130 .filter_map(|child| self.subtree_bounds(*child, world_transform.then(*local)))
2131 .reduce(union_rect),
2132 LayerKind::ClipRect { rect, .. } => {
2133 let world = world_transform.transform_rect_bbox(*rect);
2134 layer
2135 .children
2136 .iter()
2137 .filter_map(|child| self.subtree_bounds(*child, world_transform))
2138 .reduce(union_rect)
2139 .and_then(|bounds| bounds.intersection(world))
2140 }
2141 LayerKind::ClipRRect { .. }
2142 | LayerKind::ClipOval { .. }
2143 | LayerKind::ClipPath { .. } => {
2144 let world = clip_world_bounds(&layer.kind, world_transform)?;
2145 layer
2146 .children
2147 .iter()
2148 .filter_map(|child| self.subtree_bounds(*child, world_transform))
2149 .reduce(union_rect)
2150 .and_then(|bounds| bounds.intersection(world))
2151 }
2152 LayerKind::Opacity { .. } => layer
2153 .children
2154 .iter()
2155 .filter_map(|child| self.subtree_bounds(*child, world_transform))
2156 .reduce(union_rect),
2157 LayerKind::Blur { .. } | LayerKind::DropShadow { .. } => layer
2158 .children
2159 .iter()
2160 .filter_map(|child| self.subtree_bounds(*child, world_transform))
2161 .reduce(union_rect),
2162 LayerKind::ColorFilter { .. } | LayerKind::Blend { .. } => layer
2163 .children
2164 .iter()
2165 .filter_map(|child| self.subtree_bounds(*child, world_transform))
2166 .reduce(union_rect),
2167 LayerKind::ShaderMask { .. }
2168 | LayerKind::BackdropFilter { .. }
2169 | LayerKind::AnnotatedRegion { .. }
2170 | LayerKind::Leader { .. } => layer
2171 .children
2172 .iter()
2173 .filter_map(|child| self.subtree_bounds(*child, world_transform))
2174 .reduce(union_rect),
2175 LayerKind::Follower(follower) => {
2176 let next = self.follower_transform(world_transform, follower)?;
2177 layer
2178 .children
2179 .iter()
2180 .filter_map(|child| self.subtree_bounds(*child, next))
2181 .reduce(union_rect)
2182 }
2183 }
2184 }
2185
2186 fn visual_subtree_bounds(&self, id: LayerId, world_transform: Transform) -> Option<Rect> {
2187 let layer = self.layers.get(id.0)?;
2188 let child_bounds = |tree: &Self, transform: Transform| {
2189 layer
2190 .children
2191 .iter()
2192 .filter_map(|child| tree.visual_subtree_bounds(*child, transform))
2193 .reduce(union_rect)
2194 };
2195 match &layer.kind {
2196 LayerKind::Picture { bounds, .. } => Some(world_transform.transform_rect_bbox(*bounds)),
2197 LayerKind::Transform { transform: local } => {
2198 child_bounds(self, world_transform.then(*local))
2199 }
2200 LayerKind::ClipRect { rect, .. } => {
2201 let world = world_transform.transform_rect_bbox(*rect);
2202 child_bounds(self, world_transform).and_then(|bounds| bounds.intersection(world))
2203 }
2204 LayerKind::ClipRRect { .. }
2205 | LayerKind::ClipOval { .. }
2206 | LayerKind::ClipPath { .. } => {
2207 let world = clip_world_bounds(&layer.kind, world_transform)?;
2208 child_bounds(self, world_transform).and_then(|bounds| bounds.intersection(world))
2209 }
2210 LayerKind::Opacity { .. }
2211 | LayerKind::ColorFilter { .. }
2212 | LayerKind::Blend { .. }
2213 | LayerKind::ShaderMask { .. }
2214 | LayerKind::BackdropFilter { .. }
2215 | LayerKind::AnnotatedRegion { .. }
2216 | LayerKind::Leader { .. } => child_bounds(self, world_transform),
2217 LayerKind::Blur { blur } => child_bounds(self, world_transform)
2218 .map(|bounds| blur_bounds(bounds, blur.sigma_x, blur.sigma_y)),
2219 LayerKind::DropShadow { shadow } => child_bounds(self, world_transform).map(|bounds| {
2220 drop_shadow_bounds(bounds, shadow.offset, shadow.sigma_x, shadow.sigma_y)
2221 }),
2222 LayerKind::Follower(follower) => {
2223 let next = self.follower_transform(world_transform, follower)?;
2224 child_bounds(self, next)
2225 }
2226 }
2227 }
2228 #[must_use]
2229 pub fn debug_tree(&self) -> String {
2230 let mut out = String::new();
2231 if let Some(root) = self.root {
2232 self.write_debug(root, 0, &mut out);
2233 }
2234 out
2235 }
2236 fn write_debug(&self, id: LayerId, depth: usize, out: &mut String) {
2237 self.write_debug_at(id, None, depth, Transform::IDENTITY, None, out);
2238 }
2239 fn write_debug_at(
2240 &self,
2241 id: LayerId,
2242 parent: Option<LayerId>,
2243 depth: usize,
2244 world_transform: Transform,
2245 clip: Option<Rect>,
2246 out: &mut String,
2247 ) {
2248 let Some(layer) = self.layers.get(id.0) else {
2249 return;
2250 };
2251 let indent = " ".repeat(depth);
2252 let kind = match &layer.kind {
2253 LayerKind::Picture { bounds, .. } => format!(
2254 "Picture(local_bounds={bounds:?}, world_bounds={:?}, clip={clip:?})",
2255 world_transform.transform_rect_bbox(*bounds)
2256 ),
2257 LayerKind::Transform { transform } => {
2258 format!(
2259 "Transform(local={:?}, world={:?})",
2260 transform,
2261 world_transform.then(*transform)
2262 )
2263 }
2264 LayerKind::ClipRect { rect, .. } => format!(
2265 "ClipRect(local={rect:?}, world={:?})",
2266 world_transform.transform_rect_bbox(*rect)
2267 ),
2268 LayerKind::ClipRRect { rrect, .. } => format!(
2269 "ClipRRect(local={rrect:?}, world={:?})",
2270 world_transform.transform_rect_bbox(rrect.rect)
2271 ),
2272 LayerKind::ClipOval { rect, .. } => format!(
2273 "ClipOval(local={rect:?}, world={:?})",
2274 world_transform.transform_rect_bbox(*rect)
2275 ),
2276 LayerKind::ClipPath { path, .. } => format!(
2277 "ClipPath(local_bounds={:?}, world={:?})",
2278 path.bounds(),
2279 clip_world_bounds(&layer.kind, world_transform)
2280 ),
2281 LayerKind::Opacity { alpha } => format!(
2282 "Opacity(alpha={alpha:.3}, bounds={:?}, generation={})",
2283 self.subtree_bounds(id, world_transform),
2284 self.subtree_generation(id)
2285 ),
2286 LayerKind::Blur { blur } => format!(
2287 "Blur(sigma=({:.3},{:.3}), bounds={:?}, generation={})",
2288 blur.sigma_x,
2289 blur.sigma_y,
2290 self.subtree_bounds(id, world_transform),
2291 self.subtree_generation(id)
2292 ),
2293 LayerKind::DropShadow { shadow } => format!(
2294 "DropShadow(sigma=({:.3},{:.3}), offset={:?}, bounds={:?}, generation={})",
2295 shadow.sigma_x,
2296 shadow.sigma_y,
2297 shadow.offset,
2298 self.subtree_bounds(id, world_transform),
2299 self.subtree_generation(id)
2300 ),
2301 LayerKind::ColorFilter { filter } => format!(
2302 "ColorFilter(matrix={:?}, bounds={:?}, generation={})",
2303 filter.to_matrix(),
2304 self.subtree_bounds(id, world_transform),
2305 self.subtree_generation(id)
2306 ),
2307 LayerKind::Blend { mode } => format!(
2308 "Blend(mode={mode:?}, bounds={:?}, generation={})",
2309 self.subtree_bounds(id, world_transform),
2310 self.subtree_generation(id)
2311 ),
2312 LayerKind::ShaderMask {
2313 blend_mode,
2314 mask_size,
2315 ..
2316 } => format!(
2317 "ShaderMask(blend_mode={blend_mode:?}, mask_size={mask_size:?}, bounds={:?}, generation={})",
2318 self.subtree_bounds(id, world_transform),
2319 self.subtree_generation(id)
2320 ),
2321 LayerKind::BackdropFilter {
2322 blur,
2323 blend_mode,
2324 enabled,
2325 matrix,
2326 backdrop_key,
2327 } => format!(
2328 "BackdropFilter({}{}, blend_mode={blend_mode:?}, enabled={enabled}, bounds={:?}, generation={})",
2329 match matrix {
2330 Some(matrix) => format!("matrix={matrix:?}"),
2331 None => format!("sigma=({:.3},{:.3})", blur.sigma_x, blur.sigma_y),
2332 },
2333 backdrop_key.map_or_else(String::new, |key| format!(", key={key:?}")),
2334 self.subtree_bounds(id, world_transform),
2335 self.subtree_generation(id)
2336 ),
2337 LayerKind::AnnotatedRegion { sized, size, .. } => format!(
2338 "AnnotatedRegion(sized={sized}, size={size:?}, generation={})",
2339 self.subtree_generation(id)
2340 ),
2341 LayerKind::Leader { link, size, .. } => format!(
2342 "CompositedTransformTarget(size={size:?}, linked={}, generation={})",
2343 link.is_linked(),
2344 self.subtree_generation(id)
2345 ),
2346 LayerKind::Follower(FollowerLayer {
2347 show_when_unlinked,
2348 offset,
2349 target_anchor,
2350 follower_anchor,
2351 ..
2352 }) => format!(
2353 "CompositedTransformFollower(show_when_unlinked={show_when_unlinked}, offset={offset:?}, target_anchor={target_anchor:?}, follower_anchor={follower_anchor:?}, bounds={:?}, generation={})",
2354 self.subtree_bounds(id, world_transform),
2355 self.subtree_generation(id)
2356 ),
2357 };
2358 out.push_str(&format!("{indent}{id:?} parent={parent:?} {kind}\n"));
2359 let (next_translation, next_clip) = match &layer.kind {
2360 LayerKind::Picture { .. } => (world_transform, clip),
2361 LayerKind::Transform { transform: local } => (world_transform.then(*local), clip),
2362 LayerKind::ClipRect { rect, .. } => {
2363 let world = world_transform.transform_rect_bbox(*rect);
2364 (
2365 world_transform,
2366 Some(clip.map_or(world, |old| old.intersection(world).unwrap_or(world))),
2367 )
2368 }
2369 LayerKind::ClipRRect { .. }
2370 | LayerKind::ClipOval { .. }
2371 | LayerKind::ClipPath { .. } => {
2372 let narrowed = clip_world_bounds(&layer.kind, world_transform).map(|world| {
2375 clip.map_or(world, |old| old.intersection(world).unwrap_or(world))
2376 });
2377 (world_transform, narrowed.or(clip))
2378 }
2379 LayerKind::Opacity { .. } => (world_transform, clip),
2380 LayerKind::Blur { .. } | LayerKind::DropShadow { .. } => (world_transform, clip),
2381 LayerKind::ColorFilter { .. } | LayerKind::Blend { .. } => (world_transform, clip),
2382 LayerKind::ShaderMask { .. }
2383 | LayerKind::BackdropFilter { .. }
2384 | LayerKind::AnnotatedRegion { .. }
2385 | LayerKind::Leader { .. } => (world_transform, clip),
2386 LayerKind::Follower(follower) => (
2387 self.follower_transform(world_transform, follower)
2388 .unwrap_or(world_transform),
2389 clip,
2390 ),
2391 };
2392 for child in &layer.children {
2393 self.write_debug_at(
2394 *child,
2395 Some(id),
2396 depth + 1,
2397 next_translation,
2398 next_clip,
2399 out,
2400 );
2401 }
2402 }
2403}
2404
2405fn brush_generation(brush: &Brush) -> u64 {
2406 match brush {
2407 Brush::Solid(color) => {
2408 u64::from(color.red)
2409 | (u64::from(color.green) << 8)
2410 | (u64::from(color.blue) << 16)
2411 | (u64::from(color.alpha) << 24)
2412 }
2413 Brush::LinearGradient(gradient) => {
2414 gradient.stops.id().get()
2415 ^ u64::from(gradient.start.x.to_bits()).rotate_left(7)
2416 ^ u64::from(gradient.start.y.to_bits()).rotate_left(13)
2417 ^ u64::from(gradient.end.x.to_bits()).rotate_left(19)
2418 ^ u64::from(gradient.end.y.to_bits()).rotate_left(23)
2419 ^ (gradient.tile_mode as u64).rotate_left(29)
2420 }
2421 Brush::RadialGradient(gradient) => {
2422 gradient.stops.id().get()
2423 ^ u64::from(gradient.center.x.to_bits()).rotate_left(7)
2424 ^ u64::from(gradient.center.y.to_bits()).rotate_left(13)
2425 ^ u64::from(gradient.radius.to_bits()).rotate_left(19)
2426 ^ (gradient.tile_mode as u64).rotate_left(29)
2427 ^ gradient.focal.map_or(0, |focal| {
2428 u64::from(focal.x.to_bits()).rotate_left(31)
2429 ^ u64::from(focal.y.to_bits()).rotate_left(37)
2430 })
2431 ^ u64::from(gradient.focal_radius.to_bits()).rotate_left(41)
2432 }
2433 Brush::SweepGradient(gradient) => {
2434 gradient.stops.id().get()
2435 ^ u64::from(gradient.center.x.to_bits()).rotate_left(7)
2436 ^ u64::from(gradient.center.y.to_bits()).rotate_left(13)
2437 ^ u64::from(gradient.start_angle.to_bits()).rotate_left(19)
2438 ^ (gradient.tile_mode as u64).rotate_left(29)
2439 }
2440 }
2441}
2442
2443fn transform_generation(transform: Transform) -> u64 {
2444 transform
2445 .to_kurbo()
2446 .as_coeffs()
2447 .iter()
2448 .enumerate()
2449 .fold(0, |value, (index, coefficient)| {
2450 value ^ coefficient.to_bits().rotate_left((index as u32 * 9) % 63)
2451 })
2452}