1use crate::display_list::{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
24#[must_use]
28pub fn normalize_opacity(alpha: f32) -> f32 {
29 if alpha.is_finite() {
30 alpha.clamp(0., 1.)
31 } else {
32 0.
33 }
34}
35
36#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
37pub struct CompositorDiagnostics {
38 pub layers: u64,
39 pub picture_layers_repainted: u64,
40 pub transform_updates: u64,
41 pub clip_updates: u64,
42 pub layers_culled: u64,
43 pub opacity_updates: u64,
44 pub leader_publish_passes: u64,
47 pub leaders_published: u64,
50}
51
52#[derive(Clone, Copy, Debug, PartialEq)]
56pub struct FlattenedPicture {
57 pub layer: LayerId,
58 pub local_bounds: Rect,
59 pub world_bounds: Rect,
60 pub active_clip: Option<Rect>,
61}
62
63#[derive(Clone)]
70pub struct Annotation {
71 value: Rc<dyn Any>,
72 type_id: TypeId,
73}
74impl Annotation {
75 #[must_use]
76 pub fn new<T: Any>(value: T) -> Self {
77 Self {
78 value: Rc::new(value),
79 type_id: TypeId::of::<T>(),
80 }
81 }
82 #[must_use]
83 pub const fn value_type_id(&self) -> TypeId {
84 self.type_id
85 }
86 #[must_use]
87 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
88 self.value.downcast_ref::<T>()
89 }
90 #[must_use]
91 pub fn cloned<T: Any + Clone>(&self) -> Option<T> {
92 self.downcast_ref::<T>().cloned()
93 }
94}
95impl std::fmt::Debug for Annotation {
96 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97 formatter
98 .debug_struct("Annotation")
99 .field("type_id", &self.type_id)
100 .finish_non_exhaustive()
101 }
102}
103impl PartialEq for Annotation {
104 fn eq(&self, other: &Self) -> bool {
105 self.type_id == other.type_id && Rc::ptr_eq(&self.value, &other.value)
106 }
107}
108
109#[derive(Clone, Copy, Debug, Default, PartialEq)]
112pub struct LayerAnchor {
113 pub x: f32,
114 pub y: f32,
115}
116impl LayerAnchor {
117 pub const TOP_LEFT: Self = Self { x: -1., y: -1. };
118
119 #[must_use]
120 pub fn new(x: f32, y: f32) -> Self {
121 Self {
122 x: finite_or_zero(x),
123 y: finite_or_zero(y),
124 }
125 }
126 #[must_use]
127 pub const fn along_size(self, size: Size) -> Offset {
128 Offset::new(
129 size.width * (self.x + 1.) * 0.5,
130 size.height * (self.y + 1.) * 0.5,
131 )
132 }
133}
134
135fn clip_world_bounds(kind: &LayerKind, world_transform: Transform) -> Option<Rect> {
140 match kind {
141 LayerKind::ClipRect { rect, .. } => Some(world_transform.transform_rect_bbox(*rect)),
142 LayerKind::ClipRRect { rrect, .. } => Some(world_transform.transform_rect_bbox(rrect.rect)),
143 LayerKind::ClipOval { rect, .. } => Some(world_transform.transform_rect_bbox(*rect)),
144 LayerKind::ClipPath { path, .. } => path
145 .bounds()
146 .map(|bounds| world_transform.transform_rect_bbox(bounds)),
147 _ => None,
148 }
149}
150
151#[derive(Clone, Copy, Debug, PartialEq)]
155enum ClipSpace {
156 Translation,
157 Scale { x: f32, y: f32 },
158 General,
159}
160
161fn clip_space(world: Transform) -> ClipSpace {
162 let [a, b, c, d, _, _] = world.to_kurbo().as_coeffs();
163 if b == 0. && c == 0. {
164 if a == 1. && d == 1. {
165 ClipSpace::Translation
166 } else {
167 ClipSpace::Scale {
168 x: a as f32,
169 y: d as f32,
170 }
171 }
172 } else {
173 ClipSpace::General
174 }
175}
176
177#[must_use]
182pub fn resolve_follower_target(
183 leader_transform: Transform,
184 leader_size: Size,
185 target_anchor: LayerAnchor,
186 offset: Offset,
187) -> Offset {
188 let target_point = leader_transform.transform_point(target_anchor.along_size(leader_size));
189 let leader_origin = leader_transform.transform_point(Offset::ZERO);
190 target_point + (leader_transform.transform_point(offset) - leader_origin)
191}
192
193#[derive(Clone, Debug)]
199struct ResolvedClipPath {
200 world: Transform,
201 path: Arc<Path>,
202}
203
204#[derive(Clone, Debug)]
205struct LeaderData {
206 owner: PublisherIdentity,
207 transform: Transform,
208 size: Size,
209 generation: u64,
210}
211
212struct LeaderRecord {
216 id: LayerId,
217 link: LayerLink,
218 size: Size,
219 publisher: PublisherIdentity,
220 generation: u64,
221}
222
223#[derive(Clone, Copy, PartialEq, Eq)]
224enum PublishState {
225 InProgress,
226 Published,
227 Unresolvable,
228}
229
230#[derive(Clone, Debug)]
236pub struct PublisherIdentity(Rc<()>);
237impl PublisherIdentity {
238 pub(crate) fn new() -> Self {
239 Self(Rc::new(()))
240 }
241 #[must_use]
244 pub fn same_owner(&self, other: &Self) -> bool {
245 Rc::ptr_eq(&self.0, &other.0)
246 }
247}
248
249#[derive(Clone)]
252pub struct LayerLink(Rc<RefCell<Option<LeaderData>>>);
253impl Default for LayerLink {
254 fn default() -> Self {
255 Self::new()
256 }
257}
258impl std::fmt::Debug for LayerLink {
259 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
260 formatter
261 .debug_struct("LayerLink")
262 .field("linked", &self.is_linked())
263 .finish()
264 }
265}
266impl PartialEq for LayerLink {
267 fn eq(&self, other: &Self) -> bool {
268 Rc::ptr_eq(&self.0, &other.0)
269 }
270}
271impl LayerLink {
272 #[must_use]
273 pub fn new() -> Self {
274 Self(Rc::new(RefCell::new(None)))
275 }
276 #[must_use]
277 pub fn is_linked(&self) -> bool {
278 self.0.borrow().is_some()
279 }
280 #[must_use]
281 pub fn leader_size(&self) -> Option<Size> {
282 self.0.borrow().as_ref().map(|leader| leader.size)
283 }
284 #[must_use]
285 pub fn leader_transform(&self) -> Option<Transform> {
286 self.0.borrow().as_ref().map(|leader| leader.transform)
287 }
288 #[must_use]
289 pub fn leader_generation(&self) -> u64 {
290 self.0
291 .borrow()
292 .as_ref()
293 .map_or(0, |leader| leader.generation)
294 }
295 fn clear_if_owned_by(&self, owner: &PublisherIdentity) {
298 let mut state = self.0.borrow_mut();
299 if state
300 .as_ref()
301 .is_some_and(|leader| leader.owner.same_owner(owner))
302 {
303 *state = None;
304 }
305 }
306 fn clear_publication(&self) {
309 *self.0.borrow_mut() = None;
310 }
311 fn publish(&self, owner: PublisherIdentity, transform: Transform, size: Size, generation: u64) {
312 let mut state = self.0.borrow_mut();
316 if state.is_none() {
317 *state = Some(LeaderData {
318 owner,
319 transform,
320 size,
321 generation,
322 });
323 }
324 }
325}
326
327#[derive(Clone, Debug, PartialEq)]
331pub struct FlattenedAnnotation {
332 pub annotation: Annotation,
333 pub world_bounds: Option<Rect>,
334}
335
336#[derive(Clone, Debug)]
337pub enum LayerKind {
338 Picture {
339 display_list: Arc<DisplayList>,
340 bounds: Rect,
341 },
342 Transform {
343 transform: Transform,
344 },
345 ClipRect {
346 rect: Rect,
347 },
348 ClipRRect {
349 rrect: RRect,
350 },
351 ClipOval {
352 rect: Rect,
353 },
354 ClipPath {
355 path: Arc<Path>,
356 fill_rule: FillRule,
357 },
358 Opacity {
359 alpha: f32,
360 },
361 Blur {
362 blur: GaussianBlur,
363 },
364 DropShadow {
365 shadow: DropShadowEffect,
366 },
367 ColorFilter {
369 filter: Box<ColorFilter>,
370 },
371 Blend {
372 mode: BlendMode,
373 },
374 ShaderMask {
375 shader: Box<Brush>,
376 blend_mode: BlendMode,
377 mask_size: Size,
378 mask_transform: Box<Transform>,
379 },
380 BackdropFilter {
381 blur: GaussianBlur,
382 blend_mode: BlendMode,
383 enabled: bool,
384 },
385 AnnotatedRegion {
386 annotation: Annotation,
387 sized: bool,
388 size: Size,
389 },
390 Leader {
391 link: LayerLink,
392 size: Size,
393 publisher: PublisherIdentity,
394 },
395 Follower(FollowerLayer),
396}
397
398#[derive(Clone, Debug, PartialEq)]
400pub struct FollowerLayer {
401 pub link: LayerLink,
402 pub show_when_unlinked: bool,
403 pub offset: Offset,
404 pub target_anchor: LayerAnchor,
405 pub follower_anchor: LayerAnchor,
406 pub size: Size,
407}
408
409#[derive(Clone, Debug)]
410struct Layer {
411 kind: LayerKind,
412 children: Vec<LayerId>,
413 surface_partition: Option<SurfacePartitionId>,
414 generation: u64,
415 clip_cache: Option<Box<ResolvedClipPath>>,
419}
420
421fn next_generation(counter: &mut u64) -> u64 {
423 let generation = *counter;
424 *counter = generation
425 .checked_add(1)
426 .expect("layer generation exhausted");
427 generation
428}
429
430pub struct LayerTree {
434 layers: Arena<Layer>,
435 root: Option<LayerId>,
436 diagnostics: CompositorDiagnostics,
437 flattened_pictures: Vec<FlattenedPicture>,
438 flattened_annotations: Vec<FlattenedAnnotation>,
439 next_generation: u64,
440 annotation_layers: usize,
443 leader_layers: usize,
446 child_stack: Vec<LayerId>,
449}
450impl Default for LayerTree {
451 fn default() -> Self {
452 Self::new()
453 }
454}
455impl LayerTree {
456 #[must_use]
457 pub fn new() -> Self {
458 Self {
459 layers: Arena::new(),
460 root: None,
461 diagnostics: CompositorDiagnostics::default(),
462 flattened_pictures: Vec::new(),
463 flattened_annotations: Vec::new(),
464 next_generation: 1,
465 annotation_layers: 0,
466 leader_layers: 0,
467 child_stack: Vec::new(),
468 }
469 }
470 #[must_use]
471 pub fn diagnostics(&self) -> CompositorDiagnostics {
472 self.diagnostics
473 }
474 #[must_use]
475 pub fn root(&self) -> Option<LayerId> {
476 self.root
477 }
478 #[doc(hidden)]
479 #[must_use]
480 pub fn contains(&self, id: LayerId) -> bool {
481 self.layers.contains(id.0)
482 }
483 pub fn set_root(&mut self, root: LayerId) {
484 self.root = Some(root);
485 }
486
487 #[must_use]
495 pub fn scene_bounds(&self) -> Option<Rect> {
496 self.root
497 .and_then(|root| self.visual_subtree_bounds(root, Transform::IDENTITY))
498 }
499 pub fn create_picture(&mut self, display_list: DisplayList, bounds: Rect) -> LayerId {
500 self.insert(LayerKind::Picture {
501 display_list: Arc::new(display_list),
502 bounds,
503 })
504 }
505 pub fn create_transform(&mut self, transform: Transform) -> LayerId {
506 self.insert(LayerKind::Transform { transform })
507 }
508 pub fn create_clip_rect(&mut self, rect: Rect) -> LayerId {
509 self.insert(LayerKind::ClipRect { rect })
510 }
511 pub fn create_clip_rrect(&mut self, rrect: RRect) -> LayerId {
514 self.insert(LayerKind::ClipRRect { rrect })
515 }
516 pub fn create_clip_oval(&mut self, rect: Rect) -> LayerId {
519 self.insert(LayerKind::ClipOval { rect })
520 }
521 pub fn create_clip_path(&mut self, path: Arc<Path>, fill_rule: FillRule) -> LayerId {
524 self.insert(LayerKind::ClipPath { path, fill_rule })
525 }
526 pub fn create_opacity(&mut self, alpha: f32) -> LayerId {
529 self.insert(LayerKind::Opacity {
530 alpha: normalize_opacity(alpha),
531 })
532 }
533 pub fn create_blur(&mut self, blur: GaussianBlur) -> LayerId {
535 self.insert(LayerKind::Blur {
536 blur: GaussianBlur::new(blur.sigma_x, blur.sigma_y),
537 })
538 }
539 pub fn create_drop_shadow(&mut self, shadow: DropShadowEffect) -> LayerId {
541 self.insert(LayerKind::DropShadow {
542 shadow: DropShadowEffect::asymmetric(
543 shadow.offset,
544 shadow.sigma_x,
545 shadow.sigma_y,
546 shadow.color,
547 ),
548 })
549 }
550 pub fn create_color_filter(&mut self, filter: ColorFilter) -> LayerId {
553 self.insert(LayerKind::ColorFilter {
554 filter: Box::new(filter),
555 })
556 }
557 pub fn create_blend(&mut self, mode: BlendMode) -> LayerId {
560 self.insert(LayerKind::Blend { mode })
561 }
562 pub fn create_shader_mask(
566 &mut self,
567 shader: Brush,
568 blend_mode: BlendMode,
569 mask_size: Size,
570 mask_transform: Transform,
571 ) -> LayerId {
572 self.insert(LayerKind::ShaderMask {
573 shader: Box::new(shader),
574 blend_mode,
575 mask_size,
576 mask_transform: Box::new(mask_transform),
577 })
578 }
579 pub fn create_backdrop_filter(
583 &mut self,
584 blur: GaussianBlur,
585 blend_mode: BlendMode,
586 enabled: bool,
587 ) -> LayerId {
588 self.insert(LayerKind::BackdropFilter {
589 blur: GaussianBlur::new(blur.sigma_x, blur.sigma_y),
590 blend_mode,
591 enabled,
592 })
593 }
594 pub fn create_annotated_region(
595 &mut self,
596 annotation: Annotation,
597 sized: bool,
598 size: Size,
599 ) -> LayerId {
600 self.insert(LayerKind::AnnotatedRegion {
601 annotation,
602 sized,
603 size,
604 })
605 }
606 pub fn create_leader(&mut self, link: LayerLink, size: Size) -> LayerId {
607 self.insert(LayerKind::Leader {
608 link,
609 size,
610 publisher: PublisherIdentity::new(),
611 })
612 }
613 pub fn create_follower(&mut self, follower: FollowerLayer) -> LayerId {
614 self.insert(LayerKind::Follower(follower))
615 }
616 fn insert(&mut self, kind: LayerKind) -> LayerId {
617 self.annotation_layers += usize::from(matches!(kind, LayerKind::AnnotatedRegion { .. }));
618 self.leader_layers += usize::from(matches!(kind, LayerKind::Leader { .. }));
619 let generation = next_generation(&mut self.next_generation);
620 let id = LayerId(self.layers.insert(Layer {
621 kind,
622 children: Vec::new(),
623 surface_partition: None,
624 generation,
625 clip_cache: None,
626 }));
627 self.diagnostics.layers += 1;
628 id
629 }
630 pub fn remove(&mut self, id: LayerId) {
631 if let Some(layer) = self.layers.remove(id.0) {
632 self.annotation_layers -=
633 usize::from(matches!(layer.kind, LayerKind::AnnotatedRegion { .. }));
634 self.leader_layers -= usize::from(matches!(layer.kind, LayerKind::Leader { .. }));
635 if let LayerKind::Leader {
640 link, publisher, ..
641 } = &layer.kind
642 {
643 link.clear_if_owned_by(publisher);
644 }
645 self.diagnostics.layers -= 1;
646 if self.root == Some(id) {
647 self.root = None;
648 }
649 }
652 }
653 pub fn set_children(&mut self, id: LayerId, children: Vec<LayerId>) {
654 if let Some(layer) = self.layers.get_mut(id.0) {
655 if layer.children == children {
656 return;
657 }
658 layer.children = children;
659 layer.generation = next_generation(&mut self.next_generation);
660 }
661 }
662
663 pub fn set_surface_partition(&mut self, id: LayerId, partition: Option<SurfacePartitionId>) {
667 let Some(layer) = self.layers.get_mut(id.0) else {
668 return;
669 };
670 if layer.surface_partition == partition {
671 return;
672 }
673 layer.surface_partition = partition;
674 }
675
676 pub fn clear_surface_partitions(&mut self) {
679 let ids = self
680 .layers
681 .iter()
682 .filter_map(|(raw, layer)| layer.surface_partition.is_some().then_some(LayerId(raw)))
683 .collect::<Vec<_>>();
684 for id in ids {
685 self.set_surface_partition(id, None);
686 }
687 }
688 pub fn update_picture(&mut self, id: LayerId, display_list: DisplayList, bounds: Rect) {
689 if let Some(layer) = self.layers.get_mut(id.0)
690 && let LayerKind::Picture {
691 display_list: current,
692 bounds: current_bounds,
693 } = &mut layer.kind
694 {
695 *current = Arc::new(display_list);
696 *current_bounds = bounds;
697 layer.generation = next_generation(&mut self.next_generation);
698 self.diagnostics.picture_layers_repainted += 1;
699 }
700 }
701 pub fn update_transform(&mut self, id: LayerId, transform: Transform) -> bool {
702 let Some(layer) = self.layers.get_mut(id.0) else {
703 return false;
704 };
705 let LayerKind::Transform { transform: current } = &mut layer.kind else {
706 return false;
707 };
708 if *current == transform {
709 return false;
710 }
711 *current = transform;
712 layer.generation = next_generation(&mut self.next_generation);
713 self.diagnostics.transform_updates += 1;
714 true
715 }
716 pub fn update_clip(&mut self, id: LayerId, rect: Rect) -> bool {
717 let Some(layer) = self.layers.get_mut(id.0) else {
718 return false;
719 };
720 let LayerKind::ClipRect { rect: current } = &mut layer.kind else {
721 return false;
722 };
723 if *current == rect {
724 return false;
725 }
726 *current = rect;
727 layer.clip_cache = None;
728 layer.generation = next_generation(&mut self.next_generation);
729 self.diagnostics.clip_updates += 1;
730 true
731 }
732 pub fn update_clip_rrect(&mut self, id: LayerId, rrect: RRect) -> bool {
733 let Some(layer) = self.layers.get_mut(id.0) else {
734 return false;
735 };
736 let LayerKind::ClipRRect { rrect: current } = &mut layer.kind else {
737 return false;
738 };
739 if *current == rrect {
740 return false;
741 }
742 *current = rrect;
743 layer.clip_cache = None;
744 layer.generation = next_generation(&mut self.next_generation);
745 self.diagnostics.clip_updates += 1;
746 true
747 }
748 pub fn update_clip_oval(&mut self, id: LayerId, rect: Rect) -> bool {
749 let Some(layer) = self.layers.get_mut(id.0) else {
750 return false;
751 };
752 let LayerKind::ClipOval { rect: current } = &mut layer.kind else {
753 return false;
754 };
755 if *current == rect {
756 return false;
757 }
758 *current = rect;
759 layer.clip_cache = None;
760 layer.generation = next_generation(&mut self.next_generation);
761 self.diagnostics.clip_updates += 1;
762 true
763 }
764 pub fn update_clip_path(&mut self, id: LayerId, path: Arc<Path>, fill_rule: FillRule) -> bool {
765 let Some(layer) = self.layers.get_mut(id.0) else {
766 return false;
767 };
768 let LayerKind::ClipPath {
769 path: current_path,
770 fill_rule: current_rule,
771 } = &mut layer.kind
772 else {
773 return false;
774 };
775 if **current_path == *path && *current_rule == fill_rule {
776 return false;
777 }
778 *current_path = path;
779 *current_rule = fill_rule;
780 layer.clip_cache = None;
781 layer.generation = next_generation(&mut self.next_generation);
782 self.diagnostics.clip_updates += 1;
783 true
784 }
785 pub fn update_opacity(&mut self, id: LayerId, alpha: f32) -> bool {
789 let Some(layer) = self.layers.get_mut(id.0) else {
790 return false;
791 };
792 let LayerKind::Opacity { alpha: current } = &mut layer.kind else {
793 return false;
794 };
795 let alpha = normalize_opacity(alpha);
796 if *current == alpha {
797 return false;
798 }
799 *current = alpha;
800 self.diagnostics.opacity_updates += 1;
801 true
802 }
803 pub fn update_blur(&mut self, id: LayerId, blur: GaussianBlur) -> bool {
806 let Some(layer) = self.layers.get_mut(id.0) else {
807 return false;
808 };
809 let LayerKind::Blur { blur: current } = &mut layer.kind else {
810 return false;
811 };
812 let blur = GaussianBlur::new(blur.sigma_x, blur.sigma_y);
813 if *current == blur {
814 return false;
815 }
816 *current = blur;
817 true
818 }
819 pub fn update_drop_shadow(&mut self, id: LayerId, shadow: DropShadowEffect) -> bool {
823 let Some(layer) = self.layers.get_mut(id.0) else {
824 return false;
825 };
826 let LayerKind::DropShadow { shadow: current } = &mut layer.kind else {
827 return false;
828 };
829 let shadow = DropShadowEffect::asymmetric(
830 shadow.offset,
831 shadow.sigma_x,
832 shadow.sigma_y,
833 shadow.color,
834 );
835 if *current == shadow {
836 return false;
837 }
838 *current = shadow;
839 true
840 }
841 pub fn update_color_filter(&mut self, id: LayerId, filter: ColorFilter) -> bool {
842 let Some(layer) = self.layers.get_mut(id.0) else {
843 return false;
844 };
845 let LayerKind::ColorFilter { filter: current } = &mut layer.kind else {
846 return false;
847 };
848 if **current == filter {
849 return false;
850 }
851 **current = filter;
852 true
853 }
854 pub fn update_blend(&mut self, id: LayerId, mode: BlendMode) -> bool {
855 let Some(layer) = self.layers.get_mut(id.0) else {
856 return false;
857 };
858 let LayerKind::Blend { mode: current } = &mut layer.kind else {
859 return false;
860 };
861 if *current == mode {
862 return false;
863 }
864 *current = mode;
865 true
866 }
867 pub fn update_shader_mask(
868 &mut self,
869 id: LayerId,
870 shader: Brush,
871 blend_mode: BlendMode,
872 mask_size: Size,
873 mask_transform: Transform,
874 ) -> bool {
875 let Some(layer) = self.layers.get_mut(id.0) else {
876 return false;
877 };
878 let LayerKind::ShaderMask {
879 shader: current_shader,
880 blend_mode: current_mode,
881 mask_size: current_size,
882 mask_transform: current_transform,
883 } = &mut layer.kind
884 else {
885 return false;
886 };
887 if **current_shader == shader
888 && *current_mode == blend_mode
889 && *current_size == mask_size
890 && **current_transform == mask_transform
891 {
892 return false;
893 }
894 **current_shader = shader;
895 *current_mode = blend_mode;
896 *current_size = mask_size;
897 **current_transform = mask_transform;
898 layer.generation = next_generation(&mut self.next_generation);
899 true
900 }
901 pub fn update_shader_mask_blend(&mut self, id: LayerId, blend_mode: BlendMode) -> bool {
902 let Some(layer) = self.layers.get_mut(id.0) else {
903 return false;
904 };
905 let LayerKind::ShaderMask {
906 blend_mode: current,
907 ..
908 } = &mut layer.kind
909 else {
910 return false;
911 };
912 if *current == blend_mode {
913 return false;
914 }
915 *current = blend_mode;
916 layer.generation = next_generation(&mut self.next_generation);
917 true
918 }
919 pub fn update_backdrop_filter(
920 &mut self,
921 id: LayerId,
922 blur: GaussianBlur,
923 blend_mode: BlendMode,
924 enabled: bool,
925 ) -> bool {
926 let Some(layer) = self.layers.get_mut(id.0) else {
927 return false;
928 };
929 let LayerKind::BackdropFilter {
930 blur: current_blur,
931 blend_mode: current_mode,
932 enabled: current_enabled,
933 } = &mut layer.kind
934 else {
935 return false;
936 };
937 let blur = GaussianBlur::new(blur.sigma_x, blur.sigma_y);
938 if *current_blur == blur && *current_mode == blend_mode && *current_enabled == enabled {
939 return false;
940 }
941 *current_blur = blur;
942 *current_mode = blend_mode;
943 *current_enabled = enabled;
944 layer.generation = next_generation(&mut self.next_generation);
945 true
946 }
947 pub fn update_annotated_region(
948 &mut self,
949 id: LayerId,
950 annotation: Annotation,
951 sized: bool,
952 size: Size,
953 ) -> bool {
954 let Some(layer) = self.layers.get_mut(id.0) else {
955 return false;
956 };
957 let LayerKind::AnnotatedRegion {
958 annotation: current_annotation,
959 sized: current_sized,
960 size: current_size,
961 } = &mut layer.kind
962 else {
963 return false;
964 };
965 if *current_annotation == annotation && *current_sized == sized && *current_size == size {
966 return false;
967 }
968 *current_annotation = annotation;
969 *current_sized = sized;
970 *current_size = size;
971 layer.generation = next_generation(&mut self.next_generation);
972 true
973 }
974 pub fn update_leader(&mut self, id: LayerId, link: LayerLink, size: Size) -> bool {
975 let Some(layer) = self.layers.get_mut(id.0) else {
976 return false;
977 };
978 let LayerKind::Leader {
979 link: current_link,
980 size: current_size,
981 publisher,
982 } = &mut layer.kind
983 else {
984 return false;
985 };
986 if *current_link == link && *current_size == size {
987 return false;
988 }
989 current_link.clear_if_owned_by(publisher);
992 *current_link = link;
993 *current_size = size;
994 layer.generation = next_generation(&mut self.next_generation);
995 true
996 }
997 pub fn update_leader_size(&mut self, id: LayerId, size: Size) -> bool {
998 let Some(layer) = self.layers.get_mut(id.0) else {
999 return false;
1000 };
1001 let LayerKind::Leader { size: current, .. } = &mut layer.kind else {
1002 return false;
1003 };
1004 if *current == size {
1005 return false;
1006 }
1007 *current = size;
1008 layer.generation = next_generation(&mut self.next_generation);
1009 true
1010 }
1011 pub fn update_follower(&mut self, id: LayerId, follower: FollowerLayer) -> bool {
1012 let Some(layer) = self.layers.get_mut(id.0) else {
1013 return false;
1014 };
1015 let LayerKind::Follower(current) = &mut layer.kind else {
1016 return false;
1017 };
1018 if *current == follower {
1019 return false;
1020 }
1021 *current = follower;
1022 layer.generation = next_generation(&mut self.next_generation);
1023 true
1024 }
1025 #[must_use]
1028 pub fn flattened_pictures(&self) -> &[FlattenedPicture] {
1029 &self.flattened_pictures
1030 }
1031 #[must_use]
1032 pub fn flattened_annotations(&self) -> &[FlattenedAnnotation] {
1033 &self.flattened_annotations
1034 }
1035 #[must_use]
1039 pub fn find_annotation<T: Any + Clone>(&self, point: Offset) -> Option<T> {
1040 self.flattened_annotations.iter().find_map(|entry| {
1041 let in_bounds = entry
1042 .world_bounds
1043 .is_none_or(|bounds| bounds.contains(point));
1044 in_bounds.then(|| entry.annotation.cloned::<T>()).flatten()
1045 })
1046 }
1047 #[must_use]
1048 pub fn find_annotations<T: Any + Clone>(&self, point: Offset) -> Vec<T> {
1049 self.flattened_annotations
1050 .iter()
1051 .filter_map(|entry| {
1052 let in_bounds = entry
1053 .world_bounds
1054 .is_none_or(|bounds| bounds.contains(point));
1055 in_bounds.then(|| entry.annotation.cloned::<T>()).flatten()
1056 })
1057 .collect()
1058 }
1059 #[must_use]
1060 pub fn flatten(&mut self) -> DisplayList {
1061 let mut out = DisplayList::new();
1062 self.flattened_pictures.clear();
1063 self.flattened_annotations.clear();
1064 if let Some(root) = self.root {
1065 self.publish_leader_links();
1070 self.flatten_layer(root, Transform::IDENTITY, None, &mut out);
1071 if self.annotation_layers > 0 {
1072 self.collect_annotations(root, Transform::IDENTITY, None);
1073 }
1074 }
1075 out
1076 }
1077 fn clip_command(&mut self, id: LayerId, kind: &LayerKind, world: Transform) -> PaintCommand {
1085 match kind {
1086 LayerKind::ClipRect { rect, .. } => match clip_space(world) {
1087 ClipSpace::Translation | ClipSpace::Scale { .. } => PaintCommand::PushClip {
1088 rect: world.transform_rect_bbox(*rect),
1089 },
1090 ClipSpace::General => {
1091 let rect = *rect;
1092 PaintCommand::PushClipPath {
1093 path: self.memoized_fallback_path(id, move || rect_as_path(rect), world),
1094 fill_rule: FillRule::NonZero,
1095 }
1096 }
1097 },
1098 LayerKind::ClipRRect { rrect, .. } => match clip_space(world) {
1099 ClipSpace::Translation => PaintCommand::PushClipRRect {
1100 rrect: RRect::new(world.transform_rect_bbox(rrect.rect), rrect.radii),
1101 },
1102 ClipSpace::Scale { x, y } if x > 0. && x == y => PaintCommand::PushClipRRect {
1106 rrect: RRect::new(world.transform_rect_bbox(rrect.rect), rrect.radii.scaled(x)),
1107 },
1108 _ => {
1109 let (rect, radii) = (rrect.rect, rrect.radii);
1110 PaintCommand::PushClipPath {
1111 path: self.memoized_fallback_path(
1112 id,
1113 move || rrect_as_path(rect, radii, fallback_tolerance(world)),
1114 world,
1115 ),
1116 fill_rule: FillRule::NonZero,
1117 }
1118 }
1119 },
1120 LayerKind::ClipOval { rect, .. } => match clip_space(world) {
1121 ClipSpace::Translation | ClipSpace::Scale { .. } => PaintCommand::PushClipOval {
1123 rect: world.transform_rect_bbox(*rect),
1124 },
1125 ClipSpace::General => {
1126 let rect = *rect;
1127 PaintCommand::PushClipPath {
1128 path: self.memoized_fallback_path(
1129 id,
1130 move || ellipse_as_path(rect, fallback_tolerance(world)),
1131 world,
1132 ),
1133 fill_rule: FillRule::NonZero,
1134 }
1135 }
1136 },
1137 LayerKind::ClipPath {
1138 path, fill_rule, ..
1139 } => PaintCommand::PushClipPath {
1140 path: self.memoized_clip_path(id, path, world),
1141 fill_rule: *fill_rule,
1142 },
1143 _ => unreachable!("clip emitter received a non-clip layer"),
1144 }
1145 }
1146 fn memoized_clip_path(&mut self, id: LayerId, path: &Arc<Path>, world: Transform) -> Arc<Path> {
1151 if world == Transform::IDENTITY {
1152 return path.clone();
1153 }
1154 let owned = path.clone();
1155 self.memoized_fallback_path(id, move || owned.as_ref().clone(), world)
1156 }
1157 fn memoized_fallback_path(
1164 &mut self,
1165 id: LayerId,
1166 build: impl FnOnce() -> Path,
1167 world: Transform,
1168 ) -> Arc<Path> {
1169 if let Some(layer) = self.layers.get(id.0)
1170 && let Some(memo) = layer.clip_cache.as_ref()
1171 && memo.world == world
1172 {
1173 return memo.path.clone();
1174 }
1175 let resolved = Arc::new(build().transformed(world));
1176 if let Some(layer) = self.layers.get_mut(id.0) {
1177 layer.clip_cache = Some(Box::new(ResolvedClipPath {
1178 world,
1179 path: resolved.clone(),
1180 }));
1181 }
1182 resolved
1183 }
1184 fn flatten_layer(
1185 &mut self,
1186 id: LayerId,
1187 world_transform: Transform,
1188 clip: Option<Rect>,
1189 out: &mut DisplayList,
1190 ) {
1191 let partition = self
1192 .layers
1193 .get(id.0)
1194 .and_then(|layer| layer.surface_partition);
1195 if let Some(id) = partition {
1196 out.push(PaintCommand::PushSurfacePartition { id });
1197 }
1198 self.flatten_layer_contents(id, world_transform, clip, out);
1199 if partition.is_some() {
1200 out.push(PaintCommand::PopSurfacePartition);
1201 }
1202 }
1203
1204 fn visit_children(
1208 &mut self,
1209 id: LayerId,
1210 reverse: bool,
1211 mut visit: impl FnMut(&mut Self, LayerId),
1212 ) {
1213 let start = self.child_stack.len();
1214 if let Some(layer) = self.layers.get(id.0) {
1215 self.child_stack.extend_from_slice(&layer.children);
1216 }
1217 let end = self.child_stack.len();
1218 for index in start..end {
1219 let child = self.child_stack[if reverse {
1220 start + end - 1 - index
1221 } else {
1222 index
1223 }];
1224 visit(self, child);
1225 }
1226 self.child_stack.truncate(start);
1227 }
1228
1229 fn flatten_layer_contents(
1230 &mut self,
1231 id: LayerId,
1232 world_transform: Transform,
1233 clip: Option<Rect>,
1234 out: &mut DisplayList,
1235 ) {
1236 let Some(kind) = self.layers.get(id.0).map(|layer| layer.kind.clone()) else {
1237 return;
1238 };
1239 match kind {
1240 LayerKind::Picture {
1241 display_list,
1242 bounds,
1243 } => {
1244 let world = world_transform.transform_rect_bbox(bounds);
1245 if clip.is_some_and(|active| !active.intersects(world)) {
1246 self.diagnostics.layers_culled += 1;
1247 return;
1248 }
1249 self.flattened_pictures.push(FlattenedPicture {
1250 layer: id,
1251 local_bounds: bounds,
1252 world_bounds: world,
1253 active_clip: clip,
1254 });
1255 out.push(PaintCommand::PushTransform {
1256 transform: world_transform,
1257 });
1258 out.extend_from(&display_list);
1259 out.push(PaintCommand::PopTransform);
1260 }
1261 LayerKind::Transform { transform: local } => {
1262 let next = world_transform.then(local);
1263 self.visit_children(id, false, |tree, child| {
1264 tree.flatten_layer(child, next, clip, out)
1265 });
1266 }
1267 LayerKind::ClipRect { .. }
1268 | LayerKind::ClipRRect { .. }
1269 | LayerKind::ClipOval { .. }
1270 | LayerKind::ClipPath { .. } => {
1271 let Some(shape_bounds) = clip_world_bounds(&kind, world_transform) else {
1275 self.diagnostics.layers_culled += 1;
1276 return;
1277 };
1278 let next_clip = match clip {
1279 Some(active) => active.intersection(shape_bounds),
1280 None => Some(shape_bounds),
1281 };
1282 if next_clip.is_none() {
1283 self.diagnostics.layers_culled += 1;
1284 return;
1285 }
1286 out.push(self.clip_command(id, &kind, world_transform));
1287 self.visit_children(id, false, |tree, child| {
1288 tree.flatten_layer(child, world_transform, next_clip, out)
1289 });
1290 out.push(PaintCommand::PopClip);
1291 }
1292 LayerKind::Opacity { alpha } => {
1293 let bounds = self
1294 .subtree_bounds(id, world_transform)
1295 .unwrap_or_else(|| Rect::from_origin_size(Offset::ZERO, Size::ZERO));
1296 out.push(PaintCommand::PushOpacity {
1297 layer: id,
1298 alpha,
1299 generation: self.subtree_generation(id),
1300 bounds,
1301 });
1302 self.visit_children(id, false, |tree, child| {
1303 tree.flatten_layer(child, world_transform, clip, out)
1304 });
1305 out.push(PaintCommand::PopOpacity);
1306 }
1307 LayerKind::Blur { blur } => {
1308 let bounds = self
1309 .subtree_bounds(id, world_transform)
1310 .unwrap_or_else(|| Rect::from_origin_size(Offset::ZERO, Size::ZERO));
1311 out.push(PaintCommand::PushBlur {
1312 layer: id,
1313 blur,
1314 generation: self.subtree_generation(id),
1315 bounds,
1316 });
1317 self.visit_children(id, false, |tree, child| {
1318 tree.flatten_layer(child, world_transform, clip, out)
1319 });
1320 out.push(PaintCommand::PopEffect);
1321 }
1322 LayerKind::DropShadow { shadow } => {
1323 let bounds = self
1324 .subtree_bounds(id, world_transform)
1325 .unwrap_or_else(|| Rect::from_origin_size(Offset::ZERO, Size::ZERO));
1326 out.push(PaintCommand::PushDropShadow {
1327 layer: id,
1328 shadow,
1329 generation: self.subtree_generation(id),
1330 bounds,
1331 });
1332 self.visit_children(id, false, |tree, child| {
1333 tree.flatten_layer(child, world_transform, clip, out)
1334 });
1335 out.push(PaintCommand::PopEffect);
1336 }
1337 LayerKind::ColorFilter { filter } => {
1338 let bounds = self
1339 .subtree_bounds(id, world_transform)
1340 .unwrap_or_else(|| Rect::from_origin_size(Offset::ZERO, Size::ZERO));
1341 out.push(PaintCommand::PushColorFilter {
1342 layer: id,
1343 filter: *filter,
1344 generation: self.subtree_generation(id),
1345 bounds,
1346 });
1347 self.visit_children(id, false, |tree, child| {
1348 tree.flatten_layer(child, world_transform, clip, out)
1349 });
1350 out.push(PaintCommand::PopEffect);
1351 }
1352 LayerKind::Blend { mode } => {
1353 let bounds = self
1354 .subtree_bounds(id, world_transform)
1355 .unwrap_or_else(|| Rect::from_origin_size(Offset::ZERO, Size::ZERO));
1356 out.push(PaintCommand::PushBlend {
1357 layer: id,
1358 mode,
1359 generation: self.subtree_generation(id),
1360 bounds,
1361 });
1362 self.visit_children(id, false, |tree, child| {
1363 tree.flatten_layer(child, world_transform, clip, out)
1364 });
1365 out.push(PaintCommand::PopEffect);
1366 }
1367 LayerKind::ShaderMask {
1368 shader,
1369 blend_mode,
1370 mask_size,
1371 mask_transform,
1372 } => {
1373 let bounds = self
1374 .subtree_bounds(id, world_transform)
1375 .unwrap_or_else(|| Rect::from_origin_size(Offset::ZERO, Size::ZERO));
1376 if !bounds.size.width.is_finite()
1377 || !bounds.size.height.is_finite()
1378 || bounds.size.width <= 0.
1379 || bounds.size.height <= 0.
1380 {
1381 return;
1382 }
1383 out.push(PaintCommand::PushShaderMask {
1384 layer: id,
1385 shader: *shader,
1386 blend_mode,
1387 mask_size,
1388 mask_transform: *mask_transform,
1389 generation: self.subtree_generation(id),
1390 bounds,
1391 });
1392 self.visit_children(id, false, |tree, child| {
1393 tree.flatten_layer(child, world_transform, clip, out)
1394 });
1395 out.push(PaintCommand::PopEffect);
1396 }
1397 LayerKind::BackdropFilter {
1398 blur,
1399 blend_mode,
1400 enabled,
1401 } => {
1402 if !enabled || (blur.sigma_x <= f32::EPSILON && blur.sigma_y <= f32::EPSILON) {
1403 self.visit_children(id, false, |tree, child| {
1404 tree.flatten_layer(child, world_transform, clip, out)
1405 });
1406 return;
1407 }
1408 let bounds = self
1409 .subtree_bounds(id, world_transform)
1410 .unwrap_or_else(|| Rect::from_origin_size(Offset::ZERO, Size::ZERO));
1411 out.push(PaintCommand::PushBackdropFilter {
1412 layer: id,
1413 blur,
1414 blend_mode,
1415 enabled,
1416 generation: self.subtree_generation(id),
1417 bounds,
1418 });
1419 self.visit_children(id, false, |tree, child| {
1420 tree.flatten_layer(child, world_transform, clip, out)
1421 });
1422 out.push(PaintCommand::PopEffect);
1423 }
1424 LayerKind::AnnotatedRegion { .. } => {
1425 self.visit_children(id, false, |tree, child| {
1426 tree.flatten_layer(child, world_transform, clip, out)
1427 });
1428 }
1429 LayerKind::Leader { .. } => {
1430 self.visit_children(id, false, |tree, child| {
1433 tree.flatten_layer(child, world_transform, clip, out)
1434 });
1435 }
1436 LayerKind::Follower(follower) => {
1437 let Some(next_transform) = self.follower_transform(world_transform, &follower)
1438 else {
1439 return;
1440 };
1441 self.visit_children(id, false, |tree, child| {
1442 tree.flatten_layer(child, next_transform, clip, out)
1443 });
1444 }
1445 }
1446 }
1447 fn clear_link_states(&self, id: LayerId) {
1448 let Some(layer) = self.layers.get(id.0) else {
1449 return;
1450 };
1451 if let LayerKind::Leader { link, .. } = &layer.kind {
1452 link.clear_publication();
1453 }
1454 for child in layer.children.iter() {
1455 self.clear_link_states(*child);
1456 }
1457 }
1458 pub fn publish_leader_links(&mut self) {
1464 if self.leader_layers == 0 {
1465 return;
1466 }
1467 if let Some(root) = self.root {
1468 self.clear_link_states(root);
1469 self.publish_resolved_leaders(root);
1470 }
1471 }
1472 fn publish_resolved_leaders(&mut self, root: LayerId) {
1481 self.diagnostics.leader_publish_passes += 1;
1482 let mut parents = HashMap::new();
1483 let mut leaders = Vec::new();
1484 self.collect_publish_state(root, &mut parents, &mut leaders);
1485 if leaders.is_empty() {
1486 return;
1487 }
1488 let mut states = HashMap::new();
1489 let mut published = 0;
1490 for index in 0..leaders.len() {
1491 published += self.ensure_published(index, &leaders, &parents, &mut states) as u64;
1492 }
1493 self.diagnostics.leaders_published += published;
1494 }
1495 fn collect_publish_state(
1496 &self,
1497 id: LayerId,
1498 parents: &mut HashMap<LayerId, LayerId>,
1499 leaders: &mut Vec<LeaderRecord>,
1500 ) {
1501 let Some(layer) = self.layers.get(id.0) else {
1502 return;
1503 };
1504 if let LayerKind::Leader {
1505 link,
1506 size,
1507 publisher,
1508 } = &layer.kind
1509 {
1510 leaders.push(LeaderRecord {
1511 id,
1512 link: link.clone(),
1513 size: *size,
1514 publisher: publisher.clone(),
1515 generation: layer.generation,
1516 });
1517 }
1518 for child in layer.children.iter() {
1519 parents.entry(*child).or_insert(id);
1520 self.collect_publish_state(*child, parents, leaders);
1521 }
1522 }
1523 fn ensure_published(
1524 &self,
1525 index: usize,
1526 leaders: &[LeaderRecord],
1527 parents: &HashMap<LayerId, LayerId>,
1528 states: &mut HashMap<LayerId, PublishState>,
1529 ) -> bool {
1530 let id = leaders[index].id;
1531 match states.get(&id) {
1532 Some(PublishState::Published) => return true,
1533 Some(PublishState::Unresolvable) => return false,
1534 Some(PublishState::InProgress) => {
1540 states.insert(id, PublishState::Unresolvable);
1541 return false;
1542 }
1543 None => {}
1544 }
1545 states.insert(id, PublishState::InProgress);
1546 let published = match self.leader_context(index, leaders, parents, states) {
1547 Some(world) => {
1548 let record = &leaders[index];
1549 record.link.publish(
1550 record.publisher.clone(),
1551 world,
1552 record.size,
1553 record.generation,
1554 );
1555 true
1556 }
1557 None => false,
1558 };
1559 states.insert(
1560 id,
1561 if published {
1562 PublishState::Published
1563 } else {
1564 PublishState::Unresolvable
1565 },
1566 );
1567 published
1568 }
1569 fn leader_context(
1578 &self,
1579 index: usize,
1580 leaders: &[LeaderRecord],
1581 parents: &HashMap<LayerId, LayerId>,
1582 states: &mut HashMap<LayerId, PublishState>,
1583 ) -> Option<Transform> {
1584 let mut chain = vec![leaders[index].id];
1585 while let Some(parent) = chain.last().and_then(|id| parents.get(id)) {
1586 chain.push(*parent);
1587 }
1588 let mut world = Transform::IDENTITY;
1589 let mut clip: Option<Rect> = None;
1590 for node in chain.iter().rev() {
1591 let layer = self.layers.get(node.0)?;
1592 match &layer.kind {
1593 LayerKind::Transform { transform } => {
1594 world = world.then(*transform);
1595 }
1596 LayerKind::Follower(follower) => {
1597 let link = &follower.link;
1598 if link.leader_transform().is_none() {
1599 for dependency in 0..leaders.len() {
1603 if leaders[dependency].link == *link {
1604 self.ensure_published(dependency, leaders, parents, states);
1605 if link.leader_transform().is_some() {
1606 break;
1607 }
1608 }
1609 }
1610 }
1611 match link.leader_transform() {
1612 Some(_) => {
1613 world = self.follower_transform(world, follower)?;
1614 }
1615 None if follower.show_when_unlinked => {}
1616 None => return None,
1617 }
1618 }
1619 LayerKind::ClipRect { .. }
1620 | LayerKind::ClipRRect { .. }
1621 | LayerKind::ClipOval { .. }
1622 | LayerKind::ClipPath { .. } => {
1623 let shape = clip_world_bounds(&layer.kind, world)?;
1624 clip = match clip {
1625 Some(active) => active.intersection(shape),
1626 None => Some(shape),
1627 };
1628 clip?;
1631 }
1632 _ => {}
1633 }
1634 }
1635 Some(world)
1636 }
1637 fn follower_transform(
1638 &self,
1639 world_transform: Transform,
1640 follower: &FollowerLayer,
1641 ) -> Option<Transform> {
1642 let FollowerLayer {
1643 link,
1644 show_when_unlinked,
1645 offset,
1646 target_anchor,
1647 follower_anchor,
1648 size,
1649 } = follower;
1650 let Some(leader_transform) = link.leader_transform() else {
1651 return show_when_unlinked.then_some(world_transform);
1652 };
1653 let leader_size = link.leader_size().unwrap_or(Size::ZERO);
1654 let desired_anchor =
1655 resolve_follower_target(leader_transform, leader_size, *target_anchor, *offset);
1656 let desired_local = world_transform.inverse_transform_point(desired_anchor)?;
1657 let local_delta = desired_local - follower_anchor.along_size(*size);
1658 Some(world_transform.then(Transform::translation(local_delta)))
1659 }
1660 fn collect_annotations(&mut self, id: LayerId, world_transform: Transform, clip: Option<Rect>) {
1661 let Some(kind) = self.layers.get(id.0).map(|layer| layer.kind.clone()) else {
1662 return;
1663 };
1664 match kind {
1665 LayerKind::Transform { transform } => {
1666 let next = world_transform.then(transform);
1667 self.visit_children(id, false, |tree, child| {
1668 tree.collect_annotations(child, next, clip)
1669 });
1670 }
1671 LayerKind::ClipRect { rect, .. } => {
1672 let world = world_transform.transform_rect_bbox(rect);
1673 let next_clip = match clip {
1674 Some(current) => current.intersection(world),
1675 None => Some(world),
1676 };
1677 if next_clip.is_none() {
1678 return;
1679 }
1680 self.visit_children(id, false, |tree, child| {
1681 tree.collect_annotations(child, world_transform, next_clip)
1682 });
1683 }
1684 LayerKind::ClipRRect { .. }
1685 | LayerKind::ClipOval { .. }
1686 | LayerKind::ClipPath { .. } => {
1687 let Some(world) = clip_world_bounds(&kind, world_transform) else {
1688 return;
1689 };
1690 let next_clip = match clip {
1691 Some(current) => current.intersection(world),
1692 None => Some(world),
1693 };
1694 if next_clip.is_none() {
1695 return;
1696 }
1697 self.visit_children(id, false, |tree, child| {
1698 tree.collect_annotations(child, world_transform, next_clip)
1699 });
1700 }
1701 LayerKind::Follower(follower) => {
1702 let Some(next) = self.follower_transform(world_transform, &follower) else {
1703 return;
1704 };
1705 self.visit_children(id, false, |tree, child| {
1706 tree.collect_annotations(child, next, clip)
1707 });
1708 }
1709 LayerKind::AnnotatedRegion {
1710 annotation,
1711 sized,
1712 size,
1713 } => {
1714 self.visit_children(id, true, |tree, child| {
1718 tree.collect_annotations(child, world_transform, clip)
1719 });
1720 let region =
1721 world_transform.transform_rect_bbox(Rect::from_origin_size(Offset::ZERO, size));
1722 let world_bounds = if sized {
1723 match clip {
1724 Some(active) => active.intersection(region),
1725 None => Some(region),
1726 }
1727 } else {
1728 clip
1729 };
1730 if world_bounds
1731 .is_none_or(|bounds| bounds.size.width > 0. && bounds.size.height > 0.)
1732 {
1733 self.flattened_annotations.push(FlattenedAnnotation {
1734 annotation,
1735 world_bounds,
1736 });
1737 }
1738 }
1739 LayerKind::Picture { .. }
1740 | LayerKind::Opacity { .. }
1741 | LayerKind::Blur { .. }
1742 | LayerKind::DropShadow { .. }
1743 | LayerKind::ColorFilter { .. }
1744 | LayerKind::Blend { .. }
1745 | LayerKind::ShaderMask { .. }
1746 | LayerKind::BackdropFilter { .. }
1747 | LayerKind::Leader { .. } => {
1748 self.visit_children(id, false, |tree, child| {
1749 tree.collect_annotations(child, world_transform, clip)
1750 });
1751 }
1752 }
1753 }
1754 fn subtree_generation(&self, id: LayerId) -> u64 {
1755 let Some(layer) = self.layers.get(id.0) else {
1756 return 0;
1757 };
1758 let mut value = layer.generation.wrapping_mul(0x9e37_79b9_7f4a_7c15);
1759 for child in &layer.children {
1760 if let Some(child_layer) = self.layers.get(child.0)
1768 && let LayerKind::Opacity { alpha } = &child_layer.kind
1769 {
1770 value = value.rotate_left(11) ^ u64::from(alpha.to_bits());
1771 }
1772 if let Some(child_layer) = self.layers.get(child.0) {
1773 match &child_layer.kind {
1774 LayerKind::Blur { blur } => {
1775 value = value.rotate_left(13)
1776 ^ u64::from(blur.sigma_x.to_bits())
1777 ^ u64::from(blur.sigma_y.to_bits()).rotate_left(17);
1778 }
1779 LayerKind::DropShadow { shadow } => {
1780 value = value.rotate_left(13)
1781 ^ u64::from(shadow.offset.x.to_bits())
1782 ^ u64::from(shadow.offset.y.to_bits()).rotate_left(7)
1783 ^ u64::from(shadow.sigma_x.to_bits()).rotate_left(17)
1784 ^ u64::from(shadow.sigma_y.to_bits()).rotate_left(23)
1785 ^ u64::from(shadow.color.red)
1786 ^ (u64::from(shadow.color.green) << 8)
1787 ^ (u64::from(shadow.color.blue) << 16)
1788 ^ (u64::from(shadow.color.alpha) << 24);
1789 }
1790 LayerKind::ColorFilter { filter } => {
1791 for (index, bits) in filter.to_matrix().map(f32::to_bits).iter().enumerate()
1792 {
1793 value ^= u64::from(*bits).rotate_left((index as u32 % 31) + 1);
1794 }
1795 }
1796 LayerKind::Blend { mode } => {
1797 value = value.rotate_left(13) ^ u64::from(mode.code());
1798 }
1799 LayerKind::ShaderMask {
1800 shader,
1801 blend_mode,
1802 mask_size,
1803 mask_transform,
1804 } => {
1805 value = value.rotate_left(13)
1806 ^ brush_generation(shader)
1807 ^ u64::from(blend_mode.code())
1808 ^ u64::from(mask_size.width.to_bits()).rotate_left(9)
1809 ^ u64::from(mask_size.height.to_bits()).rotate_left(15)
1810 ^ transform_generation(**mask_transform);
1811 }
1812 LayerKind::BackdropFilter {
1813 blur,
1814 blend_mode,
1815 enabled,
1816 } => {
1817 value = value.rotate_left(13)
1818 ^ u64::from(blur.sigma_x.to_bits())
1819 ^ u64::from(blur.sigma_y.to_bits()).rotate_left(7)
1820 ^ u64::from(blend_mode.code())
1821 ^ u64::from(*enabled as u8);
1822 }
1823 LayerKind::AnnotatedRegion {
1824 annotation: _,
1825 sized,
1826 size,
1827 } => {
1828 value = value.rotate_left(13)
1829 ^ u64::from(*sized as u8)
1830 ^ u64::from(size.width.to_bits()).rotate_left(9)
1831 ^ u64::from(size.height.to_bits()).rotate_left(15);
1832 }
1833 LayerKind::Leader { link, size, .. } => {
1834 value = value.rotate_left(13)
1835 ^ link.leader_generation()
1836 ^ u64::from(size.width.to_bits()).rotate_left(9)
1837 ^ u64::from(size.height.to_bits()).rotate_left(15);
1838 }
1839 LayerKind::Follower(follower) => {
1840 value = value.rotate_left(13)
1841 ^ follower.link.leader_generation()
1842 ^ u64::from(follower.show_when_unlinked as u8)
1843 ^ u64::from(follower.offset.x.to_bits())
1844 ^ u64::from(follower.offset.y.to_bits()).rotate_left(7)
1845 ^ u64::from(follower.target_anchor.x.to_bits()).rotate_left(13)
1846 ^ u64::from(follower.target_anchor.y.to_bits()).rotate_left(17)
1847 ^ u64::from(follower.follower_anchor.x.to_bits()).rotate_left(21)
1848 ^ u64::from(follower.follower_anchor.y.to_bits()).rotate_left(25)
1849 ^ u64::from(follower.size.width.to_bits()).rotate_left(29)
1850 ^ u64::from(follower.size.height.to_bits()).rotate_left(31);
1851 }
1852 _ => {}
1853 }
1854 }
1855 value = value.rotate_left(7) ^ self.subtree_generation(*child);
1856 }
1857 value
1858 }
1859 fn subtree_bounds(&self, id: LayerId, world_transform: Transform) -> Option<Rect> {
1860 let layer = self.layers.get(id.0)?;
1861 match &layer.kind {
1862 LayerKind::Picture { bounds, .. } => Some(world_transform.transform_rect_bbox(*bounds)),
1863 LayerKind::Transform { transform: local } => layer
1864 .children
1865 .iter()
1866 .filter_map(|child| self.subtree_bounds(*child, world_transform.then(*local)))
1867 .reduce(union_rect),
1868 LayerKind::ClipRect { rect, .. } => {
1869 let world = world_transform.transform_rect_bbox(*rect);
1870 layer
1871 .children
1872 .iter()
1873 .filter_map(|child| self.subtree_bounds(*child, world_transform))
1874 .reduce(union_rect)
1875 .and_then(|bounds| bounds.intersection(world))
1876 }
1877 LayerKind::ClipRRect { .. }
1878 | LayerKind::ClipOval { .. }
1879 | LayerKind::ClipPath { .. } => {
1880 let world = clip_world_bounds(&layer.kind, world_transform)?;
1881 layer
1882 .children
1883 .iter()
1884 .filter_map(|child| self.subtree_bounds(*child, world_transform))
1885 .reduce(union_rect)
1886 .and_then(|bounds| bounds.intersection(world))
1887 }
1888 LayerKind::Opacity { .. } => layer
1889 .children
1890 .iter()
1891 .filter_map(|child| self.subtree_bounds(*child, world_transform))
1892 .reduce(union_rect),
1893 LayerKind::Blur { .. } | LayerKind::DropShadow { .. } => layer
1894 .children
1895 .iter()
1896 .filter_map(|child| self.subtree_bounds(*child, world_transform))
1897 .reduce(union_rect),
1898 LayerKind::ColorFilter { .. } | LayerKind::Blend { .. } => layer
1899 .children
1900 .iter()
1901 .filter_map(|child| self.subtree_bounds(*child, world_transform))
1902 .reduce(union_rect),
1903 LayerKind::ShaderMask { .. }
1904 | LayerKind::BackdropFilter { .. }
1905 | LayerKind::AnnotatedRegion { .. }
1906 | LayerKind::Leader { .. } => layer
1907 .children
1908 .iter()
1909 .filter_map(|child| self.subtree_bounds(*child, world_transform))
1910 .reduce(union_rect),
1911 LayerKind::Follower(follower) => {
1912 let next = self.follower_transform(world_transform, follower)?;
1913 layer
1914 .children
1915 .iter()
1916 .filter_map(|child| self.subtree_bounds(*child, next))
1917 .reduce(union_rect)
1918 }
1919 }
1920 }
1921
1922 fn visual_subtree_bounds(&self, id: LayerId, world_transform: Transform) -> Option<Rect> {
1923 let layer = self.layers.get(id.0)?;
1924 let child_bounds = |tree: &Self, transform: Transform| {
1925 layer
1926 .children
1927 .iter()
1928 .filter_map(|child| tree.visual_subtree_bounds(*child, transform))
1929 .reduce(union_rect)
1930 };
1931 match &layer.kind {
1932 LayerKind::Picture { bounds, .. } => Some(world_transform.transform_rect_bbox(*bounds)),
1933 LayerKind::Transform { transform: local } => {
1934 child_bounds(self, world_transform.then(*local))
1935 }
1936 LayerKind::ClipRect { rect, .. } => {
1937 let world = world_transform.transform_rect_bbox(*rect);
1938 child_bounds(self, world_transform).and_then(|bounds| bounds.intersection(world))
1939 }
1940 LayerKind::ClipRRect { .. }
1941 | LayerKind::ClipOval { .. }
1942 | LayerKind::ClipPath { .. } => {
1943 let world = clip_world_bounds(&layer.kind, world_transform)?;
1944 child_bounds(self, world_transform).and_then(|bounds| bounds.intersection(world))
1945 }
1946 LayerKind::Opacity { .. }
1947 | LayerKind::ColorFilter { .. }
1948 | LayerKind::Blend { .. }
1949 | LayerKind::ShaderMask { .. }
1950 | LayerKind::BackdropFilter { .. }
1951 | LayerKind::AnnotatedRegion { .. }
1952 | LayerKind::Leader { .. } => child_bounds(self, world_transform),
1953 LayerKind::Blur { blur } => child_bounds(self, world_transform)
1954 .map(|bounds| blur_bounds(bounds, blur.sigma_x, blur.sigma_y)),
1955 LayerKind::DropShadow { shadow } => child_bounds(self, world_transform).map(|bounds| {
1956 drop_shadow_bounds(bounds, shadow.offset, shadow.sigma_x, shadow.sigma_y)
1957 }),
1958 LayerKind::Follower(follower) => {
1959 let next = self.follower_transform(world_transform, follower)?;
1960 child_bounds(self, next)
1961 }
1962 }
1963 }
1964 #[must_use]
1965 pub fn debug_tree(&self) -> String {
1966 let mut out = String::new();
1967 if let Some(root) = self.root {
1968 self.write_debug(root, 0, &mut out);
1969 }
1970 out
1971 }
1972 fn write_debug(&self, id: LayerId, depth: usize, out: &mut String) {
1973 self.write_debug_at(id, None, depth, Transform::IDENTITY, None, out);
1974 }
1975 fn write_debug_at(
1976 &self,
1977 id: LayerId,
1978 parent: Option<LayerId>,
1979 depth: usize,
1980 world_transform: Transform,
1981 clip: Option<Rect>,
1982 out: &mut String,
1983 ) {
1984 let Some(layer) = self.layers.get(id.0) else {
1985 return;
1986 };
1987 let indent = " ".repeat(depth);
1988 let kind = match &layer.kind {
1989 LayerKind::Picture { bounds, .. } => format!(
1990 "Picture(local_bounds={bounds:?}, world_bounds={:?}, clip={clip:?})",
1991 world_transform.transform_rect_bbox(*bounds)
1992 ),
1993 LayerKind::Transform { transform } => {
1994 format!(
1995 "Transform(local={:?}, world={:?})",
1996 transform,
1997 world_transform.then(*transform)
1998 )
1999 }
2000 LayerKind::ClipRect { rect, .. } => format!(
2001 "ClipRect(local={rect:?}, world={:?})",
2002 world_transform.transform_rect_bbox(*rect)
2003 ),
2004 LayerKind::ClipRRect { rrect, .. } => format!(
2005 "ClipRRect(local={rrect:?}, world={:?})",
2006 world_transform.transform_rect_bbox(rrect.rect)
2007 ),
2008 LayerKind::ClipOval { rect, .. } => format!(
2009 "ClipOval(local={rect:?}, world={:?})",
2010 world_transform.transform_rect_bbox(*rect)
2011 ),
2012 LayerKind::ClipPath { path, .. } => format!(
2013 "ClipPath(local_bounds={:?}, world={:?})",
2014 path.bounds(),
2015 clip_world_bounds(&layer.kind, world_transform)
2016 ),
2017 LayerKind::Opacity { alpha } => format!(
2018 "Opacity(alpha={alpha:.3}, bounds={:?}, generation={})",
2019 self.subtree_bounds(id, world_transform),
2020 self.subtree_generation(id)
2021 ),
2022 LayerKind::Blur { blur } => format!(
2023 "Blur(sigma=({:.3},{:.3}), bounds={:?}, generation={})",
2024 blur.sigma_x,
2025 blur.sigma_y,
2026 self.subtree_bounds(id, world_transform),
2027 self.subtree_generation(id)
2028 ),
2029 LayerKind::DropShadow { shadow } => format!(
2030 "DropShadow(sigma=({:.3},{:.3}), offset={:?}, bounds={:?}, generation={})",
2031 shadow.sigma_x,
2032 shadow.sigma_y,
2033 shadow.offset,
2034 self.subtree_bounds(id, world_transform),
2035 self.subtree_generation(id)
2036 ),
2037 LayerKind::ColorFilter { filter } => format!(
2038 "ColorFilter(matrix={:?}, bounds={:?}, generation={})",
2039 filter.to_matrix(),
2040 self.subtree_bounds(id, world_transform),
2041 self.subtree_generation(id)
2042 ),
2043 LayerKind::Blend { mode } => format!(
2044 "Blend(mode={mode:?}, bounds={:?}, generation={})",
2045 self.subtree_bounds(id, world_transform),
2046 self.subtree_generation(id)
2047 ),
2048 LayerKind::ShaderMask {
2049 blend_mode,
2050 mask_size,
2051 ..
2052 } => format!(
2053 "ShaderMask(blend_mode={blend_mode:?}, mask_size={mask_size:?}, bounds={:?}, generation={})",
2054 self.subtree_bounds(id, world_transform),
2055 self.subtree_generation(id)
2056 ),
2057 LayerKind::BackdropFilter {
2058 blur,
2059 blend_mode,
2060 enabled,
2061 } => format!(
2062 "BackdropFilter(sigma=({:.3},{:.3}), blend_mode={blend_mode:?}, enabled={enabled}, bounds={:?}, generation={})",
2063 blur.sigma_x,
2064 blur.sigma_y,
2065 self.subtree_bounds(id, world_transform),
2066 self.subtree_generation(id)
2067 ),
2068 LayerKind::AnnotatedRegion { sized, size, .. } => format!(
2069 "AnnotatedRegion(sized={sized}, size={size:?}, generation={})",
2070 self.subtree_generation(id)
2071 ),
2072 LayerKind::Leader { link, size, .. } => format!(
2073 "CompositedTransformTarget(size={size:?}, linked={}, generation={})",
2074 link.is_linked(),
2075 self.subtree_generation(id)
2076 ),
2077 LayerKind::Follower(FollowerLayer {
2078 show_when_unlinked,
2079 offset,
2080 target_anchor,
2081 follower_anchor,
2082 ..
2083 }) => format!(
2084 "CompositedTransformFollower(show_when_unlinked={show_when_unlinked}, offset={offset:?}, target_anchor={target_anchor:?}, follower_anchor={follower_anchor:?}, bounds={:?}, generation={})",
2085 self.subtree_bounds(id, world_transform),
2086 self.subtree_generation(id)
2087 ),
2088 };
2089 out.push_str(&format!("{indent}{id:?} parent={parent:?} {kind}\n"));
2090 let (next_translation, next_clip) = match &layer.kind {
2091 LayerKind::Picture { .. } => (world_transform, clip),
2092 LayerKind::Transform { transform: local } => (world_transform.then(*local), clip),
2093 LayerKind::ClipRect { rect, .. } => {
2094 let world = world_transform.transform_rect_bbox(*rect);
2095 (
2096 world_transform,
2097 Some(clip.map_or(world, |old| old.intersection(world).unwrap_or(world))),
2098 )
2099 }
2100 LayerKind::ClipRRect { .. }
2101 | LayerKind::ClipOval { .. }
2102 | LayerKind::ClipPath { .. } => {
2103 let narrowed = clip_world_bounds(&layer.kind, world_transform).map(|world| {
2106 clip.map_or(world, |old| old.intersection(world).unwrap_or(world))
2107 });
2108 (world_transform, narrowed.or(clip))
2109 }
2110 LayerKind::Opacity { .. } => (world_transform, clip),
2111 LayerKind::Blur { .. } | LayerKind::DropShadow { .. } => (world_transform, clip),
2112 LayerKind::ColorFilter { .. } | LayerKind::Blend { .. } => (world_transform, clip),
2113 LayerKind::ShaderMask { .. }
2114 | LayerKind::BackdropFilter { .. }
2115 | LayerKind::AnnotatedRegion { .. }
2116 | LayerKind::Leader { .. } => (world_transform, clip),
2117 LayerKind::Follower(follower) => (
2118 self.follower_transform(world_transform, follower)
2119 .unwrap_or(world_transform),
2120 clip,
2121 ),
2122 };
2123 for child in &layer.children {
2124 self.write_debug_at(
2125 *child,
2126 Some(id),
2127 depth + 1,
2128 next_translation,
2129 next_clip,
2130 out,
2131 );
2132 }
2133 }
2134}
2135
2136fn brush_generation(brush: &Brush) -> u64 {
2137 match brush {
2138 Brush::Solid(color) => {
2139 u64::from(color.red)
2140 | (u64::from(color.green) << 8)
2141 | (u64::from(color.blue) << 16)
2142 | (u64::from(color.alpha) << 24)
2143 }
2144 Brush::LinearGradient(gradient) => {
2145 gradient.stops.id().get()
2146 ^ u64::from(gradient.start.x.to_bits()).rotate_left(7)
2147 ^ u64::from(gradient.start.y.to_bits()).rotate_left(13)
2148 ^ u64::from(gradient.end.x.to_bits()).rotate_left(19)
2149 ^ u64::from(gradient.end.y.to_bits()).rotate_left(23)
2150 }
2151 Brush::RadialGradient(gradient) => {
2152 gradient.stops.id().get()
2153 ^ u64::from(gradient.center.x.to_bits()).rotate_left(7)
2154 ^ u64::from(gradient.center.y.to_bits()).rotate_left(13)
2155 ^ u64::from(gradient.radius.to_bits()).rotate_left(19)
2156 }
2157 Brush::SweepGradient(gradient) => {
2158 gradient.stops.id().get()
2159 ^ u64::from(gradient.center.x.to_bits()).rotate_left(7)
2160 ^ u64::from(gradient.center.y.to_bits()).rotate_left(13)
2161 ^ u64::from(gradient.start_angle.to_bits()).rotate_left(19)
2162 }
2163 }
2164}
2165
2166fn transform_generation(transform: Transform) -> u64 {
2167 transform
2168 .to_kurbo()
2169 .as_coeffs()
2170 .iter()
2171 .enumerate()
2172 .fold(0, |value, (index, coefficient)| {
2173 value ^ coefficient.to_bits().rotate_left((index as u32 * 9) % 63)
2174 })
2175}