Skip to main content

inset_rendering/
layer.rs

1//! Port of Flutter's `rendering/layer.dart`.
2//!
3//! The layer tree: what a repaint boundary's recording is between paint and compositing, and
4//! what `RenderView.compositeFrame` uploads through a [`SceneBuilder`]. A layer is an arena
5//! object; edges are [`AnyLayer`] / [`AnyContainerLayer`] and lifetime is Flutter's
6//! [`LayerHandle`] count, which ends in `dispose` and `App::destroy`.
7//!
8//! No `EngineLayer`: valo composites a display list, so `addToScene` runs for every layer every
9//! frame and the retained-rendering bookkeeping (`_needsAddToScene`, `markNeedsAddToScene`,
10//! `alwaysNeedsAddToScene`, `addRetained`, `engineLayer`) has nothing to decide and is not
11//! ported. See `PORTING.md`.
12
13use std::any::{Any, TypeId};
14use std::cell::Cell;
15use std::collections::HashSet;
16use std::fmt::{self, Debug};
17use std::hash::{Hash, Hasher};
18use std::rc::Rc;
19use std::sync::Arc;
20use std::sync::atomic::{AtomicU64, Ordering};
21
22use inset_embedder::Surface;
23use inset_embedder::{
24    BlendMode, Clip, EngineLayer, FillRule, ImageFilter, Matrix4, Offset, Picture, RRect, Rect,
25    Scene, SceneBuilder, Size,
26};
27use inset_foundation::{App, Handle, HandleId, RetainedHandle};
28use inset_gestures::remove_perspective_transform;
29use inset_scheduler::{FrameCallback, SchedulerBinding};
30
31/// Information collected for an annotation that is found in the layer tree.
32///
33/// See also:
34///
35///  * [`AnyLayer::find_all_annotations`], which creates and uses objects of this type.
36#[derive(Debug)]
37pub struct AnnotationEntry<T> {
38    /// The annotation object that is found.
39    pub annotation: Rc<T>,
40    /// The target location described by the local coordinate space of the annotation object.
41    pub local_position: Offset,
42}
43
44impl<T> AnnotationEntry<T> {
45    /// Create an entry of found annotation by providing the object and related information.
46    pub fn new(annotation: Rc<T>, local_position: Offset) -> AnnotationEntry<T> {
47        AnnotationEntry {
48            annotation,
49            local_position,
50        }
51    }
52}
53
54/// Information collected about a list of annotations that are found in the layer tree.
55///
56/// See also:
57///
58///  * [`AnnotationEntry`], which are members of this type.
59///  * [`AnyLayer::find_all_annotations`], which creates and uses an object of this type.
60#[derive(Debug)]
61pub struct AnnotationResult<T> {
62    entries: Vec<AnnotationEntry<T>>,
63}
64
65impl<T> AnnotationResult<T> {
66    /// An empty result.
67    pub fn new() -> AnnotationResult<T> {
68        AnnotationResult {
69            entries: Vec::new(),
70        }
71    }
72
73    /// Add a new entry to the end of the result.
74    ///
75    /// Usually, entries should be added in order from most specific to least specific,
76    /// typically during an upward walk of the tree.
77    pub fn add(&mut self, entry: AnnotationEntry<T>) {
78        self.entries.push(entry);
79    }
80
81    /// The [`AnnotationEntry`] objects recorded.
82    ///
83    /// The first entry is the most specific, typically the one at the leaf of the tree.
84    pub fn entries(&self) -> &[AnnotationEntry<T>] {
85        &self.entries
86    }
87
88    /// The annotations recorded.
89    ///
90    /// The first entry is the most specific, typically the one at the leaf of the tree. It is
91    /// similar to [`entries`](Self::entries) but does not contain other information.
92    pub fn annotations(&self) -> impl Iterator<Item = &Rc<T>> {
93        self.entries.iter().map(|entry| &entry.annotation)
94    }
95}
96
97impl<T> Default for AnnotationResult<T> {
98    fn default() -> AnnotationResult<T> {
99        AnnotationResult::new()
100    }
101}
102
103/// Dart's `AnnotationResult<S>` while a search walks the tree: the type it looks for and what
104/// it has found, erased so [`Layer::find_annotations`] can sit in a vtable. [`AnyLayer::find`]
105/// and [`AnyLayer::find_all_annotations`] turn it back into an [`AnnotationResult<S>`]. See
106/// `PORTING.md`.
107#[derive(Debug)]
108pub struct AnnotationSearch {
109    searched: TypeId,
110    entries: Vec<(Rc<dyn Any>, Offset)>,
111}
112
113impl AnnotationSearch {
114    fn new<S: 'static>() -> AnnotationSearch {
115        AnnotationSearch {
116            searched: TypeId::of::<S>(),
117            entries: Vec::new(),
118        }
119    }
120
121    /// Dart's `T == S`: whether `annotation` is exactly the type this search is for.
122    pub fn accepts(&self, annotation: &dyn Any) -> bool {
123        annotation.type_id() == self.searched
124    }
125
126    /// Dart's `result.add(AnnotationEntry(annotation:, localPosition:))`. Only for an
127    /// annotation [`accepts`](Self::accepts) answered true for.
128    pub fn add(&mut self, annotation: Rc<dyn Any>, local_position: Offset) {
129        debug_assert!(self.accepts(&*annotation));
130        self.entries.push((annotation, local_position));
131    }
132
133    /// Dart's `result.entries.isNotEmpty`, negated.
134    pub fn is_empty(&self) -> bool {
135        self.entries.is_empty()
136    }
137
138    fn into_result<S: 'static>(self) -> AnnotationResult<S> {
139        let mut result = AnnotationResult::new();
140        for (annotation, local_position) in self.entries {
141            let annotation = annotation
142                .downcast::<S>()
143                .expect("an accepted annotation is the searched type");
144            result.add(AnnotationEntry::new(annotation, local_position));
145        }
146        result
147    }
148}
149
150/// The callback of [`AnyLayer::add_composition_callback`].
151pub type CompositionCallback = Rc<dyn Fn(&mut App, AnyLayer)>;
152
153static NEXT_CALLBACK_ID: AtomicU64 = AtomicU64::new(0);
154
155/// Flutter's `Layer` fields, held by every layer under the field `layer`
156/// ([`layer_accessors!`]).
157pub struct LayerData {
158    callbacks: Vec<(u64, CompositionCallback)>,
159    composition_callback_count: i32,
160    debug_mutations_locked: bool,
161    /// Set when this layer is appended to a [`ContainerLayer`], and unset when it is removed.
162    ///
163    /// This cannot be set from `attach` or `detach` which is called when an entire subtree is
164    /// attached to or detached from an owner. Layers may be appended to or removed from a
165    /// [`ContainerLayer`] regardless of whether they are attached or detached, and detaching a
166    /// layer from an owner does not imply that it has been removed from its parent.
167    parent_handle: LayerHandle<AnyLayer>,
168    /// Incremented by [`LayerHandle`].
169    ref_count: u32,
170    debug_disposed: bool,
171    parent: Option<AnyContainerLayer>,
172    owner: Option<HandleId>,
173    depth: i32,
174    next_sibling: Option<AnyLayer>,
175    previous_sibling: Option<AnyLayer>,
176    /// Whether `add_to_scene` must run for this layer: it changed since it was last added, or
177    /// never was. `update_subtree_needs_add_to_scene` folds the descendants' in before a scene
178    /// is built.
179    needs_add_to_scene: bool,
180    /// The list this layer's subtree recorded when it was last added, for
181    /// [`SceneBuilder::add_retained`] while nothing in the subtree changed.
182    engine_layer: Option<EngineLayer>,
183}
184
185impl LayerData {
186    /// Flutter's `Layer()` constructor.
187    pub const fn new() -> LayerData {
188        LayerData {
189            callbacks: Vec::new(),
190            composition_callback_count: 0,
191            debug_mutations_locked: false,
192            parent_handle: LayerHandle::new(),
193            ref_count: 0,
194            debug_disposed: false,
195            parent: None,
196            owner: None,
197            depth: 0,
198            next_sibling: None,
199            previous_sibling: None,
200            needs_add_to_scene: true,
201            engine_layer: None,
202        }
203    }
204}
205
206impl Default for LayerData {
207    fn default() -> LayerData {
208        LayerData::new()
209    }
210}
211
212impl Debug for LayerData {
213    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
214        f.debug_struct("Layer")
215            .field("owner", &self.owner)
216            .field("handles", &self.ref_count)
217            .finish_non_exhaustive()
218    }
219}
220
221/// Implements the [`Layer`] field accessors for a `layer` field.
222///
223/// `layer_accessors!(container)` also records that the type `extends ContainerLayer`, so its
224/// [`AnyLayer`] can be narrowed with [`AnyLayer::as_container_layer`].
225#[macro_export]
226macro_rules! layer_accessors {
227    () => {
228        fn layer_data(
229            self: ::inset_foundation::Handle<Self>,
230            app: &::inset_foundation::App,
231        ) -> &$crate::LayerData {
232            &app.get(self).layer
233        }
234        fn layer_data_mut(
235            self: ::inset_foundation::Handle<Self>,
236            app: &mut ::inset_foundation::App,
237        ) -> &mut $crate::LayerData {
238            &mut app.get_mut(self).layer
239        }
240    };
241    (container) => {
242        $crate::layer_accessors!();
243        const AS_CONTAINER: Option<fn() -> &'static $crate::ContainerLayerVTable> =
244            Some(|| const { &$crate::ContainerLayerVTable::of::<Self>() });
245    };
246}
247
248/// A composited layer.
249///
250/// During painting, the render tree generates a tree of composited layers that are uploaded
251/// into the engine and displayed by the compositor. This class is the base class for all
252/// composited layers.
253///
254/// Most layers can have their properties mutated, and layers can be moved to different parents.
255/// The scene must be explicitly recomposited after such changes are made; the layer tree does
256/// not maintain its own dirty state.
257///
258/// To composite the tree, create a [`SceneBuilder`] object, pass it to the root layer's
259/// [`AnyContainerLayer::build_scene`] and give the [`Scene`] to the view.
260///
261/// ## Memory
262///
263/// Layers retain resources between frames to speed up rendering. A layer will retain these
264/// resources until all [`LayerHandle`]s referring to the layer have nulled out their references.
265///
266/// Layers must not be used after disposal. If a `RenderObject` needs to maintain a layer for
267/// later usage, it must create a handle to that layer. This is handled automatically for the
268/// `RenderObject.layer` property, but additional layers must use their own [`LayerHandle`].
269///
270/// Flutter's abstract `Layer`: the shared bodies are on [`LayerBase`]. A leaf implements this
271/// trait; where Dart runs the inherited body it calls it by name, `LayerBase::attach(self, app,
272/// owner)`.
273pub trait Layer: Sized + 'static {
274    /// Dart's base-class fields, held under the field `layer` ([`layer_accessors!`]).
275    fn layer_data(self: Handle<Self>, app: &App) -> &LayerData;
276
277    /// See [`layer_data`](Self::layer_data).
278    fn layer_data_mut(self: Handle<Self>, app: &mut App) -> &mut LayerData;
279
280    /// The container table when this type `extends ContainerLayer`; `layer_accessors!(container)`
281    /// sets it. Dart's `layer is ContainerLayer`.
282    const AS_CONTAINER: Option<fn() -> &'static ContainerLayerVTable> = None;
283
284    /// Whether or not this layer, or any child layers, can be rasterized with `Scene.toImage`.
285    ///
286    /// If `false`, calling the above methods may yield an image which is incomplete.
287    ///
288    /// This value may change throughout the lifetime of the object, as the child layers
289    /// themselves are added or removed.
290    fn supports_rasterization(self: Handle<Self>, app: &App) -> bool {
291        let _ = (self, app);
292        true
293    }
294
295    /// Describes the clip that would be applied to contents of this layer, if any.
296    fn describe_clip_bounds(self: Handle<Self>, app: &App) -> Option<Rect> {
297        let _ = (self, app);
298        None
299    }
300
301    /// Subclasses may override this to true to disable retained rendering.
302    fn always_needs_add_to_scene(self: Handle<Self>, app: &App) -> bool {
303        let _ = (self, app);
304        false
305    }
306
307    /// Clears any retained resources that this layer holds.
308    ///
309    /// This method must dispose resources such as [`Picture`] objects. The layer is still usable
310    /// after this call, but any graphics related resources it holds will need to be recreated.
311    ///
312    /// This method _only_ disposes resources for this layer. For example, if it is a
313    /// [`ContainerLayer`], it does not dispose resources of any children. However,
314    /// [`ContainerLayer`]s do remove any children they have when this method is called, and if
315    /// this layer was the last holder of a removed child handle, the child may recursively clean
316    /// up its resources.
317    ///
318    /// This method automatically gets called when all outstanding [`LayerHandle`]s are disposed.
319    /// [`LayerHandle`] objects are typically held by the parent layer of this layer and any
320    /// `RenderObject`s that participated in creating it.
321    ///
322    /// After calling this method, the object is unusable: the base body destroys the arena entry.
323    /// An override ends with `LayerBase::dispose(self, app)`.
324    fn dispose(self: Handle<Self>, app: &mut App) {
325        LayerBase::dispose(self, app);
326    }
327
328    /// Mark this layer as attached to the given owner.
329    ///
330    /// Typically called only from the parent's `attach` method, and by the owner to mark the
331    /// root of a tree as attached.
332    ///
333    /// Subclasses with children should override this method to `attach` all their children to
334    /// the same owner after calling the inherited method, `LayerBase::attach(self, app, owner)`.
335    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
336        LayerBase::attach(self, app, owner);
337    }
338
339    /// Mark this layer as detached from its owner.
340    ///
341    /// Typically called only from the parent's `detach`, and by the owner to mark the root of a
342    /// tree as detached.
343    ///
344    /// Subclasses with children should override this method to `detach` all their children
345    /// after calling the inherited method, `LayerBase::detach(self, app)`.
346    fn detach(self: Handle<Self>, app: &mut App) {
347        LayerBase::detach(self, app);
348    }
349
350    /// Adjust the depth of this node's children, if any.
351    ///
352    /// Override this method in subclasses with child nodes to call
353    /// [`AnyContainerLayer::redepth_child`] for each child. Do not call this method directly.
354    fn redepth_children(self: Handle<Self>, app: &mut App) {
355        // ContainerLayer provides an implementation since its the only one that
356        // can actually have children.
357        let _ = (self, app);
358    }
359
360    /// Search this layer and its subtree for annotations of the searched type at the location
361    /// described by `local_position`.
362    ///
363    /// This method is called by the default implementation of [`AnyLayer::find`] and
364    /// [`AnyLayer::find_all_annotations`]. Override this method to customize how the layer
365    /// should search for annotations, or if the layer has its own annotations to add.
366    ///
367    /// The default implementation always returns `false`, which means neither the layer nor its
368    /// children has annotations, and the annotation search is not absorbed either.
369    ///
370    /// The annotations are searched by first visiting each child recursively, then this layer,
371    /// resulting in an order from visually front to back. New annotations found during the walk
372    /// are added to the tail of `result`.
373    ///
374    /// The `only_first` parameter indicates that, if true, the search will stop when it finds
375    /// the first qualified annotation; otherwise, it will walk the entire subtree.
376    ///
377    /// The return value indicates the opacity of this layer and its subtree at this position. If
378    /// it returns true, then this layer's parent should skip the children behind this layer. The
379    /// return value does not affect whether the parent adds its own annotations.
380    fn find_annotations(
381        self: Handle<Self>,
382        app: &App,
383        result: &mut AnnotationSearch,
384        local_position: Offset,
385        only_first: bool,
386    ) -> bool {
387        let _ = (self, app, result, local_position, only_first);
388        false
389    }
390
391    /// Override this method to upload this layer to the engine.
392    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder);
393
394    /// Dart's `_fireCompositionCallbacks`; [`ContainerLayer`] recurses into its children.
395    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
396        LayerBase::fire_composition_callbacks(self, app, include_children);
397    }
398}
399
400/// The bodies of Flutter's `Layer` that a subclass calls as `super`: `LayerBase::dispose(self,
401/// app)` where Dart writes `super.dispose()`. The virtual call is on [`AnyLayer`].
402pub trait LayerBase: Layer {
403    /// `Layer.dispose`.
404    fn dispose(self: Handle<Self>, app: &mut App) {
405        let data = self.layer_data_mut(app);
406        debug_assert!(!data.debug_mutations_locked);
407        debug_assert!(
408            !data.debug_disposed,
409            "Layers must only be disposed once. This is typically handled by LayerHandle. \
410             Subclasses should not directly call dispose, except to call LayerBase::dispose in \
411             an overridden dispose method. Tests must only call dispose once."
412        );
413        debug_assert!(
414            data.ref_count == 0,
415            "Do not directly call dispose on a layer. Instead, use a LayerHandle."
416        );
417        data.debug_disposed = true;
418        // Dart's engine layer is dropped here; the arena entry goes with it.
419        app.destroy(self);
420    }
421
422    /// `Layer.attach`.
423    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
424        let data = self.layer_data_mut(app);
425        debug_assert!(data.owner.is_none());
426        data.owner = Some(owner);
427    }
428
429    /// `Layer.detach`.
430    fn detach(self: Handle<Self>, app: &mut App) {
431        let data = self.layer_data_mut(app);
432        debug_assert!(data.owner.is_some());
433        data.owner = None;
434        let this = self.as_layer();
435        debug_assert!(
436            this.parent(app)
437                .is_none_or(|parent| this.attached(app) == parent.as_layer().attached(app))
438        );
439    }
440
441    /// `Layer._fireCompositionCallbacks`.
442    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
443        let _ = include_children;
444        let this = self.as_layer();
445        let callbacks: Vec<CompositionCallback> = self
446            .layer_data(app)
447            .callbacks
448            .iter()
449            .map(|(_, callback)| Rc::clone(callback))
450            .collect();
451        for callback in callbacks {
452            this.run_composition_callback(app, &callback);
453        }
454    }
455}
456
457impl<T: Layer> LayerBase for T {}
458
459/// The typed handle for an erased id. Free: nothing is looked up; `get` checks the slot.
460fn resolve<T: 'static>(id: HandleId) -> Handle<T> {
461    Handle::from_id(id)
462}
463
464/// The vtable of an erased [`AnyLayer`]: one `&'static` table per type, built from the trait
465/// impl by [`Layer::as_layer`]. Copied out of the handle before a virtual call, so the slot is
466/// not borrowed across it.
467///
468/// Public only so [`layer_accessors!`] can name it from another crate.
469#[doc(hidden)]
470pub struct LayerVTable {
471    layer_data: fn(&App, HandleId) -> &LayerData,
472    layer_data_mut: fn(&mut App, HandleId) -> &mut LayerData,
473    supports_rasterization: fn(&App, HandleId) -> bool,
474    describe_clip_bounds: fn(&App, HandleId) -> Option<Rect>,
475    always_needs_add_to_scene: fn(&App, HandleId) -> bool,
476    dispose: fn(&mut App, HandleId),
477    attach: fn(&mut App, HandleId, HandleId),
478    detach: fn(&mut App, HandleId),
479    redepth_children: fn(&mut App, HandleId),
480    find_annotations: fn(&App, HandleId, &mut AnnotationSearch, Offset, bool) -> bool,
481    add_to_scene: fn(&mut App, HandleId, &mut SceneBuilder),
482    fire_composition_callbacks: fn(&mut App, HandleId, bool),
483    as_container: Option<fn() -> &'static ContainerLayerVTable>,
484}
485
486impl LayerVTable {
487    pub const fn of<T: Layer>() -> LayerVTable {
488        LayerVTable {
489            layer_data: |app, id| T::layer_data(resolve(id), app),
490            layer_data_mut: |app, id| T::layer_data_mut(resolve(id), app),
491            supports_rasterization: |app, id| T::supports_rasterization(resolve(id), app),
492            describe_clip_bounds: |app, id| T::describe_clip_bounds(resolve(id), app),
493            always_needs_add_to_scene: |app, id| T::always_needs_add_to_scene(resolve(id), app),
494            dispose: |app, id| T::dispose(resolve(id), app),
495            attach: |app, id, owner| T::attach(resolve(id), app, owner),
496            detach: |app, id| T::detach(resolve(id), app),
497            redepth_children: |app, id| T::redepth_children(resolve(id), app),
498            find_annotations: |app, id, result, local_position, only_first| {
499                T::find_annotations(resolve(id), app, result, local_position, only_first)
500            },
501            add_to_scene: |app, id, builder| T::add_to_scene(resolve(id), app, builder),
502            fire_composition_callbacks: |app, id, include_children| {
503                T::fire_composition_callbacks(resolve(id), app, include_children)
504            },
505            as_container: T::AS_CONTAINER,
506        }
507    }
508}
509
510/// Erased `Layer`: one identity and a static vtable, the fat pointer rustc cannot build for an
511/// arena id. No lease.
512///
513/// Equality is Dart's `==` on an object reference.
514#[derive(Clone, Copy)]
515pub struct AnyLayer {
516    id: HandleId,
517    vtable: &'static LayerVTable,
518}
519
520impl PartialEq for AnyLayer {
521    fn eq(&self, other: &AnyLayer) -> bool {
522        self.id == other.id
523    }
524}
525
526impl Eq for AnyLayer {}
527
528impl Hash for AnyLayer {
529    fn hash<H: Hasher>(&self, state: &mut H) {
530        self.id.hash(state);
531    }
532}
533
534impl From<AnyLayer> for HandleId {
535    fn from(layer: AnyLayer) -> HandleId {
536        layer.id
537    }
538}
539
540impl Debug for AnyLayer {
541    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
542        write!(f, "AnyLayer({:?})", self.id)
543    }
544}
545
546impl AnyLayer {
547    pub fn id(self) -> HandleId {
548        self.id
549    }
550
551    fn data(self, app: &App) -> &LayerData {
552        (self.vtable.layer_data)(app, self.id)
553    }
554
555    fn data_mut(self, app: &mut App) -> &mut LayerData {
556        (self.vtable.layer_data_mut)(app, self.id)
557    }
558
559    /// Dart's `layer as ContainerLayer`, as an `Option`.
560    pub fn as_container_layer(self) -> Option<AnyContainerLayer> {
561        self.vtable
562            .as_container
563            .map(|vtable| AnyContainerLayer::from_vtable(self.id, vtable()))
564    }
565
566    /// Whether the subtree rooted at this layer has any composition callback observers.
567    ///
568    /// This only evaluates to true if the subtree rooted at this node has observers. For
569    /// example, it may evaluate to true on a parent node but false on a child if the parent has
570    /// observers but the child does not.
571    pub fn subtree_has_composition_callbacks(self, app: &App) -> bool {
572        self.data(app).composition_callback_count > 0
573    }
574
575    fn update_subtree_composition_observer_count(self, app: &mut App, delta: i32) {
576        debug_assert!(delta != 0);
577        let data = self.data_mut(app);
578        data.composition_callback_count += delta;
579        debug_assert!(data.composition_callback_count >= 0);
580        if let Some(parent) = data.parent {
581            parent
582                .as_layer()
583                .update_subtree_composition_observer_count(app, delta);
584        }
585    }
586
587    /// See [`Layer::fire_composition_callbacks`].
588    pub(crate) fn fire_composition_callbacks(self, app: &mut App, include_children: bool) {
589        (self.vtable.fire_composition_callbacks)(app, self.id, include_children);
590    }
591
592    /// The closure Dart stores in `_callbacks`: the callback between the mutation-lock asserts.
593    fn run_composition_callback(self, app: &mut App, callback: &CompositionCallback) {
594        if cfg!(debug_assertions) {
595            self.data_mut(app).debug_mutations_locked = true;
596        }
597        callback(app, self);
598        if cfg!(debug_assertions) {
599            self.data_mut(app).debug_mutations_locked = false;
600        }
601    }
602
603    /// See [`Layer::supports_rasterization`].
604    pub fn supports_rasterization(self, app: &App) -> bool {
605        (self.vtable.supports_rasterization)(app, self.id)
606    }
607
608    /// See [`Layer::describe_clip_bounds`].
609    pub fn describe_clip_bounds(self, app: &App) -> Option<Rect> {
610        (self.vtable.describe_clip_bounds)(app, self.id)
611    }
612
613    /// Adds a callback for when the layer tree that this layer is part of gets composited, or
614    /// when it is detached and will not be rendered again.
615    ///
616    /// The callback receives a reference to this layer. The recipient must not mutate the layer
617    /// during the scope of the callback, but may traverse the tree to find information about the
618    /// current transform or clip. The layer may not be attached anymore in this state, but even
619    /// if it is detached it may still have an also detached parent it can visit.
620    ///
621    /// If new callbacks are added or removed within the callback, the new callbacks will fire
622    /// (or stop firing) on the _next_ compositing event.
623    ///
624    /// Composition callbacks are useful in place of pushing a layer that would otherwise try to
625    /// observe the layer tree without actually affecting compositing. For example, a composition
626    /// callback may be used to observe the total transform and clip of the current container
627    /// layer to determine whether a render object drawn into it is visible or not.
628    ///
629    /// Calling the returned callback will remove `callback` from the composition callbacks.
630    pub fn add_composition_callback(
631        self,
632        app: &mut App,
633        callback: CompositionCallback,
634    ) -> Box<dyn FnOnce(&mut App)> {
635        self.update_subtree_composition_observer_count(app, 1);
636        let callback_id = NEXT_CALLBACK_ID.fetch_add(1, Ordering::Relaxed) + 1;
637        self.data_mut(app).callbacks.push((callback_id, callback));
638        Box::new(move |app: &mut App| {
639            // Dart's closure still finds a disposed layer; here dispose freed the entry.
640            if !app.contains(self.id) {
641                return;
642            }
643            let index = self
644                .data(app)
645                .callbacks
646                .iter()
647                .position(|(id, _)| *id == callback_id);
648            debug_assert!(self.debug_disposed(app) || index.is_some());
649            if let Some(index) = index {
650                self.data_mut(app).callbacks.remove(index);
651            }
652            self.update_subtree_composition_observer_count(app, -1);
653        })
654    }
655
656    /// If asserts are enabled, returns whether `dispose` has been called since the last time any
657    /// retained resources were created.
658    ///
659    /// A disposed layer's arena entry is gone, so a stale handle answers true as well.
660    pub fn debug_disposed(self, app: &App) -> bool {
661        !app.contains(self.id) || self.data(app).debug_disposed
662    }
663
664    /// Called by [`LayerHandle`].
665    fn unref(self, app: &mut App) {
666        let data = self.data_mut(app);
667        debug_assert!(!data.debug_mutations_locked);
668        debug_assert!(data.ref_count > 0);
669        data.ref_count -= 1;
670        if data.ref_count == 0 {
671            self.dispose(app);
672        }
673    }
674
675    /// Returns the number of objects holding a [`LayerHandle`] to this layer.
676    pub fn debug_handle_count(self, app: &App) -> u32 {
677        self.data(app).ref_count
678    }
679
680    /// See [`Layer::dispose`].
681    pub fn dispose(self, app: &mut App) {
682        (self.vtable.dispose)(app, self.id);
683    }
684
685    /// This layer's parent in the layer tree.
686    ///
687    /// The parent of the root node in the layer tree is `None`.
688    ///
689    /// Only subclasses of [`ContainerLayer`] can have children in the layer tree. All other
690    /// layer classes are used for leaves in the layer tree.
691    pub fn parent(self, app: &App) -> Option<AnyContainerLayer> {
692        self.data(app).parent
693    }
694
695    /// The owner for this layer (`None` if unattached).
696    ///
697    /// The entire layer tree that this layer belongs to will have the same owner.
698    ///
699    /// Typically the owner is a `RenderView`.
700    pub fn owner(self, app: &App) -> Option<HandleId> {
701        self.data(app).owner
702    }
703
704    /// Whether the layer tree containing this layer is attached to an owner.
705    ///
706    /// This becomes true during the call to `attach`.
707    ///
708    /// This becomes false during the call to `detach`.
709    pub fn attached(self, app: &App) -> bool {
710        self.data(app).owner.is_some()
711    }
712
713    /// See [`Layer::attach`].
714    pub fn attach(self, app: &mut App, owner: HandleId) {
715        (self.vtable.attach)(app, self.id, owner);
716    }
717
718    /// See [`Layer::detach`].
719    pub fn detach(self, app: &mut App) {
720        (self.vtable.detach)(app, self.id);
721    }
722
723    /// The depth of this layer in the layer tree.
724    ///
725    /// The depth of nodes in a tree monotonically increases as you traverse down the tree.
726    /// There's no guarantee regarding depth between siblings.
727    ///
728    /// The depth is used to ensure that nodes are processed in depth order.
729    pub fn depth(self, app: &App) -> i32 {
730        self.data(app).depth
731    }
732
733    /// See [`Layer::redepth_children`].
734    pub fn redepth_children(self, app: &mut App) {
735        (self.vtable.redepth_children)(app, self.id);
736    }
737
738    /// This layer's next sibling in the parent layer's child list.
739    pub fn next_sibling(self, app: &App) -> Option<AnyLayer> {
740        self.data(app).next_sibling
741    }
742
743    /// This layer's previous sibling in the parent layer's child list.
744    pub fn previous_sibling(self, app: &App) -> Option<AnyLayer> {
745        self.data(app).previous_sibling
746    }
747
748    /// Removes this layer from its parent layer's child list.
749    ///
750    /// This has no effect if the layer's parent is already `None`.
751    pub fn remove(self, app: &mut App) {
752        debug_assert!(!self.data(app).debug_mutations_locked);
753        if let Some(parent) = self.parent(app) {
754            parent.remove_child(app, self);
755        }
756    }
757
758    /// See [`Layer::find_annotations`].
759    pub fn find_annotations(
760        self,
761        app: &App,
762        result: &mut AnnotationSearch,
763        local_position: Offset,
764        only_first: bool,
765    ) -> bool {
766        (self.vtable.find_annotations)(app, self.id, result, local_position, only_first)
767    }
768
769    /// Search this layer and its subtree for the first annotation of type `S` under the point
770    /// described by `local_position`.
771    ///
772    /// Returns `None` if no matching annotations are found.
773    ///
774    /// By default this method calls [`find_annotations`](Self::find_annotations) with
775    /// `only_first: true` and returns the annotation of the first result. Prefer overriding
776    /// [`Layer::find_annotations`] instead of this method, because during an annotation search,
777    /// only `find_annotations` is recursively called, while custom behavior in this method is
778    /// ignored.
779    ///
780    /// See also:
781    ///
782    ///  * [`find_all_annotations`](Self::find_all_annotations), which is similar but returns all
783    ///    annotations found at the given position.
784    ///  * `AnnotatedRegionLayer`, for placing values in the layer tree.
785    pub fn find<S: 'static>(self, app: &App, local_position: Offset) -> Option<Rc<S>> {
786        let mut result = AnnotationSearch::new::<S>();
787        self.find_annotations(app, &mut result, local_position, true);
788        result
789            .into_result::<S>()
790            .entries
791            .into_iter()
792            .next()
793            .map(|entry| entry.annotation)
794    }
795
796    /// Search this layer and its subtree for all annotations of type `S` under the point
797    /// described by `local_position`.
798    ///
799    /// Returns a result with empty entries if no matching annotations are found.
800    ///
801    /// By default this method calls [`find_annotations`](Self::find_annotations) with
802    /// `only_first: false` and returns the annotations of its result. Prefer overriding
803    /// [`Layer::find_annotations`] instead of this method, because during an annotation search,
804    /// only `find_annotations` is recursively called, while custom behavior in this method is
805    /// ignored.
806    ///
807    /// See also:
808    ///
809    ///  * [`find`](Self::find), which is similar but returns the first annotation found at the
810    ///    given position.
811    ///  * `AnnotatedRegionLayer`, for placing values in the layer tree.
812    pub fn find_all_annotations<S: 'static>(
813        self,
814        app: &App,
815        local_position: Offset,
816    ) -> AnnotationResult<S> {
817        let mut result = AnnotationSearch::new::<S>();
818        self.find_annotations(app, &mut result, local_position, false);
819        result.into_result::<S>()
820    }
821
822    /// See [`Layer::add_to_scene`].
823    pub fn add_to_scene(self, app: &mut App, builder: &mut SceneBuilder) {
824        (self.vtable.add_to_scene)(app, self.id, builder);
825    }
826
827    /// Whether `add_to_scene` must run for this layer when a scene is next built: it changed
828    /// since it was last added, or never was, or a descendant did as far as
829    /// [`update_subtree_needs_add_to_scene`](Self::update_subtree_needs_add_to_scene) has
830    /// found out.
831    pub fn needs_add_to_scene(self, app: &App) -> bool {
832        self.data(app).needs_add_to_scene
833    }
834
835    /// Mark that this layer has changed and `add_to_scene` needs to be called.
836    pub fn mark_needs_add_to_scene(self, app: &mut App) {
837        debug_assert!(!self.data(app).debug_mutations_locked);
838        debug_assert!(
839            !self.always_needs_add_to_scene(app),
840            "a layer with always_needs_add_to_scene set called mark_needs_add_to_scene"
841        );
842        debug_assert!(!self.data(app).debug_disposed);
843        // Already marked. Short-circuit.
844        if self.data(app).needs_add_to_scene {
845            return;
846        }
847        self.data_mut(app).needs_add_to_scene = true;
848    }
849
850    /// See [`Layer::always_needs_add_to_scene`].
851    pub fn always_needs_add_to_scene(self, app: &App) -> bool {
852        (self.vtable.always_needs_add_to_scene)(app, self.id)
853    }
854
855    /// The engine layer used to render this layer: the list its subtree recorded when it was
856    /// last added to a scene, which [`SceneBuilder::add_retained`] embeds again while nothing
857    /// in the subtree changed.
858    pub fn engine_layer(self, app: &App) -> Option<EngineLayer> {
859        self.data(app).engine_layer.clone()
860    }
861
862    /// Sets the engine layer used to render this layer.
863    ///
864    /// Typically this is set to the value [`SceneBuilder::pop`] returned in `add_to_scene`.
865    pub fn set_engine_layer(self, app: &mut App, value: Option<EngineLayer>) {
866        debug_assert!(!self.data(app).debug_mutations_locked);
867        debug_assert!(!self.data(app).debug_disposed);
868        self.data_mut(app).engine_layer = value;
869        if !self.always_needs_add_to_scene(app) {
870            // The parent must record a new list to embed this one in, and so is marked as
871            // needing `add_to_scene`. When the whole tree is rendered the parent is adding
872            // itself already and clears the flag when it is done; when an interior layer is
873            // rendered on its own (an `OffsetLayer::to_image`) the mark waits for the frame
874            // that next renders the parent.
875            if let Some(parent) = self.parent(app)
876                && !parent.as_layer().always_needs_add_to_scene(app)
877            {
878                parent.as_layer().mark_needs_add_to_scene(app);
879            }
880        }
881    }
882
883    /// Traverses the layer subtree starting from this layer and determines whether it needs
884    /// `add_to_scene`.
885    ///
886    /// A layer needs `add_to_scene` if any of the following is true:
887    ///
888    /// - [`always_needs_add_to_scene`](Self::always_needs_add_to_scene) is true.
889    /// - [`mark_needs_add_to_scene`](Self::mark_needs_add_to_scene) has been called.
890    /// - Any of its descendants need `add_to_scene`.
891    ///
892    /// Dart's `ContainerLayer` override recurses into the children; here the erased handle
893    /// knows whether it is a container.
894    pub fn update_subtree_needs_add_to_scene(self, app: &mut App) {
895        debug_assert!(!self.data(app).debug_mutations_locked);
896        let always = self.always_needs_add_to_scene(app);
897        let data = self.data_mut(app);
898        data.needs_add_to_scene = data.needs_add_to_scene || always;
899        let Some(container) = self.as_container_layer() else {
900            return;
901        };
902        let mut child = container.first_child(app);
903        while let Some(layer) = child {
904            layer.update_subtree_needs_add_to_scene(app);
905            if layer.data(app).needs_add_to_scene {
906                self.data_mut(app).needs_add_to_scene = true;
907            }
908            child = layer.next_sibling(app);
909        }
910    }
911
912    /// Dart's `_addToSceneWithRetainedRendering`: the retained engine layer where the subtree
913    /// has not changed, `add_to_scene` otherwise.
914    pub fn add_to_scene_with_retained_rendering(self, app: &mut App, builder: &mut SceneBuilder) {
915        debug_assert!(!self.data(app).debug_mutations_locked);
916        // There can't be a loop by adding a retained layer subtree whose needs_add_to_scene is
917        // false: a retained layer appended to one of its own descendants changes that
918        // descendant's children, which sets the flag.
919        if !self.data(app).needs_add_to_scene
920            && let Some(engine_layer) = self.engine_layer(app)
921        {
922            builder.add_retained(&engine_layer);
923            return;
924        }
925        self.add_to_scene(app, builder);
926        // Clearing the flag after `add_to_scene`, not before: it calls the children's, which
927        // may mark this layer.
928        self.data_mut(app).needs_add_to_scene = false;
929    }
930}
931
932/// A layer handle of any concreteness — [`AnyLayer`], [`AnyContainerLayer`], [`AnyOffsetLayer`]
933/// or a typed `Handle<L>` — for what a [`LayerHandle`] can hold. Dart's `T extends Layer`.
934pub trait ErasedLayer: Copy + PartialEq + Debug + 'static {
935    /// Dart's implicit upcast to `Layer`.
936    fn as_layer(self) -> AnyLayer;
937}
938
939impl ErasedLayer for AnyLayer {
940    fn as_layer(self) -> AnyLayer {
941        self
942    }
943}
944
945/// Dart's implicit upcast of a concrete layer to `Layer`: the type-erased handle, through the
946/// table built from the type's `impl Layer`.
947impl<T: Layer> ErasedLayer for Handle<T> {
948    fn as_layer(self) -> AnyLayer {
949        AnyLayer {
950            id: self.id(),
951            vtable: const { &LayerVTable::of::<T>() },
952        }
953    }
954}
955
956/// A handle to prevent a [`Layer`]'s platform graphics resources from being disposed.
957///
958/// [`Layer`] objects retain native resources such as [`Picture`] objects. These objects may in
959/// turn retain large chunks of texture memory, either directly or indirectly.
960///
961/// The layer's native resources must be retained as long as there is some object that can add
962/// it to a scene. Typically, this is either its parent or an undisposed `RenderObject` that will
963/// append it to a [`ContainerLayer`]. Layers automatically hold a handle to their children, and
964/// `RenderObject`s automatically hold a handle to their `RenderObject.layer` as well as any
965/// [`PictureLayer`]s that they paint into using the `PaintingContext.canvas`. A layer
966/// automatically releases its resources once at least one handle has been acquired and all
967/// handles have been disposed. `RenderObject`s that create additional layer objects must
968/// manually manage the handles for that layer similarly to the implementation of
969/// `RenderObject.layer`.
970///
971/// If a `RenderObject` creates layers in addition to its `RenderObject.layer` and it intends to
972/// reuse those layers separately from `RenderObject.layer`, it must create a handle to that
973/// layer and dispose of it when the layer is no longer needed. For example, if it re-creates or
974/// nulls out an existing layer in `RenderObject.paint`, it should dispose of the handle to the
975/// old layer. It should also dispose of any layer handles it holds in `RenderObject.dispose`.
976///
977/// To dispose of a layer handle, set its layer to `None` with [`set_layer`](Self::set_layer).
978/// The handle lives inside an arena object, so the setter reaches it through the `App` rather
979/// than through `&mut self`; a handle dropped without clearing keeps its layer until the `App`
980/// goes, as a Dart handle that is never nulled would. See `PORTING.md`.
981pub struct LayerHandle<T> {
982    layer: Option<T>,
983}
984
985impl<T> LayerHandle<T> {
986    /// Create a new layer handle referencing no [`Layer`]. Dart's `LayerHandle([layer])` with
987    /// a layer is `new` then [`set_layer`](Self::set_layer).
988    pub const fn new() -> LayerHandle<T> {
989        LayerHandle { layer: None }
990    }
991}
992
993impl<T: ErasedLayer> LayerHandle<T> {
994    /// The [`Layer`] whose resources this object keeps alive.
995    pub fn layer(&self) -> Option<T> {
996        self.layer
997    }
998
999    /// Dart's `handle.layer = layer` for the handle `at` reaches inside `app`.
1000    ///
1001    /// Setting a new value or `None` will dispose the previously held layer if there are no
1002    /// other open handles to that layer.
1003    ///
1004    /// # Panics
1005    ///
1006    /// In debug builds, if `layer` is already disposed.
1007    pub fn set_layer(
1008        app: &mut App,
1009        at: impl Fn(&mut App) -> &mut LayerHandle<T>,
1010        layer: Option<T>,
1011    ) {
1012        debug_assert!(
1013            layer.is_none_or(|layer| !layer.as_layer().debug_disposed(app)),
1014            "Attempted to create a handle to an already disposed layer: {layer:?}."
1015        );
1016        let old = at(app).layer;
1017        if layer == old {
1018            return;
1019        }
1020        // The write comes before the unref, not after as in Dart: a layer's `parent_handle`
1021        // lives in the layer it holds, and the unref may destroy that entry.
1022        at(app).layer = layer;
1023        if let Some(layer) = layer {
1024            layer.as_layer().data_mut(app).ref_count += 1;
1025        }
1026        if let Some(old) = old {
1027            old.as_layer().unref(app);
1028        }
1029    }
1030}
1031
1032impl<T> Default for LayerHandle<T> {
1033    fn default() -> LayerHandle<T> {
1034        LayerHandle::new()
1035    }
1036}
1037
1038impl<T: Debug> Debug for LayerHandle<T> {
1039    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1040        match &self.layer {
1041            Some(layer) => write!(f, "LayerHandle({layer:?})"),
1042            None => write!(f, "LayerHandle(DISPOSED)"),
1043        }
1044    }
1045}
1046
1047/// A composited layer containing a [`Picture`].
1048///
1049/// Picture layers are always leaves in the layer tree. They are also responsible for disposing
1050/// of the [`Picture`] object they hold. This is typically done when their parent and all
1051/// `RenderObject`s that participated in painting the picture have been disposed.
1052pub struct PictureLayer {
1053    layer: LayerData,
1054    /// The bounds that were used for the canvas that drew this layer's picture.
1055    ///
1056    /// This is purely advisory. It can help debug why certain drawing commands are being culled.
1057    pub canvas_bounds: Rect,
1058    picture: Option<Arc<Picture>>,
1059    is_complex_hint: bool,
1060    will_change_hint: bool,
1061}
1062
1063impl PictureLayer {
1064    /// Creates a leaf layer for the layer tree.
1065    pub fn new(app: &mut App, canvas_bounds: Rect) -> Handle<PictureLayer> {
1066        app.create(PictureLayer {
1067            layer: LayerData::new(),
1068            canvas_bounds,
1069            picture: None,
1070            is_complex_hint: false,
1071            will_change_hint: false,
1072        })
1073    }
1074
1075    /// The picture recorded for this layer.
1076    ///
1077    /// The picture's coordinate system matches this layer's coordinate system.
1078    pub fn picture(self: Handle<Self>, app: &App) -> Option<&Arc<Picture>> {
1079        app.get(self).picture.as_ref()
1080    }
1081
1082    /// See [`picture`](Self::picture). Dart's `_picture?.dispose()` is the drop of the old one.
1083    pub fn set_picture(self: Handle<Self>, app: &mut App, picture: Option<Arc<Picture>>) {
1084        debug_assert!(!app.get(self).layer.debug_disposed);
1085        self.as_layer().mark_needs_add_to_scene(app);
1086        app.get_mut(self).picture = picture;
1087    }
1088
1089    /// Hints that the painting in this layer is complex and would benefit from caching.
1090    ///
1091    /// If this hint is not set, the compositor will apply its own heuristics to decide whether
1092    /// the this layer is complex enough to benefit from caching.
1093    pub fn is_complex_hint(self: Handle<Self>, app: &App) -> bool {
1094        app.get(self).is_complex_hint
1095    }
1096
1097    /// See [`is_complex_hint`](Self::is_complex_hint).
1098    pub fn set_is_complex_hint(self: Handle<Self>, app: &mut App, value: bool) {
1099        if value != app.get(self).is_complex_hint {
1100            app.get_mut(self).is_complex_hint = value;
1101            self.as_layer().mark_needs_add_to_scene(app);
1102        }
1103    }
1104
1105    /// Hints that the painting in this layer is likely to change next frame.
1106    ///
1107    /// This hint tells the compositor not to cache this layer because the cache will not be used
1108    /// in the future. If this hint is not set, the compositor will apply its own heuristics to
1109    /// decide whether this layer is likely to be reused in the future.
1110    pub fn will_change_hint(self: Handle<Self>, app: &App) -> bool {
1111        app.get(self).will_change_hint
1112    }
1113
1114    /// See [`will_change_hint`](Self::will_change_hint).
1115    pub fn set_will_change_hint(self: Handle<Self>, app: &mut App, value: bool) {
1116        if value != app.get(self).will_change_hint {
1117            app.get_mut(self).will_change_hint = value;
1118            self.as_layer().mark_needs_add_to_scene(app);
1119        }
1120    }
1121}
1122
1123impl Layer for PictureLayer {
1124    crate::layer_accessors!();
1125
1126    fn dispose(self: Handle<Self>, app: &mut App) {
1127        self.set_picture(app, None); // Will dispose _picture.
1128        LayerBase::dispose(self, app);
1129    }
1130
1131    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
1132        let this = app.get(self);
1133        let picture = this
1134            .picture
1135            .as_ref()
1136            .expect("a PictureLayer has a picture when it is added to the scene");
1137        builder.add_picture(
1138            Offset::ZERO,
1139            picture,
1140            this.is_complex_hint,
1141            this.will_change_hint,
1142        );
1143    }
1144
1145    fn find_annotations(
1146        self: Handle<Self>,
1147        _app: &App,
1148        _result: &mut AnnotationSearch,
1149        _local_position: Offset,
1150        _only_first: bool,
1151    ) -> bool {
1152        false
1153    }
1154}
1155
1156/// A layer that places a native surface the host composites: Flutter's `PlatformViewLayer`.
1157///
1158/// A leaf, like a picture layer. It is added to the scene on every frame: a scene's list of
1159/// surfaces is built afresh each time, and a retained display list carries no surface.
1160pub struct SurfaceLayer {
1161    layer: LayerData,
1162    surface: Arc<dyn Surface>,
1163    /// Where the surface goes, in this layer's coordinates.
1164    rect: Rect,
1165}
1166
1167impl SurfaceLayer {
1168    /// A layer placing `surface` at `rect`.
1169    pub fn new(app: &mut App, surface: Arc<dyn Surface>, rect: Rect) -> Handle<SurfaceLayer> {
1170        app.create(SurfaceLayer {
1171            layer: LayerData::new(),
1172            surface,
1173            rect,
1174        })
1175    }
1176
1177    pub fn surface(self: Handle<Self>, app: &App) -> &Arc<dyn Surface> {
1178        &app.get(self).surface
1179    }
1180
1181    pub fn rect(self: Handle<Self>, app: &App) -> Rect {
1182        app.get(self).rect
1183    }
1184}
1185
1186impl Layer for SurfaceLayer {
1187    crate::layer_accessors!();
1188
1189    fn always_needs_add_to_scene(self: Handle<Self>, _app: &App) -> bool {
1190        true
1191    }
1192
1193    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
1194        let this = app.get(self);
1195        builder.add_surface(Arc::clone(&this.surface), this.rect);
1196    }
1197
1198    fn find_annotations(
1199        self: Handle<Self>,
1200        _app: &App,
1201        _result: &mut AnnotationSearch,
1202        _local_position: Offset,
1203        _only_first: bool,
1204    ) -> bool {
1205        false
1206    }
1207}
1208
1209/// Flutter's `ContainerLayer` fields, held under the field `container_layer`
1210/// ([`container_layer_accessors!`]).
1211#[derive(Debug, Default)]
1212pub struct ContainerLayerData {
1213    first_child: Option<AnyLayer>,
1214    last_child: Option<AnyLayer>,
1215}
1216
1217impl ContainerLayerData {
1218    /// No children.
1219    pub const fn new() -> ContainerLayerData {
1220        ContainerLayerData {
1221            first_child: None,
1222            last_child: None,
1223        }
1224    }
1225}
1226
1227/// Implements the [`ContainerLayer`] field accessors for a `container_layer` field.
1228///
1229/// `container_layer_accessors!(offset)` also records that the type `extends OffsetLayer`, so
1230/// its [`AnyContainerLayer`] can be narrowed with [`AnyContainerLayer::as_offset_layer`].
1231#[macro_export]
1232macro_rules! container_layer_accessors {
1233    () => {
1234        fn container_layer_data(
1235            self: ::inset_foundation::Handle<Self>,
1236            app: &::inset_foundation::App,
1237        ) -> &$crate::ContainerLayerData {
1238            &app.get(self).container_layer
1239        }
1240        fn container_layer_data_mut(
1241            self: ::inset_foundation::Handle<Self>,
1242            app: &mut ::inset_foundation::App,
1243        ) -> &mut $crate::ContainerLayerData {
1244            &mut app.get_mut(self).container_layer
1245        }
1246    };
1247    (offset) => {
1248        $crate::container_layer_accessors!();
1249        const AS_OFFSET: Option<fn() -> &'static $crate::OffsetLayerVTable> =
1250            Some(|| const { &$crate::OffsetLayerVTable::of::<Self>() });
1251    };
1252}
1253
1254/// A composited layer that has a list of children.
1255///
1256/// A [`ContainerLayer`] instance merely takes a list of children and inserts them into the
1257/// composited rendering in order. There are subclasses of [`ContainerLayer`] which apply more
1258/// elaborate effects in the process.
1259///
1260/// Flutter's `ContainerLayer`: the child list lives on [`AnyContainerLayer`]; this trait holds
1261/// the virtual `apply_transform` and the bodies of the `Layer` methods it overrides. A leaf's
1262/// `impl Layer` forwards to them: `fn attach(..) { ContainerLayer::attach(self, app, owner) }`.
1263pub trait ContainerLayer: Layer {
1264    /// Mixin field access.
1265    fn container_layer_data(self: Handle<Self>, app: &App) -> &ContainerLayerData;
1266
1267    /// See [`container_layer_data`](Self::container_layer_data).
1268    fn container_layer_data_mut(self: Handle<Self>, app: &mut App) -> &mut ContainerLayerData;
1269
1270    /// The offset table when this type `extends OffsetLayer`;
1271    /// `container_layer_accessors!(offset)` sets it. Dart's `layer is OffsetLayer`.
1272    const AS_OFFSET: Option<fn() -> &'static OffsetLayerVTable> = None;
1273
1274    /// Dart's implicit upcast of a concrete layer to `ContainerLayer`.
1275    fn as_container_layer(self: Handle<Self>) -> AnyContainerLayer {
1276        AnyContainerLayer {
1277            id: self.id(),
1278            vtable: const { &ContainerLayerVTable::of::<Self>() },
1279        }
1280    }
1281
1282    /// Applies the transform that would be applied when compositing the given child to the
1283    /// given matrix.
1284    ///
1285    /// Specifically, this should apply the transform that is applied to child's _origin_. When
1286    /// using `apply_transform` with a chain of layers, results will be unreliable unless the
1287    /// deepest layer in the chain collapses the `layerOffset` in `add_to_scene` to zero, meaning
1288    /// that it passes [`Offset::ZERO`] to its children, and bakes any incoming `layerOffset` into
1289    /// the [`SceneBuilder`] as (for instance) a transform (which is then also included in the
1290    /// transformation applied by `apply_transform`).
1291    ///
1292    /// This method is only valid immediately after `add_to_scene` has been called, before any of
1293    /// the properties have been changed.
1294    ///
1295    /// The default implementation does nothing, since [`ContainerLayer`], by default, composites
1296    /// its children at the origin of the [`ContainerLayer`] itself.
1297    ///
1298    /// The `child` argument should generally not be `None`, since in principle a layer could
1299    /// transform each child independently. However, certain layers may explicitly allow `None`
1300    /// as a value, for example if they know that they transform all their children identically.
1301    ///
1302    /// Used by `FollowerLayer` to transform its child to a `LeaderLayer`'s position.
1303    fn apply_transform(
1304        self: Handle<Self>,
1305        app: &App,
1306        child: Option<AnyLayer>,
1307        transform: &mut Matrix4,
1308    ) {
1309        let _ = (self, app, transform);
1310        debug_assert!(child.is_some());
1311    }
1312
1313    /// `ContainerLayer._fireCompositionCallbacks`.
1314    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
1315        LayerBase::fire_composition_callbacks(self, app, include_children);
1316        if !include_children {
1317            return;
1318        }
1319        let mut child = self.as_container_layer().first_child(app);
1320        while let Some(layer) = child {
1321            layer.fire_composition_callbacks(app, include_children);
1322            child = layer.next_sibling(app);
1323        }
1324    }
1325
1326    /// `ContainerLayer.supportsRasterization`.
1327    fn supports_rasterization(self: Handle<Self>, app: &App) -> bool {
1328        let mut child = self.as_container_layer().last_child(app);
1329        while let Some(layer) = child {
1330            if !layer.supports_rasterization(app) {
1331                return false;
1332            }
1333            child = layer.previous_sibling(app);
1334        }
1335        true
1336    }
1337
1338    /// `ContainerLayer.dispose`.
1339    fn dispose(self: Handle<Self>, app: &mut App) {
1340        self.as_container_layer().remove_all_children(app);
1341        self.layer_data_mut(app).callbacks.clear();
1342        LayerBase::dispose(self, app);
1343    }
1344
1345    /// `ContainerLayer.findAnnotations`.
1346    fn find_annotations(
1347        self: Handle<Self>,
1348        app: &App,
1349        result: &mut AnnotationSearch,
1350        local_position: Offset,
1351        only_first: bool,
1352    ) -> bool {
1353        let mut child = self.as_container_layer().last_child(app);
1354        while let Some(layer) = child {
1355            let is_absorbed = layer.find_annotations(app, result, local_position, only_first);
1356            if is_absorbed {
1357                return true;
1358            }
1359            if only_first && !result.is_empty() {
1360                return is_absorbed;
1361            }
1362            child = layer.previous_sibling(app);
1363        }
1364        false
1365    }
1366
1367    /// `ContainerLayer.attach`.
1368    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
1369        debug_assert!(!self.layer_data(app).debug_mutations_locked);
1370        LayerBase::attach(self, app, owner);
1371        let mut child = self.as_container_layer().first_child(app);
1372        while let Some(layer) = child {
1373            layer.attach(app, owner);
1374            child = layer.next_sibling(app);
1375        }
1376    }
1377
1378    /// `ContainerLayer.detach`.
1379    fn detach(self: Handle<Self>, app: &mut App) {
1380        debug_assert!(!self.layer_data(app).debug_mutations_locked);
1381        LayerBase::detach(self, app);
1382        let mut child = self.as_container_layer().first_child(app);
1383        while let Some(layer) = child {
1384            layer.detach(app);
1385            child = layer.next_sibling(app);
1386        }
1387        // Detach indicates that we may never be composited again. Clients
1388        // interested in observing composition need to get an update here because
1389        // they might otherwise never get another one even though the layer is no
1390        // longer visible.
1391        //
1392        // Children fired them already in child.detach().
1393        self.as_layer().fire_composition_callbacks(app, false);
1394    }
1395
1396    /// `ContainerLayer.redepthChildren`.
1397    fn redepth_children(self: Handle<Self>, app: &mut App) {
1398        let this = self.as_container_layer();
1399        let mut child = this.first_child(app);
1400        while let Some(layer) = child {
1401            this.redepth_child(app, layer);
1402            child = layer.next_sibling(app);
1403        }
1404    }
1405
1406    /// `ContainerLayer.addToScene`.
1407    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
1408        self.as_container_layer()
1409            .add_children_to_scene(app, builder);
1410    }
1411}
1412
1413/// The vtable of an [`AnyContainerLayer`]: the layer vtable plus the container accessors.
1414///
1415/// Public only so [`layer_accessors!`] can name it from another crate.
1416#[doc(hidden)]
1417pub struct ContainerLayerVTable {
1418    layer: LayerVTable,
1419    container_data: fn(&App, HandleId) -> &ContainerLayerData,
1420    container_data_mut: fn(&mut App, HandleId) -> &mut ContainerLayerData,
1421    apply_transform: fn(&App, HandleId, Option<AnyLayer>, &mut Matrix4),
1422    as_offset: Option<fn() -> &'static OffsetLayerVTable>,
1423}
1424
1425impl ContainerLayerVTable {
1426    pub const fn of<T: ContainerLayer>() -> ContainerLayerVTable {
1427        ContainerLayerVTable {
1428            layer: LayerVTable::of::<T>(),
1429            container_data: |app, id| T::container_layer_data(resolve(id), app),
1430            container_data_mut: |app, id| T::container_layer_data_mut(resolve(id), app),
1431            apply_transform: |app, id, child, transform| {
1432                T::apply_transform(resolve(id), app, child, transform)
1433            },
1434            as_offset: T::AS_OFFSET,
1435        }
1436    }
1437}
1438
1439/// Erased `ContainerLayer`.
1440#[derive(Clone, Copy)]
1441pub struct AnyContainerLayer {
1442    id: HandleId,
1443    vtable: &'static ContainerLayerVTable,
1444}
1445
1446impl PartialEq for AnyContainerLayer {
1447    fn eq(&self, other: &AnyContainerLayer) -> bool {
1448        self.id == other.id
1449    }
1450}
1451
1452impl Eq for AnyContainerLayer {}
1453
1454impl Hash for AnyContainerLayer {
1455    fn hash<H: Hasher>(&self, state: &mut H) {
1456        self.id.hash(state);
1457    }
1458}
1459
1460impl From<AnyContainerLayer> for HandleId {
1461    fn from(layer: AnyContainerLayer) -> HandleId {
1462        layer.id
1463    }
1464}
1465
1466impl Debug for AnyContainerLayer {
1467    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1468        write!(f, "AnyContainerLayer({:?})", self.id)
1469    }
1470}
1471
1472impl ErasedLayer for AnyContainerLayer {
1473    fn as_layer(self) -> AnyLayer {
1474        AnyLayer {
1475            id: self.id,
1476            vtable: &self.vtable.layer,
1477        }
1478    }
1479}
1480
1481impl AnyContainerLayer {
1482    fn from_vtable(id: HandleId, vtable: &'static ContainerLayerVTable) -> AnyContainerLayer {
1483        AnyContainerLayer { id, vtable }
1484    }
1485
1486    pub fn id(self) -> HandleId {
1487        self.id
1488    }
1489
1490    /// Dart's `layer as OffsetLayer`, as an `Option`.
1491    pub fn as_offset_layer(self) -> Option<AnyOffsetLayer> {
1492        self.vtable
1493            .as_offset
1494            .map(|vtable| AnyOffsetLayer::from_vtable(self.id, vtable()))
1495    }
1496
1497    fn data(self, app: &App) -> &ContainerLayerData {
1498        (self.vtable.container_data)(app, self.id)
1499    }
1500
1501    fn data_mut(self, app: &mut App) -> &mut ContainerLayerData {
1502        (self.vtable.container_data_mut)(app, self.id)
1503    }
1504
1505    /// The first composited layer in this layer's child list.
1506    pub fn first_child(self, app: &App) -> Option<AnyLayer> {
1507        self.data(app).first_child
1508    }
1509
1510    /// The last composited layer in this layer's child list.
1511    pub fn last_child(self, app: &App) -> Option<AnyLayer> {
1512        self.data(app).last_child
1513    }
1514
1515    /// Returns whether this layer has at least one child layer.
1516    pub fn has_children(self, app: &App) -> bool {
1517        self.data(app).first_child.is_some()
1518    }
1519
1520    /// Consider this layer as the root and build a scene (a tree of layers) in the engine.
1521    // The reason this method is in the `ContainerLayer` class rather than
1522    // `PipelineOwner` or other singleton level is because this method can be used
1523    // both to render the whole layer tree (e.g. a normal application frame) and
1524    // to render a subtree (e.g. `OffsetLayer.toImage`).
1525    pub fn build_scene(self, app: &mut App, mut builder: SceneBuilder) -> Scene {
1526        let this = self.as_layer();
1527        this.update_subtree_needs_add_to_scene(app);
1528        this.add_to_scene(app, &mut builder);
1529        if this.subtree_has_composition_callbacks(app) {
1530            this.fire_composition_callbacks(app, true);
1531        }
1532        // Clearing the flag after `add_to_scene`, not before: it calls the children's, which
1533        // may mark this layer.
1534        this.data_mut(app).needs_add_to_scene = false;
1535        builder.build()
1536    }
1537
1538    fn debug_ultimate_previous_sibling_of(
1539        self,
1540        app: &App,
1541        mut child: AnyLayer,
1542        equals: Option<AnyLayer>,
1543    ) -> bool {
1544        let attached = self.as_layer().attached(app);
1545        debug_assert!(child.attached(app) == attached);
1546        while let Some(previous) = child.previous_sibling(app) {
1547            debug_assert!(previous != child);
1548            child = previous;
1549            debug_assert!(child.attached(app) == attached);
1550        }
1551        Some(child) == equals
1552    }
1553
1554    fn debug_ultimate_next_sibling_of(
1555        self,
1556        app: &App,
1557        mut child: AnyLayer,
1558        equals: Option<AnyLayer>,
1559    ) -> bool {
1560        let attached = self.as_layer().attached(app);
1561        debug_assert!(child.attached(app) == attached);
1562        while let Some(next) = child.next_sibling(app) {
1563            debug_assert!(next != child);
1564            child = next;
1565            debug_assert!(child.attached(app) == attached);
1566        }
1567        Some(child) == equals
1568    }
1569
1570    /// Adds the given layer to the end of this layer's child list.
1571    pub fn append(self, app: &mut App, child: AnyLayer) {
1572        let this = self.as_layer();
1573        debug_assert!(!this.data(app).debug_mutations_locked);
1574        debug_assert!(child != this);
1575        debug_assert!(Some(child) != self.first_child(app));
1576        debug_assert!(Some(child) != self.last_child(app));
1577        debug_assert!(child.parent(app).is_none());
1578        debug_assert!(!child.attached(app));
1579        debug_assert!(child.next_sibling(app).is_none());
1580        debug_assert!(child.previous_sibling(app).is_none());
1581        debug_assert!(child.data(app).parent_handle.layer().is_none());
1582        debug_assert!(self.debug_root(app) != child); // indicates we are about to create a cycle
1583        self.adopt_child(app, child);
1584        let last_child = self.last_child(app);
1585        child.data_mut(app).previous_sibling = last_child;
1586        if let Some(last_child) = last_child {
1587            last_child.data_mut(app).next_sibling = Some(child);
1588        }
1589        let data = self.data_mut(app);
1590        data.last_child = Some(child);
1591        data.first_child.get_or_insert(child);
1592        LayerHandle::set_layer(
1593            app,
1594            |app| &mut child.data_mut(app).parent_handle,
1595            Some(child),
1596        );
1597        debug_assert!(child.attached(app) == this.attached(app));
1598    }
1599
1600    /// The `assert(() { Layer node = this; while (node.parent != null) … }())` walk of `append`
1601    /// and `_adoptChild`: the root above this layer.
1602    fn debug_root(self, app: &App) -> AnyLayer {
1603        let mut node = self.as_layer();
1604        while let Some(parent) = node.parent(app) {
1605            node = parent.as_layer();
1606        }
1607        node
1608    }
1609
1610    fn adopt_child(self, app: &mut App, child: AnyLayer) {
1611        let this = self.as_layer();
1612        debug_assert!(!this.data(app).debug_mutations_locked);
1613        if !this.always_needs_add_to_scene(app) {
1614            this.mark_needs_add_to_scene(app);
1615        }
1616        let callback_count = child.data(app).composition_callback_count;
1617        if callback_count != 0 {
1618            this.update_subtree_composition_observer_count(app, callback_count);
1619        }
1620        debug_assert!(child.data(app).parent.is_none());
1621        debug_assert!(self.debug_root(app) != child); // indicates we are about to create a cycle
1622        child.data_mut(app).parent = Some(self);
1623        if let Some(owner) = this.owner(app) {
1624            child.attach(app, owner);
1625        }
1626        self.redepth_child(app, child);
1627    }
1628
1629    /// Adjust the depth of the given `child` to be greater than this node's own depth.
1630    ///
1631    /// Only call this method from overrides of [`Layer::redepth_children`].
1632    pub fn redepth_child(self, app: &mut App, child: AnyLayer) {
1633        let this = self.as_layer();
1634        debug_assert!(child.owner(app) == this.owner(app));
1635        let depth = this.depth(app);
1636        if child.depth(app) <= depth {
1637            child.data_mut(app).depth = depth + 1;
1638            child.redepth_children(app);
1639        }
1640    }
1641
1642    // Implementation of [Layer.remove].
1643    pub(crate) fn remove_child(self, app: &mut App, child: AnyLayer) {
1644        let this = self.as_layer();
1645        debug_assert!(child.parent(app) == Some(self));
1646        debug_assert!(child.attached(app) == this.attached(app));
1647        debug_assert!(self.debug_ultimate_previous_sibling_of(app, child, self.first_child(app)));
1648        debug_assert!(self.debug_ultimate_next_sibling_of(app, child, self.last_child(app)));
1649        debug_assert!(child.data(app).parent_handle.layer().is_some());
1650        let previous_sibling = child.previous_sibling(app);
1651        let next_sibling = child.next_sibling(app);
1652        match previous_sibling {
1653            None => {
1654                debug_assert!(self.first_child(app) == Some(child));
1655                self.data_mut(app).first_child = next_sibling;
1656            }
1657            Some(previous) => previous.data_mut(app).next_sibling = next_sibling,
1658        }
1659        match next_sibling {
1660            None => {
1661                debug_assert!(self.last_child(app) == Some(child));
1662                self.data_mut(app).last_child = previous_sibling;
1663            }
1664            Some(next) => next.data_mut(app).previous_sibling = previous_sibling,
1665        }
1666        self.debug_check_child_list(app);
1667        let data = child.data_mut(app);
1668        data.previous_sibling = None;
1669        data.next_sibling = None;
1670        self.drop_child(app, child);
1671        LayerHandle::set_layer(app, |app| &mut child.data_mut(app).parent_handle, None);
1672        // The release may have disposed the child; a disposed layer is detached.
1673        debug_assert!(child.debug_disposed(app) || !child.attached(app));
1674    }
1675
1676    /// The asserts of `_removeChild` after the unlink: the list is consistent end to end.
1677    fn debug_check_child_list(self, app: &App) {
1678        let attached = self.as_layer().attached(app);
1679        let first_child = self.first_child(app);
1680        let last_child = self.last_child(app);
1681        debug_assert!(first_child.is_none() == last_child.is_none());
1682        debug_assert!(first_child.is_none_or(|first| first.attached(app) == attached));
1683        debug_assert!(last_child.is_none_or(|last| last.attached(app) == attached));
1684        debug_assert!(
1685            first_child
1686                .is_none_or(|first| self.debug_ultimate_next_sibling_of(app, first, last_child))
1687        );
1688        debug_assert!(
1689            last_child.is_none_or(|last| self.debug_ultimate_previous_sibling_of(
1690                app,
1691                last,
1692                first_child
1693            ))
1694        );
1695    }
1696
1697    fn drop_child(self, app: &mut App, child: AnyLayer) {
1698        let this = self.as_layer();
1699        debug_assert!(!this.data(app).debug_mutations_locked);
1700        if !this.always_needs_add_to_scene(app) {
1701            this.mark_needs_add_to_scene(app);
1702        }
1703        let callback_count = child.data(app).composition_callback_count;
1704        if callback_count != 0 {
1705            this.update_subtree_composition_observer_count(app, -callback_count);
1706        }
1707        debug_assert!(child.data(app).parent == Some(self));
1708        debug_assert!(child.attached(app) == this.attached(app));
1709        child.data_mut(app).parent = None;
1710        if this.attached(app) {
1711            child.detach(app);
1712        }
1713    }
1714
1715    /// Removes all of this layer's children from its child list.
1716    pub fn remove_all_children(self, app: &mut App) {
1717        let this = self.as_layer();
1718        debug_assert!(!this.data(app).debug_mutations_locked);
1719        let mut child = self.first_child(app);
1720        while let Some(layer) = child {
1721            let next = layer.next_sibling(app);
1722            let data = layer.data_mut(app);
1723            data.previous_sibling = None;
1724            data.next_sibling = None;
1725            debug_assert!(layer.attached(app) == this.attached(app));
1726            self.drop_child(app, layer);
1727            LayerHandle::set_layer(app, |app| &mut layer.data_mut(app).parent_handle, None);
1728            child = next;
1729        }
1730        let data = self.data_mut(app);
1731        data.first_child = None;
1732        data.last_child = None;
1733    }
1734
1735    /// Uploads all of this layer's children to the engine.
1736    ///
1737    /// This method is typically used by `add_to_scene` to insert the children into the scene.
1738    /// Subclasses of [`ContainerLayer`] typically override `add_to_scene` to apply effects to
1739    /// the scene using the [`SceneBuilder`] API, then insert their children using
1740    /// `add_children_to_scene`, then reverse the aforementioned effects before returning from
1741    /// `add_to_scene`.
1742    pub fn add_children_to_scene(self, app: &mut App, builder: &mut SceneBuilder) {
1743        let mut child = self.first_child(app);
1744        while let Some(layer) = child {
1745            layer.add_to_scene_with_retained_rendering(app, builder);
1746            child = layer.next_sibling(app);
1747        }
1748    }
1749
1750    /// See [`ContainerLayer::apply_transform`].
1751    pub fn apply_transform(self, app: &App, child: Option<AnyLayer>, transform: &mut Matrix4) {
1752        (self.vtable.apply_transform)(app, self.id, child, transform);
1753    }
1754
1755    /// Returns the descendants of this layer in depth first order.
1756    pub fn depth_first_iterate_children(self, app: &App) -> Vec<AnyLayer> {
1757        let mut children = Vec::new();
1758        let mut child = self.first_child(app);
1759        while let Some(layer) = child {
1760            children.push(layer);
1761            if let Some(container) = layer.as_container_layer() {
1762                children.extend(container.depth_first_iterate_children(app));
1763            }
1764            child = layer.next_sibling(app);
1765        }
1766        children
1767    }
1768}
1769
1770/// Flutter's `OffsetLayer` fields, held under the field `offset_layer`
1771/// ([`offset_layer_accessors!`]).
1772#[derive(Debug)]
1773pub struct OffsetLayerData {
1774    offset: Offset,
1775}
1776
1777impl OffsetLayerData {
1778    /// Flutter's `OffsetLayer({offset})`.
1779    pub const fn new(offset: Offset) -> OffsetLayerData {
1780        OffsetLayerData { offset }
1781    }
1782}
1783
1784impl Default for OffsetLayerData {
1785    /// Flutter's `OffsetLayer()`: `offset` is zero.
1786    fn default() -> OffsetLayerData {
1787        OffsetLayerData::new(Offset::ZERO)
1788    }
1789}
1790
1791/// Implements the [`OffsetLayerMixin`] field accessors for an `offset_layer` field.
1792#[macro_export]
1793macro_rules! offset_layer_accessors {
1794    () => {
1795        fn offset_layer_data(
1796            self: ::inset_foundation::Handle<Self>,
1797            app: &::inset_foundation::App,
1798        ) -> &$crate::OffsetLayerData {
1799            &app.get(self).offset_layer
1800        }
1801        fn offset_layer_data_mut(
1802            self: ::inset_foundation::Handle<Self>,
1803            app: &mut ::inset_foundation::App,
1804        ) -> &mut $crate::OffsetLayerData {
1805            &mut app.get_mut(self).offset_layer
1806        }
1807    };
1808}
1809
1810/// A layer that is displayed at an offset from its parent layer.
1811///
1812/// Offset layers are key to efficient repainting because they are created by repaint boundaries
1813/// in the `RenderObject` tree (see `RenderObject.isRepaintBoundary`). When a render object that
1814/// is a repaint boundary is asked to paint at given offset in a `PaintingContext`, the render
1815/// object first checks whether it needs to repaint itself. If not, it reuses its existing
1816/// [`OffsetLayer`] (and its entire subtree) by mutating its offset property, cutting off the
1817/// paint walk.
1818///
1819/// Flutter's `OffsetLayer` is a concrete class that `TransformLayer`, `OpacityLayer` and
1820/// `ImageFilterLayer` extend: the bodies are here, [`OffsetLayer`] is the concrete leaf.
1821pub trait OffsetLayerMixin: ContainerLayer {
1822    /// Mixin field access.
1823    fn offset_layer_data(self: Handle<Self>, app: &App) -> &OffsetLayerData;
1824
1825    /// See [`offset_layer_data`](Self::offset_layer_data).
1826    fn offset_layer_data_mut(self: Handle<Self>, app: &mut App) -> &mut OffsetLayerData;
1827
1828    /// Dart's implicit upcast of a concrete layer to `OffsetLayer`.
1829    fn as_offset_layer(self: Handle<Self>) -> AnyOffsetLayer {
1830        AnyOffsetLayer {
1831            id: self.id(),
1832            vtable: const { &OffsetLayerVTable::of::<Self>() },
1833        }
1834    }
1835
1836    /// Offset from parent in the parent's coordinate system.
1837    fn offset(self: Handle<Self>, app: &App) -> Offset {
1838        self.offset_layer_data(app).offset
1839    }
1840
1841    /// See [`offset`](Self::offset).
1842    fn set_offset(self: Handle<Self>, app: &mut App, value: Offset) {
1843        self.offset_layer_data_mut(app).offset = value;
1844    }
1845
1846    /// `OffsetLayer.findAnnotations`.
1847    fn find_annotations(
1848        self: Handle<Self>,
1849        app: &App,
1850        result: &mut AnnotationSearch,
1851        local_position: Offset,
1852        only_first: bool,
1853    ) -> bool {
1854        let offset = self.offset(app);
1855        ContainerLayer::find_annotations(self, app, result, local_position - offset, only_first)
1856    }
1857
1858    /// `OffsetLayer.applyTransform`.
1859    fn apply_transform(
1860        self: Handle<Self>,
1861        app: &App,
1862        child: Option<AnyLayer>,
1863        transform: &mut Matrix4,
1864    ) {
1865        debug_assert!(child.is_some());
1866        let offset = self.offset(app);
1867        *transform = transform.then(&Matrix4::translation(
1868            offset.dx() as f32,
1869            offset.dy() as f32,
1870        ));
1871    }
1872
1873    /// `OffsetLayer.addToScene`.
1874    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
1875        // Skia has a fast path for concatenating scale/translation only matrices.
1876        // Hence pushing a translation-only transform layer should be fast. For
1877        // retained rendering, we don't want to push the offset down to each leaf
1878        // node. Otherwise, changing an offset layer on the very high level could
1879        // cascade the change to too many leaves.
1880        let offset = self.offset(app);
1881        builder.push_offset(offset.dx(), offset.dy());
1882        self.as_container_layer()
1883            .add_children_to_scene(app, builder);
1884        let engine_layer = builder.pop();
1885        self.as_layer().set_engine_layer(app, Some(engine_layer));
1886    }
1887}
1888
1889/// The vtable of an [`AnyOffsetLayer`]: the container vtable plus the offset accessors.
1890///
1891/// Public only so [`container_layer_accessors!`] can name it from another crate.
1892#[doc(hidden)]
1893pub struct OffsetLayerVTable {
1894    container: ContainerLayerVTable,
1895    offset_data: fn(&App, HandleId) -> &OffsetLayerData,
1896    offset_data_mut: fn(&mut App, HandleId) -> &mut OffsetLayerData,
1897}
1898
1899impl OffsetLayerVTable {
1900    pub const fn of<T: OffsetLayerMixin>() -> OffsetLayerVTable {
1901        OffsetLayerVTable {
1902            container: ContainerLayerVTable::of::<T>(),
1903            offset_data: |app, id| T::offset_layer_data(resolve(id), app),
1904            offset_data_mut: |app, id| T::offset_layer_data_mut(resolve(id), app),
1905        }
1906    }
1907}
1908
1909/// Erased `OffsetLayer`: what `RenderObject.updateCompositedLayer` returns and
1910/// `PaintingContext` positions.
1911#[derive(Clone, Copy)]
1912pub struct AnyOffsetLayer {
1913    id: HandleId,
1914    vtable: &'static OffsetLayerVTable,
1915}
1916
1917impl PartialEq for AnyOffsetLayer {
1918    fn eq(&self, other: &AnyOffsetLayer) -> bool {
1919        self.id == other.id
1920    }
1921}
1922
1923impl Eq for AnyOffsetLayer {}
1924
1925impl Hash for AnyOffsetLayer {
1926    fn hash<H: Hasher>(&self, state: &mut H) {
1927        self.id.hash(state);
1928    }
1929}
1930
1931impl From<AnyOffsetLayer> for HandleId {
1932    fn from(layer: AnyOffsetLayer) -> HandleId {
1933        layer.id
1934    }
1935}
1936
1937impl Debug for AnyOffsetLayer {
1938    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1939        write!(f, "AnyOffsetLayer({:?})", self.id)
1940    }
1941}
1942
1943impl ErasedLayer for AnyOffsetLayer {
1944    fn as_layer(self) -> AnyLayer {
1945        self.as_container_layer().as_layer()
1946    }
1947}
1948
1949impl AnyOffsetLayer {
1950    fn from_vtable(id: HandleId, vtable: &'static OffsetLayerVTable) -> AnyOffsetLayer {
1951        AnyOffsetLayer { id, vtable }
1952    }
1953
1954    pub fn id(self) -> HandleId {
1955        self.id
1956    }
1957
1958    /// The `ContainerLayer` view of this layer. Free: points into the nested table.
1959    pub fn as_container_layer(self) -> AnyContainerLayer {
1960        AnyContainerLayer::from_vtable(self.id, &self.vtable.container)
1961    }
1962
1963    /// See [`OffsetLayerMixin::offset`].
1964    pub fn offset(self, app: &App) -> Offset {
1965        (self.vtable.offset_data)(app, self.id).offset
1966    }
1967
1968    /// See [`OffsetLayerMixin::set_offset`].
1969    pub fn set_offset(self, app: &mut App, value: Offset) {
1970        if value == self.offset(app) {
1971            return;
1972        }
1973        (self.vtable.offset_data_mut)(app, self.id).offset = value;
1974        if !self.as_layer().always_needs_add_to_scene(app) {
1975            self.as_layer().mark_needs_add_to_scene(app);
1976        }
1977    }
1978}
1979
1980/// Flutter's concrete `OffsetLayer`; the bodies are [`OffsetLayerMixin`].
1981pub struct OffsetLayer {
1982    layer: LayerData,
1983    container_layer: ContainerLayerData,
1984    offset_layer: OffsetLayerData,
1985}
1986
1987impl OffsetLayer {
1988    /// Creates an offset layer.
1989    ///
1990    /// By default, `offset` is zero. It must be set before the compositing phase of the pipeline.
1991    pub fn new(app: &mut App, offset: Offset) -> Handle<OffsetLayer> {
1992        app.create(OffsetLayer {
1993            layer: LayerData::new(),
1994            container_layer: ContainerLayerData::new(),
1995            offset_layer: OffsetLayerData::new(offset),
1996        })
1997    }
1998}
1999
2000impl Layer for OffsetLayer {
2001    crate::layer_accessors!(container);
2002
2003    fn supports_rasterization(self: Handle<Self>, app: &App) -> bool {
2004        ContainerLayer::supports_rasterization(self, app)
2005    }
2006
2007    fn dispose(self: Handle<Self>, app: &mut App) {
2008        ContainerLayer::dispose(self, app);
2009    }
2010
2011    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
2012        ContainerLayer::attach(self, app, owner);
2013    }
2014
2015    fn detach(self: Handle<Self>, app: &mut App) {
2016        ContainerLayer::detach(self, app);
2017    }
2018
2019    fn redepth_children(self: Handle<Self>, app: &mut App) {
2020        ContainerLayer::redepth_children(self, app);
2021    }
2022
2023    fn find_annotations(
2024        self: Handle<Self>,
2025        app: &App,
2026        result: &mut AnnotationSearch,
2027        local_position: Offset,
2028        only_first: bool,
2029    ) -> bool {
2030        OffsetLayerMixin::find_annotations(self, app, result, local_position, only_first)
2031    }
2032
2033    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
2034        OffsetLayerMixin::add_to_scene(self, app, builder);
2035    }
2036
2037    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
2038        ContainerLayer::fire_composition_callbacks(self, app, include_children);
2039    }
2040}
2041
2042impl ContainerLayer for OffsetLayer {
2043    crate::container_layer_accessors!(offset);
2044
2045    fn apply_transform(
2046        self: Handle<Self>,
2047        app: &App,
2048        child: Option<AnyLayer>,
2049        transform: &mut Matrix4,
2050    ) {
2051        OffsetLayerMixin::apply_transform(self, app, child, transform);
2052    }
2053}
2054
2055impl OffsetLayerMixin for OffsetLayer {
2056    crate::offset_layer_accessors!();
2057}
2058
2059/// A key that identifies a group of backdrop filters that share one backdrop.
2060///
2061/// Every `BackdropFilterLayer` with the same key blurs the scene once, as of the first of
2062/// them, which is what Flutter's `BackdropGroup` trades for the cost of one filter pass.
2063#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
2064pub struct BackdropKey(u64);
2065
2066static NEXT_BACKDROP_KEY: AtomicU64 = AtomicU64::new(0);
2067
2068impl BackdropKey {
2069    /// Create a new [`BackdropKey`].
2070    #[expect(
2071        clippy::new_without_default,
2072        reason = "each call creates a distinct key; Default would suggest a neutral value"
2073    )]
2074    pub fn new() -> BackdropKey {
2075        BackdropKey(NEXT_BACKDROP_KEY.fetch_add(1, Ordering::Relaxed))
2076    }
2077
2078    /// dart:ui's `backdropId` for [`SceneBuilder::push_backdrop_filter`].
2079    pub fn id(self) -> u64 {
2080        self.0
2081    }
2082}
2083
2084/// A composite layer that clips its children using a rectangle.
2085///
2086/// When debugging, setting [`debug_disable_clip_layers`](crate::debug::debug_disable_clip_layers)
2087/// to true will cause this layer to be skipped (directly replaced by its children). This can be
2088/// helpful to track down the cause of performance problems.
2089pub struct ClipRectLayer {
2090    layer: LayerData,
2091    container_layer: ContainerLayerData,
2092    clip_rect: Option<Rect>,
2093    clip_behavior: Clip,
2094}
2095
2096impl ClipRectLayer {
2097    /// Creates a layer with a rectangular clip.
2098    ///
2099    /// The [`clip_rect`](Self::clip_rect) argument must not be null before the compositing phase
2100    /// of the pipeline.
2101    ///
2102    /// The [`clip_behavior`](Self::clip_behavior) argument must not be [`Clip::None`].
2103    pub fn new(app: &mut App) -> Handle<ClipRectLayer> {
2104        debug_assert!(Clip::HardEdge != Clip::None);
2105        app.create(ClipRectLayer {
2106            layer: LayerData::new(),
2107            container_layer: ContainerLayerData::new(),
2108            clip_rect: None,
2109            clip_behavior: Clip::HardEdge,
2110        })
2111    }
2112
2113    /// The rectangle to clip in the parent's coordinate system.
2114    ///
2115    /// The scene must be explicitly recomposited after this property is changed (as described at
2116    /// [`Layer`]).
2117    pub fn clip_rect(self: Handle<Self>, app: &App) -> Option<Rect> {
2118        app.get(self).clip_rect
2119    }
2120
2121    /// See [`clip_rect`](Self::clip_rect).
2122    pub fn set_clip_rect(self: Handle<Self>, app: &mut App, value: Option<Rect>) {
2123        if value != app.get(self).clip_rect {
2124            app.get_mut(self).clip_rect = value;
2125            self.as_layer().mark_needs_add_to_scene(app);
2126        }
2127    }
2128
2129    /// Controls how to clip.
2130    ///
2131    /// Must not be set to null or [`Clip::None`].
2132    ///
2133    /// Defaults to [`Clip::HardEdge`].
2134    pub fn clip_behavior(self: Handle<Self>, app: &App) -> Clip {
2135        app.get(self).clip_behavior
2136    }
2137
2138    /// See [`clip_behavior`](Self::clip_behavior).
2139    pub fn set_clip_behavior(self: Handle<Self>, app: &mut App, value: Clip) {
2140        debug_assert!(value != Clip::None);
2141        if value != app.get(self).clip_behavior {
2142            app.get_mut(self).clip_behavior = value;
2143            self.as_layer().mark_needs_add_to_scene(app);
2144        }
2145    }
2146}
2147
2148impl Layer for ClipRectLayer {
2149    crate::layer_accessors!(container);
2150
2151    fn describe_clip_bounds(self: Handle<Self>, app: &App) -> Option<Rect> {
2152        self.clip_rect(app)
2153    }
2154
2155    fn supports_rasterization(self: Handle<Self>, app: &App) -> bool {
2156        ContainerLayer::supports_rasterization(self, app)
2157    }
2158
2159    fn dispose(self: Handle<Self>, app: &mut App) {
2160        ContainerLayer::dispose(self, app);
2161    }
2162
2163    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
2164        ContainerLayer::attach(self, app, owner);
2165    }
2166
2167    fn detach(self: Handle<Self>, app: &mut App) {
2168        ContainerLayer::detach(self, app);
2169    }
2170
2171    fn redepth_children(self: Handle<Self>, app: &mut App) {
2172        ContainerLayer::redepth_children(self, app);
2173    }
2174
2175    fn find_annotations(
2176        self: Handle<Self>,
2177        app: &App,
2178        result: &mut AnnotationSearch,
2179        local_position: Offset,
2180        only_first: bool,
2181    ) -> bool {
2182        if !self
2183            .clip_rect(app)
2184            .expect("clipRect must be set before searching annotations")
2185            .contains(local_position)
2186        {
2187            return false;
2188        }
2189        ContainerLayer::find_annotations(self, app, result, local_position, only_first)
2190    }
2191
2192    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
2193        debug_assert!(self.clip_rect(app).is_some());
2194        let mut enabled = true;
2195        if cfg!(debug_assertions) {
2196            enabled = !crate::debug::debug_disable_clip_layers();
2197        }
2198        if enabled {
2199            let clip_rect = self
2200                .clip_rect(app)
2201                .expect("clipRect must be set before compositing");
2202            let clip_behavior = self.clip_behavior(app);
2203            builder.push_clip_rect(clip_rect, clip_behavior);
2204        }
2205        self.as_container_layer()
2206            .add_children_to_scene(app, builder);
2207        let engine_layer = enabled.then(|| builder.pop());
2208        self.as_layer().set_engine_layer(app, engine_layer);
2209    }
2210
2211    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
2212        ContainerLayer::fire_composition_callbacks(self, app, include_children);
2213    }
2214}
2215
2216impl ContainerLayer for ClipRectLayer {
2217    crate::container_layer_accessors!();
2218}
2219
2220/// A composite layer that clips its children using a rounded rectangle.
2221///
2222/// When debugging, setting [`debug_disable_clip_layers`](crate::debug::debug_disable_clip_layers)
2223/// to true will cause this layer to be skipped (directly replaced by its children). This can be
2224/// helpful to track down the cause of performance problems.
2225pub struct ClipRRectLayer {
2226    layer: LayerData,
2227    container_layer: ContainerLayerData,
2228    clip_rrect: Option<RRect>,
2229    clip_behavior: Clip,
2230}
2231
2232impl ClipRRectLayer {
2233    /// Creates a layer with a rounded-rectangular clip.
2234    ///
2235    /// The [`clip_rrect`](Self::clip_rrect) and [`clip_behavior`](Self::clip_behavior) properties
2236    /// must be non-null before the compositing phase of the pipeline.
2237    pub fn new(app: &mut App) -> Handle<ClipRRectLayer> {
2238        debug_assert!(Clip::AntiAlias != Clip::None);
2239        app.create(ClipRRectLayer {
2240            layer: LayerData::new(),
2241            container_layer: ContainerLayerData::new(),
2242            clip_rrect: None,
2243            clip_behavior: Clip::AntiAlias,
2244        })
2245    }
2246
2247    /// The rounded-rect to clip in the parent's coordinate system.
2248    ///
2249    /// The scene must be explicitly recomposited after this property is changed (as described at
2250    /// [`Layer`]).
2251    pub fn clip_rrect(self: Handle<Self>, app: &App) -> Option<RRect> {
2252        app.get(self).clip_rrect
2253    }
2254
2255    /// See [`clip_rrect`](Self::clip_rrect).
2256    pub fn set_clip_rrect(self: Handle<Self>, app: &mut App, value: Option<RRect>) {
2257        if value != app.get(self).clip_rrect {
2258            app.get_mut(self).clip_rrect = value;
2259            self.as_layer().mark_needs_add_to_scene(app);
2260        }
2261    }
2262
2263    /// Controls how to clip.
2264    ///
2265    /// Must not be set to null or [`Clip::None`].
2266    ///
2267    /// Defaults to [`Clip::AntiAlias`].
2268    pub fn clip_behavior(self: Handle<Self>, app: &App) -> Clip {
2269        app.get(self).clip_behavior
2270    }
2271
2272    /// See [`clip_behavior`](Self::clip_behavior).
2273    pub fn set_clip_behavior(self: Handle<Self>, app: &mut App, value: Clip) {
2274        debug_assert!(value != Clip::None);
2275        if value != app.get(self).clip_behavior {
2276            app.get_mut(self).clip_behavior = value;
2277            self.as_layer().mark_needs_add_to_scene(app);
2278        }
2279    }
2280}
2281
2282impl Layer for ClipRRectLayer {
2283    crate::layer_accessors!(container);
2284
2285    fn describe_clip_bounds(self: Handle<Self>, app: &App) -> Option<Rect> {
2286        self.clip_rrect(app).map(RRect::outer_rect)
2287    }
2288
2289    fn supports_rasterization(self: Handle<Self>, app: &App) -> bool {
2290        ContainerLayer::supports_rasterization(self, app)
2291    }
2292
2293    fn dispose(self: Handle<Self>, app: &mut App) {
2294        ContainerLayer::dispose(self, app);
2295    }
2296
2297    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
2298        ContainerLayer::attach(self, app, owner);
2299    }
2300
2301    fn detach(self: Handle<Self>, app: &mut App) {
2302        ContainerLayer::detach(self, app);
2303    }
2304
2305    fn redepth_children(self: Handle<Self>, app: &mut App) {
2306        ContainerLayer::redepth_children(self, app);
2307    }
2308
2309    fn find_annotations(
2310        self: Handle<Self>,
2311        app: &App,
2312        result: &mut AnnotationSearch,
2313        local_position: Offset,
2314        only_first: bool,
2315    ) -> bool {
2316        if !self
2317            .clip_rrect(app)
2318            .expect("clipRRect must be set before searching annotations")
2319            .contains(local_position)
2320        {
2321            return false;
2322        }
2323        ContainerLayer::find_annotations(self, app, result, local_position, only_first)
2324    }
2325
2326    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
2327        debug_assert!(self.clip_rrect(app).is_some());
2328        let mut enabled = true;
2329        if cfg!(debug_assertions) {
2330            enabled = !crate::debug::debug_disable_clip_layers();
2331        }
2332        if enabled {
2333            let clip_rrect = self
2334                .clip_rrect(app)
2335                .expect("clipRRect must be set before compositing");
2336            let clip_behavior = self.clip_behavior(app);
2337            builder.push_clip_rrect(clip_rrect, clip_behavior);
2338        }
2339        self.as_container_layer()
2340            .add_children_to_scene(app, builder);
2341        let engine_layer = enabled.then(|| builder.pop());
2342        self.as_layer().set_engine_layer(app, engine_layer);
2343    }
2344
2345    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
2346        ContainerLayer::fire_composition_callbacks(self, app, include_children);
2347    }
2348}
2349
2350impl ContainerLayer for ClipRRectLayer {
2351    crate::container_layer_accessors!();
2352}
2353
2354/// A composite layer that clips its children using a path.
2355///
2356/// When debugging, setting [`debug_disable_clip_layers`](crate::debug::debug_disable_clip_layers)
2357/// to true will cause this layer to be skipped (directly replaced by its children). This can be
2358/// helpful to track down the cause of performance problems.
2359pub struct ClipPathLayer {
2360    layer: LayerData,
2361    container_layer: ContainerLayerData,
2362    clip_path: Option<Arc<inset_embedder::Path>>,
2363    clip_behavior: Clip,
2364}
2365
2366impl ClipPathLayer {
2367    /// Creates a layer with a path-based clip.
2368    ///
2369    /// The [`clip_path`](Self::clip_path) and [`clip_behavior`](Self::clip_behavior) properties
2370    /// must be non-null before the compositing phase of the pipeline.
2371    pub fn new(app: &mut App) -> Handle<ClipPathLayer> {
2372        debug_assert!(Clip::AntiAlias != Clip::None);
2373        app.create(ClipPathLayer {
2374            layer: LayerData::new(),
2375            container_layer: ContainerLayerData::new(),
2376            clip_path: None,
2377            clip_behavior: Clip::AntiAlias,
2378        })
2379    }
2380
2381    /// The path to clip in the parent's coordinate system.
2382    ///
2383    /// The scene must be explicitly recomposited after this property is changed (as described at
2384    /// [`Layer`]).
2385    pub fn clip_path(self: Handle<Self>, app: &App) -> Option<&Arc<inset_embedder::Path>> {
2386        app.get(self).clip_path.as_ref()
2387    }
2388
2389    /// See [`clip_path`](Self::clip_path).
2390    pub fn set_clip_path(
2391        self: Handle<Self>,
2392        app: &mut App,
2393        value: Option<Arc<inset_embedder::Path>>,
2394    ) {
2395        app.get_mut(self).clip_path = value;
2396        self.as_layer().mark_needs_add_to_scene(app);
2397    }
2398
2399    /// Controls how to clip.
2400    ///
2401    /// Must not be set to null or [`Clip::None`].
2402    ///
2403    /// Defaults to [`Clip::AntiAlias`].
2404    pub fn clip_behavior(self: Handle<Self>, app: &App) -> Clip {
2405        app.get(self).clip_behavior
2406    }
2407
2408    /// See [`clip_behavior`](Self::clip_behavior).
2409    pub fn set_clip_behavior(self: Handle<Self>, app: &mut App, value: Clip) {
2410        debug_assert!(value != Clip::None);
2411        if value != app.get(self).clip_behavior {
2412            app.get_mut(self).clip_behavior = value;
2413            self.as_layer().mark_needs_add_to_scene(app);
2414        }
2415    }
2416}
2417
2418impl Layer for ClipPathLayer {
2419    crate::layer_accessors!(container);
2420
2421    fn describe_clip_bounds(self: Handle<Self>, app: &App) -> Option<Rect> {
2422        let bounds = app.get(self).clip_path.as_ref()?.bounds();
2423        Some(Rect::from_ltwh(
2424            bounds.x as f64,
2425            bounds.y as f64,
2426            bounds.width as f64,
2427            bounds.height as f64,
2428        ))
2429    }
2430
2431    fn supports_rasterization(self: Handle<Self>, app: &App) -> bool {
2432        ContainerLayer::supports_rasterization(self, app)
2433    }
2434
2435    fn dispose(self: Handle<Self>, app: &mut App) {
2436        ContainerLayer::dispose(self, app);
2437    }
2438
2439    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
2440        ContainerLayer::attach(self, app, owner);
2441    }
2442
2443    fn detach(self: Handle<Self>, app: &mut App) {
2444        ContainerLayer::detach(self, app);
2445    }
2446
2447    fn redepth_children(self: Handle<Self>, app: &mut App) {
2448        ContainerLayer::redepth_children(self, app);
2449    }
2450
2451    fn find_annotations(
2452        self: Handle<Self>,
2453        app: &App,
2454        result: &mut AnnotationSearch,
2455        local_position: Offset,
2456        only_first: bool,
2457    ) -> bool {
2458        let path = app
2459            .get(self)
2460            .clip_path
2461            .as_ref()
2462            .expect("clipPath must be set before searching annotations");
2463        if !path.contains(local_position.into(), FillRule::NonZero) {
2464            return false;
2465        }
2466        ContainerLayer::find_annotations(self, app, result, local_position, only_first)
2467    }
2468
2469    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
2470        debug_assert!(app.get(self).clip_path.is_some());
2471        let mut enabled = true;
2472        if cfg!(debug_assertions) {
2473            enabled = !crate::debug::debug_disable_clip_layers();
2474        }
2475        if enabled {
2476            let clip_path = Arc::clone(
2477                app.get(self)
2478                    .clip_path
2479                    .as_ref()
2480                    .expect("clipPath must be set before compositing"),
2481            );
2482            let clip_behavior = self.clip_behavior(app);
2483            builder.push_clip_path(&clip_path, clip_behavior);
2484        }
2485        self.as_container_layer()
2486            .add_children_to_scene(app, builder);
2487        let engine_layer = enabled.then(|| builder.pop());
2488        self.as_layer().set_engine_layer(app, engine_layer);
2489    }
2490
2491    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
2492        ContainerLayer::fire_composition_callbacks(self, app, include_children);
2493    }
2494}
2495
2496impl ContainerLayer for ClipPathLayer {
2497    crate::container_layer_accessors!();
2498}
2499
2500/// Dart's `MatrixUtils.transformPoint`.
2501fn transform_point(transform: &Matrix4, point: Offset) -> Offset {
2502    let storage = transform.to_flutter_array();
2503    let x = point.dx();
2504    let y = point.dy();
2505    let rx = storage[0] as f64 * x + storage[4] as f64 * y + storage[12] as f64;
2506    let ry = storage[1] as f64 * x + storage[5] as f64 * y + storage[13] as f64;
2507    let rw = storage[3] as f64 * x + storage[7] as f64 * y + storage[15] as f64;
2508    if rw == 1.0 {
2509        Offset::new(rx, ry)
2510    } else {
2511        Offset::new(rx / rw, ry / rw)
2512    }
2513}
2514
2515/// A composited layer that applies a given transformation matrix to its children.
2516///
2517/// This class inherits from [`OffsetLayer`] to make it one of the layers that can be used at the
2518/// root of a `RenderObject` hierarchy.
2519pub struct TransformLayer {
2520    layer: LayerData,
2521    container_layer: ContainerLayerData,
2522    offset_layer: OffsetLayerData,
2523    transform: Option<Matrix4>,
2524    last_effective_transform: Option<Matrix4>,
2525    inverted_transform: Cell<Option<Matrix4>>,
2526    inverse_dirty: Cell<bool>,
2527}
2528
2529impl TransformLayer {
2530    /// Creates a transform layer.
2531    ///
2532    /// The [`transform`](Self::transform) and `offset` properties must be non-null before the
2533    /// compositing phase of the pipeline.
2534    pub fn new(app: &mut App) -> Handle<TransformLayer> {
2535        app.create(TransformLayer {
2536            layer: LayerData::new(),
2537            container_layer: ContainerLayerData::new(),
2538            offset_layer: OffsetLayerData::new(Offset::ZERO),
2539            transform: None,
2540            last_effective_transform: None,
2541            inverted_transform: Cell::new(None),
2542            inverse_dirty: Cell::new(true),
2543        })
2544    }
2545
2546    /// The matrix to apply.
2547    ///
2548    /// The scene must be explicitly recomposited after this property is changed (as described at
2549    /// [`Layer`]).
2550    ///
2551    /// This transform is applied before `offset`, if both are set.
2552    ///
2553    /// The [`transform`](Self::transform) property must be non-null before the compositing phase
2554    /// of the pipeline.
2555    pub fn transform(self: Handle<Self>, app: &App) -> Option<Matrix4> {
2556        app.get(self).transform
2557    }
2558
2559    /// See [`transform`](Self::transform).
2560    pub fn set_transform(self: Handle<Self>, app: &mut App, value: Matrix4) {
2561        debug_assert!(
2562            value
2563                .to_flutter_array()
2564                .iter()
2565                .all(|component| component.is_finite())
2566        );
2567        if app.get(self).transform == Some(value) {
2568            return;
2569        }
2570        app.get_mut(self).transform = Some(value);
2571        app.get(self).inverse_dirty.set(true);
2572        self.as_layer().mark_needs_add_to_scene(app);
2573    }
2574
2575    fn transform_offset(self: Handle<Self>, app: &App, local_position: Offset) -> Option<Offset> {
2576        if app.get(self).inverse_dirty.get() {
2577            let transform = app
2578                .get(self)
2579                .transform
2580                .expect("transform must be set before searching annotations");
2581            app.get(self)
2582                .inverted_transform
2583                .set(remove_perspective_transform(transform).invert());
2584            app.get(self).inverse_dirty.set(false);
2585        }
2586        app.get(self)
2587            .inverted_transform
2588            .get()
2589            .map(|inverted| transform_point(&inverted, local_position))
2590    }
2591}
2592
2593impl Layer for TransformLayer {
2594    crate::layer_accessors!(container);
2595
2596    fn supports_rasterization(self: Handle<Self>, app: &App) -> bool {
2597        ContainerLayer::supports_rasterization(self, app)
2598    }
2599
2600    fn dispose(self: Handle<Self>, app: &mut App) {
2601        ContainerLayer::dispose(self, app);
2602    }
2603
2604    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
2605        ContainerLayer::attach(self, app, owner);
2606    }
2607
2608    fn detach(self: Handle<Self>, app: &mut App) {
2609        ContainerLayer::detach(self, app);
2610    }
2611
2612    fn redepth_children(self: Handle<Self>, app: &mut App) {
2613        ContainerLayer::redepth_children(self, app);
2614    }
2615
2616    fn find_annotations(
2617        self: Handle<Self>,
2618        app: &App,
2619        result: &mut AnnotationSearch,
2620        local_position: Offset,
2621        only_first: bool,
2622    ) -> bool {
2623        let Some(transformed_offset) = self.transform_offset(app, local_position) else {
2624            return false;
2625        };
2626        OffsetLayerMixin::find_annotations(self, app, result, transformed_offset, only_first)
2627    }
2628
2629    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
2630        debug_assert!(self.transform(app).is_some());
2631        let mut last_effective = self
2632            .transform(app)
2633            .expect("transform must be set before compositing");
2634        let offset = self.offset(app);
2635        if offset != Offset::ZERO {
2636            last_effective =
2637                Matrix4::translation(offset.dx() as f32, offset.dy() as f32).then(&last_effective);
2638        }
2639        app.get_mut(self).last_effective_transform = Some(last_effective);
2640        builder.push_transform(&last_effective);
2641        self.as_container_layer()
2642            .add_children_to_scene(app, builder);
2643        let engine_layer = builder.pop();
2644        self.as_layer().set_engine_layer(app, Some(engine_layer));
2645    }
2646
2647    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
2648        ContainerLayer::fire_composition_callbacks(self, app, include_children);
2649    }
2650}
2651
2652impl ContainerLayer for TransformLayer {
2653    crate::container_layer_accessors!(offset);
2654
2655    fn apply_transform(
2656        self: Handle<Self>,
2657        app: &App,
2658        child: Option<AnyLayer>,
2659        transform: &mut Matrix4,
2660    ) {
2661        debug_assert!(child.is_some());
2662        debug_assert!(
2663            app.get(self).last_effective_transform.is_some() || self.transform(app).is_some()
2664        );
2665        let applied = match app.get(self).last_effective_transform {
2666            None => self
2667                .transform(app)
2668                .expect("transform must be set before applyTransform"),
2669            Some(last_effective) => last_effective,
2670        };
2671        *transform = transform.then(&applied);
2672    }
2673}
2674
2675impl OffsetLayerMixin for TransformLayer {
2676    crate::offset_layer_accessors!();
2677}
2678
2679/// A composited layer that makes its children partially transparent.
2680///
2681/// When debugging, setting
2682/// [`debug_disable_opacity_layers`](crate::debug::debug_disable_opacity_layers) to true will
2683/// cause this layer to be skipped (directly replaced by its children). This can be helpful to
2684/// track down the cause of performance problems.
2685///
2686/// Try to avoid an [`OpacityLayer`] with no children. Remove that layer if possible to save some
2687/// tree walks.
2688pub struct OpacityLayer {
2689    layer: LayerData,
2690    container_layer: ContainerLayerData,
2691    offset_layer: OffsetLayerData,
2692    alpha: Option<i32>,
2693}
2694
2695impl OpacityLayer {
2696    /// Creates an opacity layer.
2697    ///
2698    /// The [`alpha`](Self::alpha) property must be non-null before the compositing phase of the
2699    /// pipeline.
2700    pub fn new(app: &mut App) -> Handle<OpacityLayer> {
2701        app.create(OpacityLayer {
2702            layer: LayerData::new(),
2703            container_layer: ContainerLayerData::new(),
2704            offset_layer: OffsetLayerData::new(Offset::ZERO),
2705            alpha: None,
2706        })
2707    }
2708
2709    /// The amount to multiply into the alpha channel.
2710    ///
2711    /// The opacity is expressed as an integer from 0 to 255, where 0 is fully transparent and
2712    /// 255 is fully opaque.
2713    ///
2714    /// The scene must be explicitly recomposited after this property is changed (as described at
2715    /// [`Layer`]).
2716    pub fn alpha(self: Handle<Self>, app: &App) -> Option<i32> {
2717        app.get(self).alpha
2718    }
2719
2720    /// See [`alpha`](Self::alpha).
2721    pub fn set_alpha(self: Handle<Self>, app: &mut App, value: i32) {
2722        if app.get(self).alpha != Some(value) {
2723            app.get_mut(self).alpha = Some(value);
2724            self.as_layer().mark_needs_add_to_scene(app);
2725        }
2726    }
2727}
2728
2729impl Layer for OpacityLayer {
2730    crate::layer_accessors!(container);
2731
2732    fn supports_rasterization(self: Handle<Self>, app: &App) -> bool {
2733        ContainerLayer::supports_rasterization(self, app)
2734    }
2735
2736    fn dispose(self: Handle<Self>, app: &mut App) {
2737        ContainerLayer::dispose(self, app);
2738    }
2739
2740    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
2741        ContainerLayer::attach(self, app, owner);
2742    }
2743
2744    fn detach(self: Handle<Self>, app: &mut App) {
2745        ContainerLayer::detach(self, app);
2746    }
2747
2748    fn redepth_children(self: Handle<Self>, app: &mut App) {
2749        ContainerLayer::redepth_children(self, app);
2750    }
2751
2752    fn find_annotations(
2753        self: Handle<Self>,
2754        app: &App,
2755        result: &mut AnnotationSearch,
2756        local_position: Offset,
2757        only_first: bool,
2758    ) -> bool {
2759        OffsetLayerMixin::find_annotations(self, app, result, local_position, only_first)
2760    }
2761
2762    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
2763        debug_assert!(self.alpha(app).is_some());
2764
2765        // Don't add this layer if there's no child.
2766        let mut enabled = self.as_container_layer().first_child(app).is_some();
2767        if !enabled {
2768            // Ensure the engine layer is disposed.
2769            self.as_layer().set_engine_layer(app, None);
2770            return;
2771        }
2772
2773        if cfg!(debug_assertions) {
2774            enabled = enabled && !crate::debug::debug_disable_opacity_layers();
2775        }
2776
2777        let realized_alpha = self
2778            .alpha(app)
2779            .expect("alpha must be set before compositing");
2780        let offset = self.offset(app);
2781        if enabled && realized_alpha < 255 {
2782            builder.push_opacity(realized_alpha, offset);
2783        } else {
2784            builder.push_offset(offset.dx(), offset.dy());
2785        }
2786        self.as_container_layer()
2787            .add_children_to_scene(app, builder);
2788        let engine_layer = builder.pop();
2789        self.as_layer().set_engine_layer(app, Some(engine_layer));
2790    }
2791
2792    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
2793        ContainerLayer::fire_composition_callbacks(self, app, include_children);
2794    }
2795}
2796
2797impl ContainerLayer for OpacityLayer {
2798    crate::container_layer_accessors!(offset);
2799
2800    fn apply_transform(
2801        self: Handle<Self>,
2802        app: &App,
2803        child: Option<AnyLayer>,
2804        transform: &mut Matrix4,
2805    ) {
2806        OffsetLayerMixin::apply_transform(self, app, child, transform);
2807    }
2808}
2809
2810impl OffsetLayerMixin for OpacityLayer {
2811    crate::offset_layer_accessors!();
2812}
2813
2814/// A composited layer that applies a filter to the existing contents of the scene.
2815pub struct BackdropFilterLayer {
2816    layer: LayerData,
2817    container_layer: ContainerLayerData,
2818    filter: Option<ImageFilter>,
2819    blend_mode: BlendMode,
2820    backdrop_key: Option<BackdropKey>,
2821}
2822
2823impl BackdropFilterLayer {
2824    /// Creates a backdrop filter layer.
2825    ///
2826    /// The [`filter`](Self::filter) property must be non-null before the compositing phase of
2827    /// the pipeline.
2828    ///
2829    /// The [`blend_mode`](Self::blend_mode) property defaults to [`BlendMode::SrcOver`].
2830    pub fn new(app: &mut App) -> Handle<BackdropFilterLayer> {
2831        app.create(BackdropFilterLayer {
2832            layer: LayerData::new(),
2833            container_layer: ContainerLayerData::new(),
2834            filter: None,
2835            blend_mode: BlendMode::SrcOver,
2836            backdrop_key: None,
2837        })
2838    }
2839
2840    /// The filter to apply to the existing contents of the scene.
2841    ///
2842    /// The scene must be explicitly recomposited after this property is changed (as described at
2843    /// [`Layer`]).
2844    pub fn filter(self: Handle<Self>, app: &App) -> Option<&ImageFilter> {
2845        app.get(self).filter.as_ref()
2846    }
2847
2848    /// See [`filter`](Self::filter).
2849    pub fn set_filter(self: Handle<Self>, app: &mut App, value: Option<ImageFilter>) {
2850        app.get_mut(self).filter = value;
2851        self.as_layer().mark_needs_add_to_scene(app);
2852    }
2853
2854    /// The blend mode to use to apply the filtered background content onto the background
2855    /// surface.
2856    ///
2857    /// The default value of this property is [`BlendMode::SrcOver`].
2858    ///
2859    /// The scene must be explicitly recomposited after this property is changed (as described at
2860    /// [`Layer`]).
2861    pub fn blend_mode(self: Handle<Self>, app: &App) -> BlendMode {
2862        app.get(self).blend_mode
2863    }
2864
2865    /// See [`blend_mode`](Self::blend_mode).
2866    pub fn set_blend_mode(self: Handle<Self>, app: &mut App, value: BlendMode) {
2867        if value != app.get(self).blend_mode {
2868            app.get_mut(self).blend_mode = value;
2869            self.as_layer().mark_needs_add_to_scene(app);
2870        }
2871    }
2872
2873    /// The backdrop key that identifies the `BackdropGroup` this filter will apply to.
2874    ///
2875    /// The default value for the backdrop key is `None`, meaning that it's not part of a
2876    /// `BackdropGroup`.
2877    ///
2878    /// The scene must be explicitly recomposited after this property is changed (as described at
2879    /// [`Layer`]).
2880    pub fn backdrop_key(self: Handle<Self>, app: &App) -> Option<BackdropKey> {
2881        app.get(self).backdrop_key
2882    }
2883
2884    /// See [`backdrop_key`](Self::backdrop_key).
2885    pub fn set_backdrop_key(self: Handle<Self>, app: &mut App, value: Option<BackdropKey>) {
2886        if value != app.get(self).backdrop_key {
2887            app.get_mut(self).backdrop_key = value;
2888            self.as_layer().mark_needs_add_to_scene(app);
2889        }
2890    }
2891}
2892
2893impl Layer for BackdropFilterLayer {
2894    crate::layer_accessors!(container);
2895
2896    fn supports_rasterization(self: Handle<Self>, app: &App) -> bool {
2897        ContainerLayer::supports_rasterization(self, app)
2898    }
2899
2900    fn dispose(self: Handle<Self>, app: &mut App) {
2901        ContainerLayer::dispose(self, app);
2902    }
2903
2904    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
2905        ContainerLayer::attach(self, app, owner);
2906    }
2907
2908    fn detach(self: Handle<Self>, app: &mut App) {
2909        ContainerLayer::detach(self, app);
2910    }
2911
2912    fn redepth_children(self: Handle<Self>, app: &mut App) {
2913        ContainerLayer::redepth_children(self, app);
2914    }
2915
2916    fn find_annotations(
2917        self: Handle<Self>,
2918        app: &App,
2919        result: &mut AnnotationSearch,
2920        local_position: Offset,
2921        only_first: bool,
2922    ) -> bool {
2923        ContainerLayer::find_annotations(self, app, result, local_position, only_first)
2924    }
2925
2926    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
2927        debug_assert!(app.get(self).filter.is_some());
2928        let filter = app
2929            .get(self)
2930            .filter
2931            .clone()
2932            .expect("filter must be set before compositing");
2933        let blend_mode = self.blend_mode(app);
2934        let backdrop_id = self.backdrop_key(app).map(BackdropKey::id);
2935        builder.push_backdrop_filter(&filter, blend_mode, backdrop_id);
2936        self.as_container_layer()
2937            .add_children_to_scene(app, builder);
2938        let engine_layer = builder.pop();
2939        self.as_layer().set_engine_layer(app, Some(engine_layer));
2940    }
2941
2942    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
2943        ContainerLayer::fire_composition_callbacks(self, app, include_children);
2944    }
2945}
2946
2947impl ContainerLayer for BackdropFilterLayer {
2948    crate::container_layer_accessors!();
2949}
2950
2951/// An object that a [`LeaderLayer`] can register with.
2952///
2953/// An instance of this class should be provided as the [`LeaderLayer::link`] and the
2954/// [`FollowerLayer::link`] properties to cause the [`FollowerLayer`] to follow the
2955/// [`LeaderLayer`].
2956///
2957/// See also:
2958///
2959///  * `CompositedTransformTarget`, the widget that creates a [`LeaderLayer`].
2960///  * `CompositedTransformFollower`, the widget that creates a [`FollowerLayer`].
2961///  * `RenderLeaderLayer` and `RenderFollowerLayer`, the corresponding render objects.
2962pub struct LayerLink {
2963    leader: Option<Handle<LeaderLayer>>,
2964    debug_previous_leaders: Option<HashSet<Handle<LeaderLayer>>>,
2965    debug_leader_check_scheduled: bool,
2966    /// The total size of the content of the connected [`LeaderLayer`].
2967    ///
2968    /// Generally this should be set by the `RenderObject` that paints on the registered
2969    /// [`LeaderLayer`] (for instance a `RenderLeaderLayer` that shares this link with its
2970    /// followers). This size may be outdated before and during layout.
2971    pub leader_size: Option<Size>,
2972}
2973
2974impl LayerLink {
2975    /// Creates a link with no leader.
2976    pub fn new(app: &mut App) -> Handle<LayerLink> {
2977        app.create(LayerLink {
2978            leader: None,
2979            debug_previous_leaders: None,
2980            debug_leader_check_scheduled: false,
2981            leader_size: None,
2982        })
2983    }
2984
2985    /// The [`LeaderLayer`] connected to this link.
2986    pub fn leader(self: Handle<Self>, app: &App) -> Option<Handle<LeaderLayer>> {
2987        app.get(self).leader
2988    }
2989
2990    fn register_leader(self: Handle<Self>, app: &mut App, leader: Handle<LeaderLayer>) {
2991        debug_assert_ne!(self.leader(app), Some(leader));
2992        if cfg!(debug_assertions)
2993            && let Some(current) = self.leader(app)
2994        {
2995            let previous = app
2996                .get_mut(self)
2997                .debug_previous_leaders
2998                .get_or_insert_with(HashSet::new);
2999            debug_assert!(previous.insert(current));
3000            self.debug_schedule_leaders_clean_up_check(app);
3001        }
3002        app.get_mut(self).leader = Some(leader);
3003    }
3004
3005    fn unregister_leader(self: Handle<Self>, app: &mut App, leader: Handle<LeaderLayer>) {
3006        if self.leader(app) == Some(leader) {
3007            app.get_mut(self).leader = None;
3008        } else if cfg!(debug_assertions) {
3009            let removed = app
3010                .get_mut(self)
3011                .debug_previous_leaders
3012                .as_mut()
3013                .expect("a replaced leader is tracked")
3014                .remove(&leader);
3015            debug_assert!(removed);
3016        }
3017    }
3018
3019    /// Schedules the check as post frame callback to make sure the `_debugPreviousLeaders` is
3020    /// empty.
3021    fn debug_schedule_leaders_clean_up_check(self: Handle<Self>, app: &mut App) {
3022        debug_assert!(app.get(self).debug_previous_leaders.is_some());
3023        if cfg!(debug_assertions) {
3024            if app.get(self).debug_leader_check_scheduled {
3025                return;
3026            }
3027            app.get_mut(self).debug_leader_check_scheduled = true;
3028            SchedulerBinding::add_post_frame_callback(
3029                app,
3030                FrameCallback::handle_method(self, |this, app, _time_stamp| {
3031                    app.get_mut(this).debug_leader_check_scheduled = false;
3032                    debug_assert!(
3033                        app.get(this)
3034                            .debug_previous_leaders
3035                            .as_ref()
3036                            .expect("a replaced leader is tracked")
3037                            .is_empty()
3038                    );
3039                }),
3040            );
3041        }
3042    }
3043}
3044
3045/// A composited layer that can be followed by a [`FollowerLayer`].
3046///
3047/// This layer collapses the accumulated offset into a transform and passes [`Offset::ZERO`] to
3048/// its child layers in the [`Layer::add_to_scene`] / `add_children_to_scene` methods, so that
3049/// [`ContainerLayer::apply_transform`] will work reliably.
3050pub struct LeaderLayer {
3051    layer: LayerData,
3052    container_layer: ContainerLayerData,
3053    /// `None` only while [`Layer::dispose`] takes the retain so it can [`App::release`] it
3054    /// before the arena entry is destroyed.
3055    link: Option<RetainedHandle<Handle<LayerLink>>>,
3056    offset: Offset,
3057}
3058
3059impl LeaderLayer {
3060    /// Creates a leader layer.
3061    ///
3062    /// The [`link`](Self::link) property must not have been provided to any other [`LeaderLayer`]
3063    /// layers that are attached to the layer tree at the same time.
3064    ///
3065    /// The [`offset`](Self::offset) property must be non-null before the compositing phase of
3066    /// the pipeline.
3067    pub fn new(app: &mut App, link: Handle<LayerLink>) -> Handle<LeaderLayer> {
3068        let link = app.retain(link);
3069        app.create(LeaderLayer {
3070            layer: LayerData::new(),
3071            container_layer: ContainerLayerData::new(),
3072            link: Some(link),
3073            offset: Offset::ZERO,
3074        })
3075    }
3076
3077    /// The object with which this layer should register.
3078    ///
3079    /// The link will be established when this layer is [`Layer::attach`]ed, and will be cleared
3080    /// when this layer is [`Layer::detach`]ed.
3081    pub fn link(self: Handle<Self>, app: &App) -> Handle<LayerLink> {
3082        app.get(self)
3083            .link
3084            .as_ref()
3085            .expect("a LeaderLayer holds its link until dispose")
3086            .get()
3087    }
3088
3089    /// See [`link`](Self::link).
3090    pub fn set_link(self: Handle<Self>, app: &mut App, value: Handle<LayerLink>) {
3091        let current = self.link(app);
3092        if current == value {
3093            return;
3094        }
3095        if self.as_layer().attached(app) {
3096            current.unregister_leader(app, self);
3097            value.register_leader(app, self);
3098        }
3099        let retained = app.retain(value);
3100        let old = app
3101            .get_mut(self)
3102            .link
3103            .replace(retained)
3104            .expect("a LeaderLayer holds its link until dispose");
3105        app.release(old);
3106    }
3107
3108    /// Offset from parent in the parent's coordinate system.
3109    ///
3110    /// The scene must be explicitly recomposited after this property is changed (as described at
3111    /// [`Layer`]).
3112    ///
3113    /// The [`offset`](Self::offset) property must be non-null before the compositing phase of
3114    /// the pipeline.
3115    pub fn offset(self: Handle<Self>, app: &App) -> Offset {
3116        app.get(self).offset
3117    }
3118
3119    /// See [`offset`](Self::offset).
3120    pub fn set_offset(self: Handle<Self>, app: &mut App, value: Offset) {
3121        if value == app.get(self).offset {
3122            return;
3123        }
3124        app.get_mut(self).offset = value;
3125        if !self.as_layer().always_needs_add_to_scene(app) {
3126            self.as_layer().mark_needs_add_to_scene(app);
3127        }
3128    }
3129}
3130
3131impl Layer for LeaderLayer {
3132    crate::layer_accessors!(container);
3133
3134    fn supports_rasterization(self: Handle<Self>, app: &App) -> bool {
3135        ContainerLayer::supports_rasterization(self, app)
3136    }
3137
3138    fn dispose(self: Handle<Self>, app: &mut App) {
3139        let link = app
3140            .get_mut(self)
3141            .link
3142            .take()
3143            .expect("a LeaderLayer holds its link until dispose");
3144        ContainerLayer::dispose(self, app);
3145        app.release(link);
3146    }
3147
3148    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
3149        ContainerLayer::attach(self, app, owner);
3150        let link = self.link(app);
3151        link.register_leader(app, self);
3152    }
3153
3154    fn detach(self: Handle<Self>, app: &mut App) {
3155        let link = self.link(app);
3156        link.unregister_leader(app, self);
3157        ContainerLayer::detach(self, app);
3158    }
3159
3160    fn redepth_children(self: Handle<Self>, app: &mut App) {
3161        ContainerLayer::redepth_children(self, app);
3162    }
3163
3164    fn find_annotations(
3165        self: Handle<Self>,
3166        app: &App,
3167        result: &mut AnnotationSearch,
3168        local_position: Offset,
3169        only_first: bool,
3170    ) -> bool {
3171        let offset = self.offset(app);
3172        ContainerLayer::find_annotations(self, app, result, local_position - offset, only_first)
3173    }
3174
3175    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
3176        let offset = self.offset(app);
3177        if offset != Offset::ZERO {
3178            builder.push_transform(&Matrix4::translation(
3179                offset.dx() as f32,
3180                offset.dy() as f32,
3181            ));
3182        }
3183        self.as_container_layer()
3184            .add_children_to_scene(app, builder);
3185        let engine_layer = (offset != Offset::ZERO).then(|| builder.pop());
3186        self.as_layer().set_engine_layer(app, engine_layer);
3187    }
3188
3189    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
3190        ContainerLayer::fire_composition_callbacks(self, app, include_children);
3191    }
3192}
3193
3194impl ContainerLayer for LeaderLayer {
3195    crate::container_layer_accessors!();
3196
3197    /// Applies the transform that would be applied when compositing the given child to the given
3198    /// matrix.
3199    ///
3200    /// See [`ContainerLayer::apply_transform`] for details.
3201    ///
3202    /// The `child` argument may be null, as the same transform is applied to all children.
3203    fn apply_transform(
3204        self: Handle<Self>,
3205        app: &App,
3206        _child: Option<AnyLayer>,
3207        transform: &mut Matrix4,
3208    ) {
3209        let offset = self.offset(app);
3210        if offset != Offset::ZERO {
3211            *transform = transform.then(&Matrix4::translation(
3212                offset.dx() as f32,
3213                offset.dy() as f32,
3214            ));
3215        }
3216    }
3217}
3218
3219/// A composited layer that applies a transformation matrix to its children such that they are
3220/// positioned to match a [`LeaderLayer`].
3221///
3222/// If any of the ancestors of this layer have a degenerate matrix (e.g. scaling by zero), then
3223/// the [`FollowerLayer`] will not be able to transform its child to the coordinate space of the
3224/// [`LeaderLayer`].
3225///
3226/// A [`linked_offset`](FollowerLayer::linked_offset) property can be provided to further offset
3227/// the child layer from the leader layer, for example if the child is to follow the linked layer
3228/// at a distance rather than directly overlapping it.
3229pub struct FollowerLayer {
3230    layer: LayerData,
3231    container_layer: ContainerLayerData,
3232    /// `None` only while [`Layer::dispose`] takes the retain so it can [`App::release`] it
3233    /// before the arena entry is destroyed.
3234    link: Option<RetainedHandle<Handle<LayerLink>>>,
3235    show_when_unlinked: bool,
3236    unlinked_offset: Offset,
3237    linked_offset: Offset,
3238    last_offset: Option<Offset>,
3239    last_transform: Option<Matrix4>,
3240    inverted_transform: Cell<Option<Matrix4>>,
3241    inverse_dirty: Cell<bool>,
3242}
3243
3244impl FollowerLayer {
3245    /// Creates a follower layer.
3246    ///
3247    /// The [`unlinked_offset`](Self::unlinked_offset), [`linked_offset`](Self::linked_offset),
3248    /// and [`show_when_unlinked`](Self::show_when_unlinked) properties must be non-null before
3249    /// the compositing phase of the pipeline.
3250    pub fn new(app: &mut App, link: Handle<LayerLink>) -> Handle<FollowerLayer> {
3251        let link = app.retain(link);
3252        app.create(FollowerLayer {
3253            layer: LayerData::new(),
3254            container_layer: ContainerLayerData::new(),
3255            link: Some(link),
3256            show_when_unlinked: true,
3257            unlinked_offset: Offset::ZERO,
3258            linked_offset: Offset::ZERO,
3259            last_offset: None,
3260            last_transform: None,
3261            inverted_transform: Cell::new(None),
3262            inverse_dirty: Cell::new(true),
3263        })
3264    }
3265
3266    /// The link to the [`LeaderLayer`].
3267    ///
3268    /// The same object should be provided to a [`LeaderLayer`] that is earlier in the layer
3269    /// tree. When this layer is composited, it will apply a transform that moves its children
3270    /// to match the position of the [`LeaderLayer`].
3271    pub fn link(self: Handle<Self>, app: &App) -> Handle<LayerLink> {
3272        app.get(self)
3273            .link
3274            .as_ref()
3275            .expect("a FollowerLayer holds its link until dispose")
3276            .get()
3277    }
3278
3279    /// See [`link`](Self::link).
3280    pub fn set_link(self: Handle<Self>, app: &mut App, value: Handle<LayerLink>) {
3281        if self.link(app) == value {
3282            return;
3283        }
3284        let retained = app.retain(value);
3285        let old = app
3286            .get_mut(self)
3287            .link
3288            .replace(retained)
3289            .expect("a FollowerLayer holds its link until dispose");
3290        app.release(old);
3291    }
3292
3293    /// Whether to show the layer's contents when the [`link`](Self::link) does not point to a
3294    /// [`LeaderLayer`].
3295    ///
3296    /// When the layer is linked, children layers are positioned such that they have the same
3297    /// global position as the linked [`LeaderLayer`].
3298    ///
3299    /// When the layer is not linked, then: if [`show_when_unlinked`](Self::show_when_unlinked)
3300    /// is true, children are positioned as if the [`FollowerLayer`] was a [`ContainerLayer`];
3301    /// if it is false, then children are hidden.
3302    ///
3303    /// The [`show_when_unlinked`](Self::show_when_unlinked) property must be non-null before the
3304    /// compositing phase of the pipeline.
3305    pub fn show_when_unlinked(self: Handle<Self>, app: &App) -> bool {
3306        app.get(self).show_when_unlinked
3307    }
3308
3309    /// See [`show_when_unlinked`](Self::show_when_unlinked).
3310    pub fn set_show_when_unlinked(self: Handle<Self>, app: &mut App, value: bool) {
3311        app.get_mut(self).show_when_unlinked = value;
3312    }
3313
3314    /// Offset from parent in the parent's coordinate system, used when the layer is not linked
3315    /// to a [`LeaderLayer`].
3316    ///
3317    /// The scene must be explicitly recomposited after this property is changed (as described at
3318    /// [`Layer`]).
3319    ///
3320    /// The [`unlinked_offset`](Self::unlinked_offset) property must be non-null before the
3321    /// compositing phase of the pipeline.
3322    ///
3323    /// See also:
3324    ///
3325    ///  * [`linked_offset`](Self::linked_offset), for when the layers are linked.
3326    pub fn unlinked_offset(self: Handle<Self>, app: &App) -> Offset {
3327        app.get(self).unlinked_offset
3328    }
3329
3330    /// See [`unlinked_offset`](Self::unlinked_offset).
3331    pub fn set_unlinked_offset(self: Handle<Self>, app: &mut App, value: Offset) {
3332        app.get_mut(self).unlinked_offset = value;
3333    }
3334
3335    /// Offset from the origin of the leader layer to the origin of the child layers, used when
3336    /// the layer is linked to a [`LeaderLayer`].
3337    ///
3338    /// The scene must be explicitly recomposited after this property is changed (as described at
3339    /// [`Layer`]).
3340    ///
3341    /// The [`linked_offset`](Self::linked_offset) property must be non-null before the
3342    /// compositing phase of the pipeline.
3343    ///
3344    /// See also:
3345    ///
3346    ///  * [`unlinked_offset`](Self::unlinked_offset), for when the layer is not linked.
3347    pub fn linked_offset(self: Handle<Self>, app: &App) -> Offset {
3348        app.get(self).linked_offset
3349    }
3350
3351    /// See [`linked_offset`](Self::linked_offset).
3352    pub fn set_linked_offset(self: Handle<Self>, app: &mut App, value: Offset) {
3353        app.get_mut(self).linked_offset = value;
3354    }
3355
3356    fn transform_offset(self: Handle<Self>, app: &App, local_position: Offset) -> Option<Offset> {
3357        if app.get(self).inverse_dirty.get() {
3358            let last = self.get_last_transform(app).expect(
3359                "FollowerLayer._transformOffset requires getLastTransform after addToScene",
3360            );
3361            app.get(self).inverted_transform.set(last.invert());
3362            app.get(self).inverse_dirty.set(false);
3363        }
3364        let inverted = app.get(self).inverted_transform.get()?;
3365        let storage = inverted.to_flutter_array();
3366        let x = local_position.dx();
3367        let y = local_position.dy();
3368        let rx = storage[0] as f64 * x + storage[4] as f64 * y + storage[12] as f64;
3369        let ry = storage[1] as f64 * x + storage[5] as f64 * y + storage[13] as f64;
3370        let linked_offset = self.linked_offset(app);
3371        Some(Offset::new(
3372            rx - linked_offset.dx(),
3373            ry - linked_offset.dy(),
3374        ))
3375    }
3376
3377    /// The transform that was used during the last composition phase.
3378    ///
3379    /// If the [`link`](Self::link) was not linked to a [`LeaderLayer`], or if this layer has a
3380    /// degenerate matrix applied, then this will be `None`.
3381    ///
3382    /// This method returns a new [`Matrix4`] instance each time it is invoked.
3383    pub fn get_last_transform(self: Handle<Self>, app: &App) -> Option<Matrix4> {
3384        let last_transform = app.get(self).last_transform?;
3385        let last_offset = app
3386            .get(self)
3387            .last_offset
3388            .expect("lastOffset is set with lastTransform");
3389        Some(
3390            Matrix4::translation(-last_offset.dx() as f32, -last_offset.dy() as f32)
3391                .then(&last_transform),
3392        )
3393    }
3394
3395    /// Call [`ContainerLayer::apply_transform`] for each layer in the provided list.
3396    ///
3397    /// The list is in reverse order (deepest first). The first layer will be treated as the
3398    /// child of the second, and so forth. The first layer in the list won't have
3399    /// `apply_transform` called on it. The first layer may be null.
3400    fn collect_transform_for_layer_chain(
3401        app: &App,
3402        layers: &[Option<AnyContainerLayer>],
3403    ) -> Matrix4 {
3404        let mut result = Matrix4::IDENTITY;
3405        for index in (1..layers.len()).rev() {
3406            if let Some(layer) = layers[index] {
3407                let child = layers[index - 1].map(AnyContainerLayer::as_layer);
3408                layer.apply_transform(app, child, &mut result);
3409            }
3410        }
3411        result
3412    }
3413
3414    /// Find the common ancestor of two layers `a` and `b` by searching towards the root of the
3415    /// tree, and append each ancestor of `a` or `b` visited along the path to `ancestors_a` and
3416    /// `ancestors_b` respectively.
3417    ///
3418    /// Returns `None` if `a` `b` do not share a common ancestor, in which case the results in
3419    /// `ancestors_a` and `ancestors_b` are undefined.
3420    fn paths_to_common_ancestor(
3421        app: &App,
3422        a: Option<AnyLayer>,
3423        b: Option<AnyLayer>,
3424        ancestors_a: &mut Vec<Option<AnyContainerLayer>>,
3425        ancestors_b: &mut Vec<Option<AnyContainerLayer>>,
3426    ) -> Option<AnyLayer> {
3427        let (a, b) = (a?, b?);
3428        if a == b {
3429            return Some(a);
3430        }
3431        if a.depth(app) < b.depth(app) {
3432            ancestors_b.push(b.parent(app));
3433            return Self::paths_to_common_ancestor(
3434                app,
3435                Some(a),
3436                b.parent(app).map(AnyContainerLayer::as_layer),
3437                ancestors_a,
3438                ancestors_b,
3439            );
3440        } else if a.depth(app) > b.depth(app) {
3441            ancestors_a.push(a.parent(app));
3442            return Self::paths_to_common_ancestor(
3443                app,
3444                a.parent(app).map(AnyContainerLayer::as_layer),
3445                Some(b),
3446                ancestors_a,
3447                ancestors_b,
3448            );
3449        }
3450        ancestors_a.push(a.parent(app));
3451        ancestors_b.push(b.parent(app));
3452        Self::paths_to_common_ancestor(
3453            app,
3454            a.parent(app).map(AnyContainerLayer::as_layer),
3455            b.parent(app).map(AnyContainerLayer::as_layer),
3456            ancestors_a,
3457            ancestors_b,
3458        )
3459    }
3460
3461    fn debug_check_leader_before_follower(
3462        app: &App,
3463        leader_to_common_ancestor: &[Option<AnyContainerLayer>],
3464        follower_to_common_ancestor: &[Option<AnyContainerLayer>],
3465    ) -> bool {
3466        if follower_to_common_ancestor.len() <= 1 {
3467            return false;
3468        }
3469        if leader_to_common_ancestor.len() <= 1 {
3470            return true;
3471        }
3472        let leader_subtree_below_ancestor = leader_to_common_ancestor
3473            [leader_to_common_ancestor.len() - 2]
3474            .expect("the leader subtree below the ancestor is a layer");
3475        let follower_subtree_below_ancestor = follower_to_common_ancestor
3476            [follower_to_common_ancestor.len() - 2]
3477            .expect("the follower subtree below the ancestor is a layer");
3478        let mut sibling = Some(leader_subtree_below_ancestor.as_layer());
3479        while let Some(layer) = sibling {
3480            if layer == follower_subtree_below_ancestor.as_layer() {
3481                return true;
3482            }
3483            sibling = layer.next_sibling(app);
3484        }
3485        false
3486    }
3487
3488    /// Populate `_lastTransform` given the current state of the tree.
3489    fn establish_transform(self: Handle<Self>, app: &mut App) {
3490        app.get_mut(self).last_transform = None;
3491        let Some(leader) = self.link(app).leader(app) else {
3492            return;
3493        };
3494        debug_assert_eq!(
3495            leader.as_layer().owner(app),
3496            self.as_layer().owner(app),
3497            "Linked LeaderLayer anchor is not in the same layer tree as the FollowerLayer."
3498        );
3499
3500        let mut forward_layers = vec![Some(leader.as_container_layer())];
3501        let mut inverse_layers = vec![Some(self.as_container_layer())];
3502        let ancestor = Self::paths_to_common_ancestor(
3503            app,
3504            Some(leader.as_layer()),
3505            Some(self.as_layer()),
3506            &mut forward_layers,
3507            &mut inverse_layers,
3508        );
3509        debug_assert!(
3510            ancestor.is_some(),
3511            "LeaderLayer and FollowerLayer do not have a common ancestor."
3512        );
3513        debug_assert!(
3514            Self::debug_check_leader_before_follower(app, &forward_layers, &inverse_layers),
3515            "LeaderLayer anchor must come before FollowerLayer in paint order, but the reverse \
3516             was true."
3517        );
3518
3519        let mut forward_transform = Self::collect_transform_for_layer_chain(app, &forward_layers);
3520        leader
3521            .as_container_layer()
3522            .apply_transform(app, None, &mut forward_transform);
3523        let linked_offset = self.linked_offset(app);
3524        forward_transform = forward_transform.then(&Matrix4::translation(
3525            linked_offset.dx() as f32,
3526            linked_offset.dy() as f32,
3527        ));
3528
3529        let inverse_transform = Self::collect_transform_for_layer_chain(app, &inverse_layers);
3530        let Some(inverse_transform) = inverse_transform.invert() else {
3531            return;
3532        };
3533        app.get_mut(self).last_transform = Some(inverse_transform.then(&forward_transform));
3534        app.get(self).inverse_dirty.set(true);
3535    }
3536}
3537
3538impl Layer for FollowerLayer {
3539    crate::layer_accessors!(container);
3540
3541    /// A [`FollowerLayer`] copies changes from a [`LeaderLayer`] that could be anywhere in the
3542    /// layer tree, and that leader layer could change without notifying the follower layer.
3543    /// Therefore a follower layer's `add_to_scene` is always called.
3544    fn always_needs_add_to_scene(self: Handle<Self>, _app: &App) -> bool {
3545        true
3546    }
3547
3548    fn supports_rasterization(self: Handle<Self>, app: &App) -> bool {
3549        ContainerLayer::supports_rasterization(self, app)
3550    }
3551
3552    fn dispose(self: Handle<Self>, app: &mut App) {
3553        let link = app
3554            .get_mut(self)
3555            .link
3556            .take()
3557            .expect("a FollowerLayer holds its link until dispose");
3558        ContainerLayer::dispose(self, app);
3559        app.release(link);
3560    }
3561
3562    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
3563        ContainerLayer::attach(self, app, owner);
3564    }
3565
3566    fn detach(self: Handle<Self>, app: &mut App) {
3567        ContainerLayer::detach(self, app);
3568    }
3569
3570    fn redepth_children(self: Handle<Self>, app: &mut App) {
3571        ContainerLayer::redepth_children(self, app);
3572    }
3573
3574    fn find_annotations(
3575        self: Handle<Self>,
3576        app: &App,
3577        result: &mut AnnotationSearch,
3578        local_position: Offset,
3579        only_first: bool,
3580    ) -> bool {
3581        if self.link(app).leader(app).is_none() {
3582            if self.show_when_unlinked(app) {
3583                return ContainerLayer::find_annotations(
3584                    self,
3585                    app,
3586                    result,
3587                    local_position - self.unlinked_offset(app),
3588                    only_first,
3589                );
3590            }
3591            return false;
3592        }
3593        let Some(transformed_offset) = self.transform_offset(app, local_position) else {
3594            return false;
3595        };
3596        ContainerLayer::find_annotations(self, app, result, transformed_offset, only_first)
3597    }
3598
3599    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
3600        if self.link(app).leader(app).is_none() && !self.show_when_unlinked(app) {
3601            app.get_mut(self).last_transform = None;
3602            app.get_mut(self).last_offset = None;
3603            app.get(self).inverse_dirty.set(true);
3604            self.as_layer().set_engine_layer(app, None);
3605            return;
3606        }
3607        self.establish_transform(app);
3608        if app.get(self).last_transform.is_some() {
3609            let unlinked_offset = self.unlinked_offset(app);
3610            app.get_mut(self).last_offset = Some(unlinked_offset);
3611            let last_transform = app
3612                .get(self)
3613                .last_transform
3614                .expect("lastTransform was just set");
3615            builder.push_transform(&last_transform);
3616            self.as_container_layer()
3617                .add_children_to_scene(app, builder);
3618            let engine_layer = builder.pop();
3619            self.as_layer().set_engine_layer(app, Some(engine_layer));
3620        } else {
3621            app.get_mut(self).last_offset = None;
3622            let unlinked_offset = self.unlinked_offset(app);
3623            let matrix =
3624                Matrix4::translation(unlinked_offset.dx() as f32, unlinked_offset.dy() as f32);
3625            builder.push_transform(&matrix);
3626            self.as_container_layer()
3627                .add_children_to_scene(app, builder);
3628            let engine_layer = builder.pop();
3629            self.as_layer().set_engine_layer(app, Some(engine_layer));
3630        }
3631        app.get(self).inverse_dirty.set(true);
3632    }
3633
3634    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
3635        ContainerLayer::fire_composition_callbacks(self, app, include_children);
3636    }
3637}
3638
3639impl ContainerLayer for FollowerLayer {
3640    crate::container_layer_accessors!();
3641
3642    fn apply_transform(
3643        self: Handle<Self>,
3644        app: &App,
3645        child: Option<AnyLayer>,
3646        transform: &mut Matrix4,
3647    ) {
3648        debug_assert!(child.is_some());
3649        if let Some(last_transform) = app.get(self).last_transform {
3650            *transform = transform.then(&last_transform);
3651        } else {
3652            let unlinked_offset = self.unlinked_offset(app);
3653            *transform = transform.then(&Matrix4::translation(
3654                unlinked_offset.dx() as f32,
3655                unlinked_offset.dy() as f32,
3656            ));
3657        }
3658    }
3659}
3660
3661/// A composited layer which annotates its children with a value. Pushing this layer to the tree
3662/// is the common way of adding an annotation.
3663///
3664/// An annotation is an optional object of any type that, when attached with a layer, can be
3665/// retrieved using [`AnyLayer::find`] or [`AnyLayer::find_all_annotations`] with a position. The
3666/// search process is done recursively, controlled by a concept of being opaque to a type of
3667/// annotation, explained in the document of [`Layer::find_annotations`].
3668///
3669/// When an annotation search arrives, this layer defers the same search to each of this layer's
3670/// children, respecting their opacity. Then it adds this layer's annotation if all of the
3671/// following restrictions are met:
3672///
3673/// * The target type must be identical to the annotated type `T`.
3674/// * If [`size`](Self::size) is provided, the target position must be contained within the
3675///   rectangle formed by [`size`](Self::size) and [`offset`](Self::offset).
3676///
3677/// This layer is opaque to a type of annotation if any child is also opaque, or if
3678/// [`opaque`](Self::opaque) is true and the layer's annotation is added.
3679pub struct AnnotatedRegionLayer {
3680    layer: LayerData,
3681    container_layer: ContainerLayerData,
3682    value: Rc<dyn Any>,
3683    size: Option<Size>,
3684    offset: Offset,
3685    opaque: bool,
3686}
3687
3688impl AnnotatedRegionLayer {
3689    /// Creates a new layer that annotates its children with `value`.
3690    pub fn new(app: &mut App, value: Rc<dyn Any>) -> Handle<AnnotatedRegionLayer> {
3691        app.create(AnnotatedRegionLayer {
3692            layer: LayerData::new(),
3693            container_layer: ContainerLayerData::new(),
3694            value,
3695            size: None,
3696            offset: Offset::ZERO,
3697            opaque: false,
3698        })
3699    }
3700
3701    /// The annotated object, which is added to the result if all restrictions are met.
3702    pub fn value(self: Handle<Self>, app: &App) -> &Rc<dyn Any> {
3703        &app.get(self).value
3704    }
3705
3706    /// The size of the annotated object.
3707    ///
3708    /// If [`size`](Self::size) is provided, then the annotation is found only if the target
3709    /// position is contained by the rectangle formed by [`size`](Self::size) and
3710    /// [`offset`](Self::offset). Otherwise no such restriction is applied, and clipping can only
3711    /// be done by the ancestor layers.
3712    pub fn size(self: Handle<Self>, app: &App) -> Option<Size> {
3713        app.get(self).size
3714    }
3715
3716    /// See [`size`](Self::size).
3717    pub fn set_size(self: Handle<Self>, app: &mut App, value: Option<Size>) {
3718        app.get_mut(self).size = value;
3719    }
3720
3721    /// The position of the annotated object.
3722    ///
3723    /// The [`offset`](Self::offset) defaults to [`Offset::ZERO`] if not provided, and is ignored
3724    /// if [`size`](Self::size) is not set.
3725    ///
3726    /// The [`offset`](Self::offset) only offsets the clipping rectangle, and does not affect how
3727    /// the painting or annotation search is propagated to its children.
3728    pub fn offset(self: Handle<Self>, app: &App) -> Offset {
3729        app.get(self).offset
3730    }
3731
3732    /// See [`offset`](Self::offset).
3733    pub fn set_offset(self: Handle<Self>, app: &mut App, value: Offset) {
3734        app.get_mut(self).offset = value;
3735    }
3736
3737    /// Whether the annotation of this layer should be opaque during an annotation search of type
3738    /// `T`, preventing siblings visually behind it from being searched.
3739    ///
3740    /// If [`opaque`](Self::opaque) is true, and this layer does add its annotation
3741    /// [`value`](Self::value), then the layer will always be opaque during the search.
3742    ///
3743    /// If [`opaque`](Self::opaque) is false, or if this layer does not add its annotation, then
3744    /// the opacity of this layer will be the one returned by the children, meaning that it will
3745    /// be opaque if any child is opaque.
3746    ///
3747    /// The [`opaque`](Self::opaque) defaults to false.
3748    ///
3749    /// The [`opaque`](Self::opaque) is effectively useless during [`AnyLayer::find`] (more
3750    /// specifically, [`Layer::find_annotations`] with `only_first: true`), since the search
3751    /// process then skips the remaining tree after finding the first annotation.
3752    ///
3753    /// See also:
3754    ///
3755    ///  * [`Layer::find_annotations`], which explains the concept of being opaque to a type of
3756    ///    annotation as the return value.
3757    ///  * `HitTestBehavior`, which controls similar logic when hit-testing in the render tree.
3758    pub fn opaque(self: Handle<Self>, app: &App) -> bool {
3759        app.get(self).opaque
3760    }
3761
3762    /// See [`opaque`](Self::opaque).
3763    pub fn set_opaque(self: Handle<Self>, app: &mut App, value: bool) {
3764        app.get_mut(self).opaque = value;
3765    }
3766}
3767
3768impl Layer for AnnotatedRegionLayer {
3769    crate::layer_accessors!(container);
3770
3771    fn supports_rasterization(self: Handle<Self>, app: &App) -> bool {
3772        ContainerLayer::supports_rasterization(self, app)
3773    }
3774
3775    fn dispose(self: Handle<Self>, app: &mut App) {
3776        ContainerLayer::dispose(self, app);
3777    }
3778
3779    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
3780        ContainerLayer::attach(self, app, owner);
3781    }
3782
3783    fn detach(self: Handle<Self>, app: &mut App) {
3784        ContainerLayer::detach(self, app);
3785    }
3786
3787    fn redepth_children(self: Handle<Self>, app: &mut App) {
3788        ContainerLayer::redepth_children(self, app);
3789    }
3790
3791    /// Searches the subtree for annotations of the searched type at the location `local_position`,
3792    /// then adds the annotation [`value`](Self::value) if applicable.
3793    ///
3794    /// This method always searches its children, and if any child returns `true`, the remaining
3795    /// children are skipped. Regardless of what the children return, this method then adds this
3796    /// layer's annotation if all of the following restrictions are met:
3797    ///
3798    /// * The target type must be identical to the annotated type `T`.
3799    /// * If [`size`](Self::size) is provided, the target position must be contained within the
3800    ///   rectangle formed by [`size`](Self::size) and [`offset`](Self::offset).
3801    ///
3802    /// This search process respects `only_first`, meaning that when `only_first` is true, the
3803    /// search will stop when it finds the first annotation from the children, and the layer's
3804    /// own annotation is checked only when none is given by the children.
3805    ///
3806    /// The return value is true if any child returns `true`, or if [`opaque`](Self::opaque) is
3807    /// true and the layer's annotation is added.
3808    ///
3809    /// For explanation of layer annotations, parameters and return value, refer to
3810    /// [`Layer::find_annotations`].
3811    fn find_annotations(
3812        self: Handle<Self>,
3813        app: &App,
3814        result: &mut AnnotationSearch,
3815        local_position: Offset,
3816        only_first: bool,
3817    ) -> bool {
3818        let mut is_absorbed =
3819            ContainerLayer::find_annotations(self, app, result, local_position, only_first);
3820        if !result.is_empty() && only_first {
3821            return is_absorbed;
3822        }
3823        let (value, size, offset, opaque) = {
3824            let this = app.get(self);
3825            (Rc::clone(&this.value), this.size, this.offset, this.opaque)
3826        };
3827        if let Some(size) = size
3828            && !(offset & size).contains(local_position)
3829        {
3830            return is_absorbed;
3831        }
3832        if result.accepts(&*value) {
3833            is_absorbed = is_absorbed || opaque;
3834            result.add(value, local_position - offset);
3835        }
3836        is_absorbed
3837    }
3838
3839    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
3840        ContainerLayer::add_to_scene(self, app, builder);
3841    }
3842
3843    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
3844        ContainerLayer::fire_composition_callbacks(self, app, include_children);
3845    }
3846}
3847
3848impl ContainerLayer for AnnotatedRegionLayer {
3849    crate::container_layer_accessors!();
3850}
3851
3852#[cfg(test)]
3853mod tests {
3854    use inset_foundation::AppCell;
3855
3856    use super::*;
3857
3858    fn offset_layer(app: &mut App) -> AnyLayer {
3859        OffsetLayer::new(app, Offset::ZERO).as_layer()
3860    }
3861
3862    #[test]
3863    fn append_links_children_in_order_and_adopts_them() {
3864        let cell = AppCell::new();
3865        let mut app = cell.borrow_mut();
3866        let parent = OffsetLayer::new(&mut app, Offset::ZERO).as_container_layer();
3867        let a = offset_layer(&mut app);
3868        let b = offset_layer(&mut app);
3869        parent.append(&mut app, a);
3870        parent.append(&mut app, b);
3871        assert_eq!(parent.first_child(&app), Some(a));
3872        assert_eq!(parent.last_child(&app), Some(b));
3873        assert_eq!(a.next_sibling(&app), Some(b));
3874        assert_eq!(b.previous_sibling(&app), Some(a));
3875        assert_eq!(a.parent(&app), Some(parent));
3876        assert_eq!(a.depth(&app), 1);
3877        assert_eq!(a.debug_handle_count(&app), 1, "the parent handle");
3878    }
3879
3880    #[test]
3881    fn a_layer_is_disposed_when_its_last_handle_is_released() {
3882        let cell = AppCell::new();
3883        let mut app = cell.borrow_mut();
3884        let layer = offset_layer(&mut app);
3885        let handle = app.create(LayerHandle::<AnyLayer>::new());
3886        LayerHandle::set_layer(&mut app, |app| app.get_mut(handle), Some(layer));
3887        assert_eq!(layer.debug_handle_count(&app), 1);
3888        LayerHandle::set_layer(&mut app, |app| app.get_mut(handle), None);
3889        assert!(layer.debug_disposed(&app));
3890        assert!(
3891            !app.contains(layer.id()),
3892            "dispose destroys the arena entry"
3893        );
3894    }
3895
3896    #[test]
3897    fn removing_a_child_releases_the_parent_handle_and_disposes_it() {
3898        let cell = AppCell::new();
3899        let mut app = cell.borrow_mut();
3900        let parent = OffsetLayer::new(&mut app, Offset::ZERO).as_container_layer();
3901        let child = offset_layer(&mut app);
3902        parent.append(&mut app, child);
3903        child.remove(&mut app);
3904        assert!(!parent.has_children(&app));
3905        assert!(child.debug_disposed(&app));
3906    }
3907
3908    #[test]
3909    fn a_child_kept_by_another_handle_survives_removal() {
3910        let cell = AppCell::new();
3911        let mut app = cell.borrow_mut();
3912        let parent = OffsetLayer::new(&mut app, Offset::ZERO).as_container_layer();
3913        let child = offset_layer(&mut app);
3914        let handle = app.create(LayerHandle::<AnyLayer>::new());
3915        LayerHandle::set_layer(&mut app, |app| app.get_mut(handle), Some(child));
3916        parent.append(&mut app, child);
3917        child.remove(&mut app);
3918        assert!(!child.debug_disposed(&app));
3919        assert_eq!(child.parent(&app), None);
3920        LayerHandle::set_layer(&mut app, |app| app.get_mut(handle), None);
3921        assert!(child.debug_disposed(&app));
3922    }
3923
3924    #[test]
3925    fn attach_and_detach_walk_the_subtree() {
3926        let cell = AppCell::new();
3927        let mut app = cell.borrow_mut();
3928        let owner = app.create(());
3929        let root = OffsetLayer::new(&mut app, Offset::ZERO).as_container_layer();
3930        let child = offset_layer(&mut app);
3931        root.append(&mut app, child);
3932        root.as_layer().attach(&mut app, owner.id());
3933        assert!(child.attached(&app));
3934        let late = offset_layer(&mut app);
3935        root.append(&mut app, late);
3936        assert!(
3937            late.attached(&app),
3938            "appending to an attached tree attaches"
3939        );
3940        root.as_layer().detach(&mut app);
3941        assert!(!child.attached(&app));
3942        assert!(!late.attached(&app));
3943    }
3944
3945    #[test]
3946    fn disposing_a_container_disposes_children_it_alone_held() {
3947        let cell = AppCell::new();
3948        let mut app = cell.borrow_mut();
3949        let parent = OffsetLayer::new(&mut app, Offset::ZERO).as_container_layer();
3950        let child = offset_layer(&mut app);
3951        parent.append(&mut app, child);
3952        let handle = app.create(LayerHandle::<AnyContainerLayer>::new());
3953        LayerHandle::set_layer(&mut app, |app| app.get_mut(handle), Some(parent));
3954        LayerHandle::set_layer(&mut app, |app| app.get_mut(handle), None);
3955        assert!(parent.as_layer().debug_disposed(&app));
3956        assert!(child.debug_disposed(&app));
3957    }
3958
3959    #[test]
3960    fn a_picture_layer_is_a_leaf_that_holds_its_picture() {
3961        let cell = AppCell::new();
3962        let mut app = cell.borrow_mut();
3963        let layer = PictureLayer::new(&mut app, Rect::from_ltwh(0.0, 0.0, 10.0, 10.0));
3964        let picture = Arc::new(inset_embedder::Canvas::new().build());
3965        layer.set_picture(&mut app, Some(picture));
3966        assert!(layer.picture(&app).is_some());
3967        assert!(layer.as_layer().as_container_layer().is_none());
3968        let mut builder = SceneBuilder::new();
3969        layer.as_layer().add_to_scene(&mut app, &mut builder);
3970        let _scene = builder.build();
3971    }
3972
3973    #[test]
3974    fn composition_callbacks_fire_on_build_scene_and_detach() {
3975        use std::cell::Cell;
3976        let cell = AppCell::new();
3977        let mut app = cell.borrow_mut();
3978        let owner = app.create(());
3979        let root = OffsetLayer::new(&mut app, Offset::ZERO).as_container_layer();
3980        let child = offset_layer(&mut app);
3981        root.append(&mut app, child);
3982        let fired = Rc::new(Cell::new(0));
3983        let remove = {
3984            let fired = Rc::clone(&fired);
3985            child
3986                .add_composition_callback(&mut app, Rc::new(move |_, _| fired.set(fired.get() + 1)))
3987        };
3988        assert!(root.as_layer().subtree_has_composition_callbacks(&app));
3989        let _scene = root.build_scene(&mut app, SceneBuilder::new());
3990        assert_eq!(fired.get(), 1);
3991        root.as_layer().attach(&mut app, owner.id());
3992        root.as_layer().detach(&mut app);
3993        assert_eq!(fired.get(), 2, "detach fires once more");
3994        remove(&mut app);
3995        assert!(!root.as_layer().subtree_has_composition_callbacks(&app));
3996    }
3997
3998    #[test]
3999    fn find_walks_children_back_to_front_through_offsets() {
4000        struct Tag(&'static str);
4001        struct Annotated {
4002            layer: LayerData,
4003            tag: Rc<Tag>,
4004        }
4005        impl Layer for Annotated {
4006            crate::layer_accessors!();
4007            fn find_annotations(
4008                self: Handle<Self>,
4009                app: &App,
4010                result: &mut AnnotationSearch,
4011                local_position: Offset,
4012                _only_first: bool,
4013            ) -> bool {
4014                let tag = Rc::clone(&app.get(self).tag);
4015                if result.accepts(&*tag) {
4016                    result.add(tag, local_position);
4017                }
4018                false
4019            }
4020            fn add_to_scene(self: Handle<Self>, _app: &mut App, _builder: &mut SceneBuilder) {}
4021        }
4022        let cell = AppCell::new();
4023        let mut app = cell.borrow_mut();
4024        let root = OffsetLayer::new(&mut app, Offset::new(10.0, 0.0)).as_container_layer();
4025        for name in ["back", "front"] {
4026            let layer = app.create(Annotated {
4027                layer: LayerData::new(),
4028                tag: Rc::new(Tag(name)),
4029            });
4030            root.append(&mut app, layer.as_layer());
4031        }
4032        let found = root.as_layer().find::<Tag>(&app, Offset::new(15.0, 5.0));
4033        assert_eq!(found.map(|tag| tag.0), Some("front"));
4034        let all = root
4035            .as_layer()
4036            .find_all_annotations::<Tag>(&app, Offset::new(15.0, 5.0));
4037        assert_eq!(all.entries().len(), 2);
4038        assert_eq!(all.entries()[0].local_position, Offset::new(5.0, 5.0));
4039        assert!(root.as_layer().find::<String>(&app, Offset::ZERO).is_none());
4040    }
4041
4042    /// An opacity layer over one leaf under a root, with a frame's scene built: the shape
4043    /// retained rendering acts on.
4044    /// A picture layer that draws a square: content a scene keeps, where it
4045    /// drops a subtree that draws nothing.
4046    fn drawn_layer(app: &mut App) -> AnyLayer {
4047        let square = Rect::from_ltwh(0.0, 0.0, 10.0, 10.0);
4048        let mut canvas = inset_embedder::Canvas::new();
4049        canvas.draw_rect(square, &inset_embedder::Paint::default());
4050        let layer = PictureLayer::new(app, square);
4051        layer.set_picture(app, Some(Arc::new(canvas.build())));
4052        layer.as_layer()
4053    }
4054
4055    fn retained_tree(app: &mut App) -> (Handle<OffsetLayer>, Handle<OpacityLayer>) {
4056        let root = OffsetLayer::new(app, Offset::ZERO);
4057        let opacity = OpacityLayer::new(app);
4058        opacity.set_alpha(app, 128);
4059        let leaf = drawn_layer(app);
4060        opacity.as_container_layer().append(app, leaf);
4061        root.as_container_layer().append(app, opacity.as_layer());
4062        let _scene = root
4063            .as_container_layer()
4064            .build_scene(app, SceneBuilder::new());
4065        (root, opacity)
4066    }
4067
4068    #[test]
4069    fn a_surface_layer_places_its_surface_under_its_offset_every_frame() {
4070        let cell = AppCell::new();
4071        let mut app = cell.borrow_mut();
4072        let root = OffsetLayer::new(&mut app, Offset::new(10.0, 5.0));
4073        let surface = inset_embedder::test_support::idle_surface();
4074        let layer = SurfaceLayer::new(
4075            &mut app,
4076            Arc::clone(&surface),
4077            Rect::from_ltwh(1.0, 2.0, 30.0, 20.0),
4078        );
4079        root.as_container_layer().append(&mut app, layer.as_layer());
4080        for _frame in 0..2 {
4081            let scene = root
4082                .as_container_layer()
4083                .build_scene(&mut app, SceneBuilder::new());
4084            assert_eq!(
4085                scene.surfaces,
4086                [inset_embedder::SurfacePlacement {
4087                    surface: Arc::clone(&surface),
4088                    rect: Rect::from_ltwh(11.0, 7.0, 30.0, 20.0),
4089                    scale: 1.0,
4090                    clip: Rect::from_ltwh(11.0, 7.0, 30.0, 20.0),
4091                }]
4092            );
4093        }
4094        assert!(layer.as_layer().always_needs_add_to_scene(&app));
4095    }
4096
4097    #[test]
4098    fn an_unchanged_subtree_is_retained_across_scenes() {
4099        let cell = AppCell::new();
4100        let mut app = cell.borrow_mut();
4101        let (root, opacity) = retained_tree(&mut app);
4102        let recorded = opacity.as_layer().engine_layer(&app).expect("recorded");
4103        assert!(!opacity.as_layer().needs_add_to_scene(&app));
4104
4105        let scene = root
4106            .as_container_layer()
4107            .build_scene(&mut app, SceneBuilder::new());
4108        let retained = opacity.as_layer().engine_layer(&app).expect("recorded");
4109        assert!(
4110            Arc::ptr_eq(&recorded, &retained),
4111            "the same list is retained"
4112        );
4113        let root_list = root
4114            .as_layer()
4115            .engine_layer(&app)
4116            .expect("the root re-records");
4117        assert!(
4118            root_list.ops().iter().any(|op| matches!(
4119                op,
4120                inset_embedder::valo::Op::DrawDisplayList { list, .. } if Arc::ptr_eq(list, &retained)
4121            )),
4122            "embedded again: {:?}",
4123            root_list.ops()
4124        );
4125        assert_eq!(
4126            inset_embedder::flattened_ops(&scene.picture)
4127                .iter()
4128                .filter(|op| matches!(op, inset_embedder::valo::Op::SaveLayer { .. }))
4129                .count(),
4130            1,
4131            "the retained opacity layer still draws"
4132        );
4133    }
4134
4135    #[test]
4136    fn a_changed_property_re_records_the_subtree() {
4137        let cell = AppCell::new();
4138        let mut app = cell.borrow_mut();
4139        let (root, opacity) = retained_tree(&mut app);
4140        let recorded = opacity.as_layer().engine_layer(&app).expect("recorded");
4141
4142        opacity.set_alpha(&mut app, 200);
4143        assert!(opacity.as_layer().needs_add_to_scene(&app));
4144        let _scene = root
4145            .as_container_layer()
4146            .build_scene(&mut app, SceneBuilder::new());
4147        let again = opacity.as_layer().engine_layer(&app).expect("recorded");
4148        assert!(
4149            !Arc::ptr_eq(&recorded, &again),
4150            "a new list for the new alpha"
4151        );
4152        assert!(!opacity.as_layer().needs_add_to_scene(&app));
4153    }
4154
4155    #[test]
4156    fn appending_a_child_marks_the_parent_and_its_ancestors_at_build() {
4157        let cell = AppCell::new();
4158        let mut app = cell.borrow_mut();
4159        let (root, opacity) = retained_tree(&mut app);
4160        assert!(!root.as_layer().needs_add_to_scene(&app));
4161
4162        let leaf = offset_layer(&mut app);
4163        opacity.as_container_layer().append(&mut app, leaf);
4164        assert!(opacity.as_layer().needs_add_to_scene(&app));
4165        assert!(
4166            !root.as_layer().needs_add_to_scene(&app),
4167            "the mark does not climb until the scene is built"
4168        );
4169        root.as_layer().update_subtree_needs_add_to_scene(&mut app);
4170        assert!(root.as_layer().needs_add_to_scene(&app));
4171    }
4172
4173    #[test]
4174    fn a_follower_layer_always_re_records() {
4175        let cell = AppCell::new();
4176        let mut app = cell.borrow_mut();
4177        let link = LayerLink::new(&mut app);
4178        let follower = FollowerLayer::new(&mut app, link);
4179        let child = offset_layer(&mut app);
4180        follower.as_container_layer().append(&mut app, child);
4181        for _ in 0..2 {
4182            let _scene = follower
4183                .as_container_layer()
4184                .build_scene(&mut app, SceneBuilder::new());
4185            assert!(
4186                follower.as_layer().needs_add_to_scene(&app)
4187                    || follower.as_layer().always_needs_add_to_scene(&app)
4188            );
4189        }
4190        let first = follower.as_layer().engine_layer(&app).expect("recorded");
4191        let _scene = follower
4192            .as_container_layer()
4193            .build_scene(&mut app, SceneBuilder::new());
4194        let second = follower.as_layer().engine_layer(&app).expect("recorded");
4195        assert!(!Arc::ptr_eq(&first, &second), "never retained");
4196    }
4197
4198    fn tag(app: &mut App, n: u32) -> Handle<AnnotatedRegionLayer> {
4199        AnnotatedRegionLayer::new(app, Rc::new(n))
4200    }
4201
4202    #[test]
4203    fn clip_layers_reject_annotations_outside_the_clip() {
4204        let cell = AppCell::new();
4205        let mut app = cell.borrow_mut();
4206        let rect = ClipRectLayer::new(&mut app);
4207        rect.set_clip_rect(&mut app, Some(Rect::from_ltwh(0.0, 0.0, 50.0, 50.0)));
4208        let child = tag(&mut app, 7);
4209        rect.as_container_layer().append(&mut app, child.as_layer());
4210        assert_eq!(
4211            rect.as_layer()
4212                .find::<u32>(&app, Offset::new(10.0, 10.0))
4213                .as_deref(),
4214            Some(&7)
4215        );
4216        assert!(
4217            rect.as_layer()
4218                .find::<u32>(&app, Offset::new(60.0, 10.0))
4219                .is_none(),
4220            "outside the clip"
4221        );
4222
4223        let rrect = ClipRRectLayer::new(&mut app);
4224        rrect.set_clip_rrect(
4225            &mut app,
4226            Some(RRect::from_rect_and_radius(
4227                Rect::from_ltwh(0.0, 0.0, 50.0, 50.0),
4228                inset_embedder::Radius::circular(4.0),
4229            )),
4230        );
4231        let child = tag(&mut app, 8);
4232        rrect
4233            .as_container_layer()
4234            .append(&mut app, child.as_layer());
4235        assert_eq!(
4236            rrect
4237                .as_layer()
4238                .find::<u32>(&app, Offset::new(10.0, 10.0))
4239                .as_deref(),
4240            Some(&8)
4241        );
4242        assert!(
4243            rrect
4244                .as_layer()
4245                .find::<u32>(&app, Offset::new(60.0, 10.0))
4246                .is_none()
4247        );
4248
4249        let mut path = inset_embedder::PathBuilder::new();
4250        path.rect(Rect::from_ltwh(0.0, 0.0, 50.0, 50.0).into());
4251        let clip_path = ClipPathLayer::new(&mut app);
4252        clip_path.set_clip_path(&mut app, Some(path.build()));
4253        let child = tag(&mut app, 9);
4254        clip_path
4255            .as_container_layer()
4256            .append(&mut app, child.as_layer());
4257        assert_eq!(
4258            clip_path
4259                .as_layer()
4260                .find::<u32>(&app, Offset::new(10.0, 10.0))
4261                .as_deref(),
4262            Some(&9)
4263        );
4264        assert!(
4265            clip_path
4266                .as_layer()
4267                .find::<u32>(&app, Offset::new(60.0, 10.0))
4268                .is_none()
4269        );
4270    }
4271
4272    #[test]
4273    fn transform_layer_transforms_the_annotation_position() {
4274        let cell = AppCell::new();
4275        let mut app = cell.borrow_mut();
4276        let layer = TransformLayer::new(&mut app);
4277        layer.set_transform(&mut app, Matrix4::translation(10.0, 0.0));
4278        let region = tag(&mut app, 7);
4279        region.set_size(&mut app, Some(Size::new(20.0, 20.0)));
4280        layer
4281            .as_container_layer()
4282            .append(&mut app, region.as_layer());
4283        assert!(
4284            layer
4285                .as_layer()
4286                .find::<u32>(&app, Offset::new(15.0, 5.0))
4287                .is_some()
4288        );
4289        assert!(
4290            layer
4291                .as_layer()
4292                .find::<u32>(&app, Offset::new(5.0, 5.0))
4293                .is_none(),
4294            "left of the translated region"
4295        );
4296    }
4297
4298    #[test]
4299    fn opacity_layer_build_scene_succeeds_at_255_and_128() {
4300        let cell = AppCell::new();
4301        let mut app = cell.borrow_mut();
4302        for alpha in [255, 128] {
4303            let layer = OpacityLayer::new(&mut app);
4304            layer.set_alpha(&mut app, alpha);
4305            let child = OffsetLayer::new(&mut app, Offset::ZERO);
4306            layer
4307                .as_container_layer()
4308                .append(&mut app, child.as_layer());
4309            let _scene = layer
4310                .as_container_layer()
4311                .build_scene(&mut app, SceneBuilder::new());
4312        }
4313        let empty = OpacityLayer::new(&mut app);
4314        empty.set_alpha(&mut app, 128);
4315        let _scene = empty
4316            .as_container_layer()
4317            .build_scene(&mut app, SceneBuilder::new());
4318    }
4319
4320    #[test]
4321    fn layer_link_register_unregister_and_leader_getter() {
4322        let cell = AppCell::new();
4323        let mut app = cell.borrow_mut();
4324        let owner = app.create(());
4325        let link = LayerLink::new(&mut app);
4326        assert!(link.leader(&app).is_none());
4327        let leader = LeaderLayer::new(&mut app, link);
4328        leader.as_layer().attach(&mut app, owner.id());
4329        assert_eq!(link.leader(&app), Some(leader));
4330        leader.as_layer().detach(&mut app);
4331        assert!(link.leader(&app).is_none());
4332    }
4333
4334    #[test]
4335    fn leader_layer_attach_registers_and_detach_unregisters() {
4336        let cell = AppCell::new();
4337        let mut app = cell.borrow_mut();
4338        let owner = app.create(());
4339        let root = OffsetLayer::new(&mut app, Offset::ZERO);
4340        let link = LayerLink::new(&mut app);
4341        let leader = LeaderLayer::new(&mut app, link);
4342        root.as_container_layer()
4343            .append(&mut app, leader.as_layer());
4344        root.as_layer().attach(&mut app, owner.id());
4345        assert_eq!(link.leader(&app), Some(leader));
4346        root.as_layer().detach(&mut app);
4347        assert!(link.leader(&app).is_none());
4348    }
4349
4350    #[test]
4351    fn a_replaced_leader_leaves_the_links_new_leader_in_place() {
4352        let cell = AppCell::new();
4353        let mut app = cell.borrow_mut();
4354        let owner = app.create(());
4355        let link = LayerLink::new(&mut app);
4356        let leader1 = LeaderLayer::new(&mut app, link);
4357        let leader2 = LeaderLayer::new(&mut app, link);
4358        leader1.as_layer().attach(&mut app, owner.id());
4359        leader2.as_layer().attach(&mut app, owner.id());
4360        assert_eq!(link.leader(&app), Some(leader2));
4361        leader2.as_layer().detach(&mut app);
4362        leader1.as_layer().detach(&mut app);
4363        assert!(link.leader(&app).is_none());
4364    }
4365
4366    #[test]
4367    fn switching_the_link_of_an_attached_leader_does_not_crash() {
4368        let cell = AppCell::new();
4369        let mut app = cell.borrow_mut();
4370        let owner = app.create(());
4371        let link = LayerLink::new(&mut app);
4372        let leader = LeaderLayer::new(&mut app, link);
4373        leader.as_layer().attach(&mut app, owner.id());
4374        let link2 = LayerLink::new(&mut app);
4375        leader.set_link(&mut app, link2);
4376        leader.as_layer().detach(&mut app);
4377        assert_eq!(leader.link(&app), link2);
4378        assert!(link.leader(&app).is_none());
4379        assert!(link2.leader(&app).is_none());
4380    }
4381
4382    #[test]
4383    fn follower_get_last_transform_after_build_scene_matches_the_leader_offset() {
4384        let cell = AppCell::new();
4385        let mut app = cell.borrow_mut();
4386        let owner = app.create(());
4387        let root = OffsetLayer::new(&mut app, Offset::ZERO);
4388        let link = LayerLink::new(&mut app);
4389        let leader = LeaderLayer::new(&mut app, link);
4390        leader.set_offset(&mut app, Offset::new(10.0, 20.0));
4391        let follower = FollowerLayer::new(&mut app, link);
4392        root.as_container_layer()
4393            .append(&mut app, leader.as_layer());
4394        root.as_container_layer()
4395            .append(&mut app, follower.as_layer());
4396        root.as_layer().attach(&mut app, owner.id());
4397        let _scene = root
4398            .as_container_layer()
4399            .build_scene(&mut app, SceneBuilder::new());
4400        assert_eq!(
4401            follower.get_last_transform(&app).unwrap(),
4402            Matrix4::translation(10.0, 20.0)
4403        );
4404    }
4405
4406    #[test]
4407    fn follower_with_show_when_unlinked_false_pushes_nothing() {
4408        let cell = AppCell::new();
4409        let mut app = cell.borrow_mut();
4410        let link = LayerLink::new(&mut app);
4411        let follower = FollowerLayer::new(&mut app, link);
4412        follower.set_show_when_unlinked(&mut app, false);
4413        let child = offset_layer(&mut app);
4414        follower.as_container_layer().append(&mut app, child);
4415        let _scene = follower
4416            .as_container_layer()
4417            .build_scene(&mut app, SceneBuilder::new());
4418        assert!(follower.get_last_transform(&app).is_none());
4419    }
4420
4421    #[test]
4422    fn annotated_region_layer_find_with_size_offset_and_opaque() {
4423        let cell = AppCell::new();
4424        let mut app = cell.borrow_mut();
4425        let root = OffsetLayer::new(&mut app, Offset::ZERO);
4426        let behind = tag(&mut app, 1);
4427        let front = tag(&mut app, 2);
4428        front.set_opaque(&mut app, true);
4429        root.as_container_layer()
4430            .append(&mut app, behind.as_layer());
4431        root.as_container_layer().append(&mut app, front.as_layer());
4432        let result = root
4433            .as_layer()
4434            .find_all_annotations::<u32>(&app, Offset::ZERO);
4435        assert_eq!(
4436            result
4437                .annotations()
4438                .map(|value| **value)
4439                .collect::<Vec<_>>(),
4440            vec![2],
4441            "an opaque region hides its siblings"
4442        );
4443
4444        let root = OffsetLayer::new(&mut app, Offset::ZERO);
4445        let first = tag(&mut app, 1);
4446        let second = tag(&mut app, 2);
4447        root.as_container_layer().append(&mut app, first.as_layer());
4448        root.as_container_layer()
4449            .append(&mut app, second.as_layer());
4450        let result = root
4451            .as_layer()
4452            .find_all_annotations::<u32>(&app, Offset::ZERO);
4453        assert_eq!(
4454            result
4455                .annotations()
4456                .map(|value| **value)
4457                .collect::<Vec<_>>(),
4458            vec![2, 1],
4459            "front to back when neither is opaque"
4460        );
4461
4462        let sized = tag(&mut app, 3);
4463        sized.set_size(&mut app, Some(Size::new(20.0, 20.0)));
4464        sized.set_offset(&mut app, Offset::new(90.0, 90.0));
4465        assert!(
4466            sized
4467                .as_layer()
4468                .find::<u32>(&app, Offset::new(95.0, 95.0))
4469                .is_some()
4470        );
4471        assert!(
4472            sized.as_layer().find::<u32>(&app, Offset::ZERO).is_none(),
4473            "outside the sized region"
4474        );
4475    }
4476}