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//! A layer keeps the [`EngineLayer`] its `add_to_scene` last made, a node of the scene's tree, and
9//! hands it to [`SceneBuilder::add_retained`] while nothing in its subtree changed, as Flutter's
10//! retained rendering does (`_needsAddToScene`, `markNeedsAddToScene`, `alwaysNeedsAddToScene`,
11//! `engineLayer`).
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 node this layer's subtree made when it was last added to a scene, 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 node of the scene's tree its subtree made
856    /// when it was last added to a scene, which [`SceneBuilder::add_retained`] adds again while
857    /// nothing 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 build a new engine layer to add this one to, 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, retained with its ancestors like any other: the scene keeps it
1159/// as a layer of its own, and a host places the surface from the tree every frame.
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 add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
1190        let this = app.get(self);
1191        builder.add_surface(Arc::clone(&this.surface), this.rect);
1192    }
1193
1194    fn find_annotations(
1195        self: Handle<Self>,
1196        _app: &App,
1197        _result: &mut AnnotationSearch,
1198        _local_position: Offset,
1199        _only_first: bool,
1200    ) -> bool {
1201        false
1202    }
1203}
1204
1205/// Flutter's `ContainerLayer` fields, held under the field `container_layer`
1206/// ([`container_layer_accessors!`]).
1207#[derive(Debug, Default)]
1208pub struct ContainerLayerData {
1209    first_child: Option<AnyLayer>,
1210    last_child: Option<AnyLayer>,
1211}
1212
1213impl ContainerLayerData {
1214    /// No children.
1215    pub const fn new() -> ContainerLayerData {
1216        ContainerLayerData {
1217            first_child: None,
1218            last_child: None,
1219        }
1220    }
1221}
1222
1223/// Implements the [`ContainerLayer`] field accessors for a `container_layer` field.
1224///
1225/// `container_layer_accessors!(offset)` also records that the type `extends OffsetLayer`, so
1226/// its [`AnyContainerLayer`] can be narrowed with [`AnyContainerLayer::as_offset_layer`].
1227#[macro_export]
1228macro_rules! container_layer_accessors {
1229    () => {
1230        fn container_layer_data(
1231            self: ::inset_foundation::Handle<Self>,
1232            app: &::inset_foundation::App,
1233        ) -> &$crate::ContainerLayerData {
1234            &app.get(self).container_layer
1235        }
1236        fn container_layer_data_mut(
1237            self: ::inset_foundation::Handle<Self>,
1238            app: &mut ::inset_foundation::App,
1239        ) -> &mut $crate::ContainerLayerData {
1240            &mut app.get_mut(self).container_layer
1241        }
1242    };
1243    (offset) => {
1244        $crate::container_layer_accessors!();
1245        const AS_OFFSET: Option<fn() -> &'static $crate::OffsetLayerVTable> =
1246            Some(|| const { &$crate::OffsetLayerVTable::of::<Self>() });
1247    };
1248}
1249
1250/// A composited layer that has a list of children.
1251///
1252/// A [`ContainerLayer`] instance merely takes a list of children and inserts them into the
1253/// composited rendering in order. There are subclasses of [`ContainerLayer`] which apply more
1254/// elaborate effects in the process.
1255///
1256/// Flutter's `ContainerLayer`: the child list lives on [`AnyContainerLayer`]; this trait holds
1257/// the virtual `apply_transform` and the bodies of the `Layer` methods it overrides. A leaf's
1258/// `impl Layer` forwards to them: `fn attach(..) { ContainerLayer::attach(self, app, owner) }`.
1259pub trait ContainerLayer: Layer {
1260    /// Mixin field access.
1261    fn container_layer_data(self: Handle<Self>, app: &App) -> &ContainerLayerData;
1262
1263    /// See [`container_layer_data`](Self::container_layer_data).
1264    fn container_layer_data_mut(self: Handle<Self>, app: &mut App) -> &mut ContainerLayerData;
1265
1266    /// The offset table when this type `extends OffsetLayer`;
1267    /// `container_layer_accessors!(offset)` sets it. Dart's `layer is OffsetLayer`.
1268    const AS_OFFSET: Option<fn() -> &'static OffsetLayerVTable> = None;
1269
1270    /// Dart's implicit upcast of a concrete layer to `ContainerLayer`.
1271    fn as_container_layer(self: Handle<Self>) -> AnyContainerLayer {
1272        AnyContainerLayer {
1273            id: self.id(),
1274            vtable: const { &ContainerLayerVTable::of::<Self>() },
1275        }
1276    }
1277
1278    /// Applies the transform that would be applied when compositing the given child to the
1279    /// given matrix.
1280    ///
1281    /// Specifically, this should apply the transform that is applied to child's _origin_. When
1282    /// using `apply_transform` with a chain of layers, results will be unreliable unless the
1283    /// deepest layer in the chain collapses the `layerOffset` in `add_to_scene` to zero, meaning
1284    /// that it passes [`Offset::ZERO`] to its children, and bakes any incoming `layerOffset` into
1285    /// the [`SceneBuilder`] as (for instance) a transform (which is then also included in the
1286    /// transformation applied by `apply_transform`).
1287    ///
1288    /// This method is only valid immediately after `add_to_scene` has been called, before any of
1289    /// the properties have been changed.
1290    ///
1291    /// The default implementation does nothing, since [`ContainerLayer`], by default, composites
1292    /// its children at the origin of the [`ContainerLayer`] itself.
1293    ///
1294    /// The `child` argument should generally not be `None`, since in principle a layer could
1295    /// transform each child independently. However, certain layers may explicitly allow `None`
1296    /// as a value, for example if they know that they transform all their children identically.
1297    ///
1298    /// Used by `FollowerLayer` to transform its child to a `LeaderLayer`'s position.
1299    fn apply_transform(
1300        self: Handle<Self>,
1301        app: &App,
1302        child: Option<AnyLayer>,
1303        transform: &mut Matrix4,
1304    ) {
1305        let _ = (self, app, transform);
1306        debug_assert!(child.is_some());
1307    }
1308
1309    /// `ContainerLayer._fireCompositionCallbacks`.
1310    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
1311        LayerBase::fire_composition_callbacks(self, app, include_children);
1312        if !include_children {
1313            return;
1314        }
1315        let mut child = self.as_container_layer().first_child(app);
1316        while let Some(layer) = child {
1317            layer.fire_composition_callbacks(app, include_children);
1318            child = layer.next_sibling(app);
1319        }
1320    }
1321
1322    /// `ContainerLayer.supportsRasterization`.
1323    fn supports_rasterization(self: Handle<Self>, app: &App) -> bool {
1324        let mut child = self.as_container_layer().last_child(app);
1325        while let Some(layer) = child {
1326            if !layer.supports_rasterization(app) {
1327                return false;
1328            }
1329            child = layer.previous_sibling(app);
1330        }
1331        true
1332    }
1333
1334    /// `ContainerLayer.dispose`.
1335    fn dispose(self: Handle<Self>, app: &mut App) {
1336        self.as_container_layer().remove_all_children(app);
1337        self.layer_data_mut(app).callbacks.clear();
1338        LayerBase::dispose(self, app);
1339    }
1340
1341    /// `ContainerLayer.findAnnotations`.
1342    fn find_annotations(
1343        self: Handle<Self>,
1344        app: &App,
1345        result: &mut AnnotationSearch,
1346        local_position: Offset,
1347        only_first: bool,
1348    ) -> bool {
1349        let mut child = self.as_container_layer().last_child(app);
1350        while let Some(layer) = child {
1351            let is_absorbed = layer.find_annotations(app, result, local_position, only_first);
1352            if is_absorbed {
1353                return true;
1354            }
1355            if only_first && !result.is_empty() {
1356                return is_absorbed;
1357            }
1358            child = layer.previous_sibling(app);
1359        }
1360        false
1361    }
1362
1363    /// `ContainerLayer.attach`.
1364    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
1365        debug_assert!(!self.layer_data(app).debug_mutations_locked);
1366        LayerBase::attach(self, app, owner);
1367        let mut child = self.as_container_layer().first_child(app);
1368        while let Some(layer) = child {
1369            layer.attach(app, owner);
1370            child = layer.next_sibling(app);
1371        }
1372    }
1373
1374    /// `ContainerLayer.detach`.
1375    fn detach(self: Handle<Self>, app: &mut App) {
1376        debug_assert!(!self.layer_data(app).debug_mutations_locked);
1377        LayerBase::detach(self, app);
1378        let mut child = self.as_container_layer().first_child(app);
1379        while let Some(layer) = child {
1380            layer.detach(app);
1381            child = layer.next_sibling(app);
1382        }
1383        // Detach indicates that we may never be composited again. Clients
1384        // interested in observing composition need to get an update here because
1385        // they might otherwise never get another one even though the layer is no
1386        // longer visible.
1387        //
1388        // Children fired them already in child.detach().
1389        self.as_layer().fire_composition_callbacks(app, false);
1390    }
1391
1392    /// `ContainerLayer.redepthChildren`.
1393    fn redepth_children(self: Handle<Self>, app: &mut App) {
1394        let this = self.as_container_layer();
1395        let mut child = this.first_child(app);
1396        while let Some(layer) = child {
1397            this.redepth_child(app, layer);
1398            child = layer.next_sibling(app);
1399        }
1400    }
1401
1402    /// `ContainerLayer.addToScene`.
1403    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
1404        self.as_container_layer()
1405            .add_children_to_scene(app, builder);
1406    }
1407}
1408
1409/// The vtable of an [`AnyContainerLayer`]: the layer vtable plus the container accessors.
1410///
1411/// Public only so [`layer_accessors!`] can name it from another crate.
1412#[doc(hidden)]
1413pub struct ContainerLayerVTable {
1414    layer: LayerVTable,
1415    container_data: fn(&App, HandleId) -> &ContainerLayerData,
1416    container_data_mut: fn(&mut App, HandleId) -> &mut ContainerLayerData,
1417    apply_transform: fn(&App, HandleId, Option<AnyLayer>, &mut Matrix4),
1418    as_offset: Option<fn() -> &'static OffsetLayerVTable>,
1419}
1420
1421impl ContainerLayerVTable {
1422    pub const fn of<T: ContainerLayer>() -> ContainerLayerVTable {
1423        ContainerLayerVTable {
1424            layer: LayerVTable::of::<T>(),
1425            container_data: |app, id| T::container_layer_data(resolve(id), app),
1426            container_data_mut: |app, id| T::container_layer_data_mut(resolve(id), app),
1427            apply_transform: |app, id, child, transform| {
1428                T::apply_transform(resolve(id), app, child, transform)
1429            },
1430            as_offset: T::AS_OFFSET,
1431        }
1432    }
1433}
1434
1435/// Erased `ContainerLayer`.
1436#[derive(Clone, Copy)]
1437pub struct AnyContainerLayer {
1438    id: HandleId,
1439    vtable: &'static ContainerLayerVTable,
1440}
1441
1442impl PartialEq for AnyContainerLayer {
1443    fn eq(&self, other: &AnyContainerLayer) -> bool {
1444        self.id == other.id
1445    }
1446}
1447
1448impl Eq for AnyContainerLayer {}
1449
1450impl Hash for AnyContainerLayer {
1451    fn hash<H: Hasher>(&self, state: &mut H) {
1452        self.id.hash(state);
1453    }
1454}
1455
1456impl From<AnyContainerLayer> for HandleId {
1457    fn from(layer: AnyContainerLayer) -> HandleId {
1458        layer.id
1459    }
1460}
1461
1462impl Debug for AnyContainerLayer {
1463    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1464        write!(f, "AnyContainerLayer({:?})", self.id)
1465    }
1466}
1467
1468impl ErasedLayer for AnyContainerLayer {
1469    fn as_layer(self) -> AnyLayer {
1470        AnyLayer {
1471            id: self.id,
1472            vtable: &self.vtable.layer,
1473        }
1474    }
1475}
1476
1477impl AnyContainerLayer {
1478    fn from_vtable(id: HandleId, vtable: &'static ContainerLayerVTable) -> AnyContainerLayer {
1479        AnyContainerLayer { id, vtable }
1480    }
1481
1482    pub fn id(self) -> HandleId {
1483        self.id
1484    }
1485
1486    /// Dart's `layer as OffsetLayer`, as an `Option`.
1487    pub fn as_offset_layer(self) -> Option<AnyOffsetLayer> {
1488        self.vtable
1489            .as_offset
1490            .map(|vtable| AnyOffsetLayer::from_vtable(self.id, vtable()))
1491    }
1492
1493    fn data(self, app: &App) -> &ContainerLayerData {
1494        (self.vtable.container_data)(app, self.id)
1495    }
1496
1497    fn data_mut(self, app: &mut App) -> &mut ContainerLayerData {
1498        (self.vtable.container_data_mut)(app, self.id)
1499    }
1500
1501    /// The first composited layer in this layer's child list.
1502    pub fn first_child(self, app: &App) -> Option<AnyLayer> {
1503        self.data(app).first_child
1504    }
1505
1506    /// The last composited layer in this layer's child list.
1507    pub fn last_child(self, app: &App) -> Option<AnyLayer> {
1508        self.data(app).last_child
1509    }
1510
1511    /// Returns whether this layer has at least one child layer.
1512    pub fn has_children(self, app: &App) -> bool {
1513        self.data(app).first_child.is_some()
1514    }
1515
1516    /// Consider this layer as the root and build a scene (a tree of layers) in the engine.
1517    // The reason this method is in the `ContainerLayer` class rather than
1518    // `PipelineOwner` or other singleton level is because this method can be used
1519    // both to render the whole layer tree (e.g. a normal application frame) and
1520    // to render a subtree (e.g. `OffsetLayer.toImage`).
1521    pub fn build_scene(self, app: &mut App, mut builder: SceneBuilder) -> Scene {
1522        let this = self.as_layer();
1523        this.update_subtree_needs_add_to_scene(app);
1524        this.add_to_scene(app, &mut builder);
1525        if this.subtree_has_composition_callbacks(app) {
1526            this.fire_composition_callbacks(app, true);
1527        }
1528        // Clearing the flag after `add_to_scene`, not before: it calls the children's, which
1529        // may mark this layer.
1530        this.data_mut(app).needs_add_to_scene = false;
1531        builder.build()
1532    }
1533
1534    fn debug_ultimate_previous_sibling_of(
1535        self,
1536        app: &App,
1537        mut child: AnyLayer,
1538        equals: Option<AnyLayer>,
1539    ) -> bool {
1540        let attached = self.as_layer().attached(app);
1541        debug_assert!(child.attached(app) == attached);
1542        while let Some(previous) = child.previous_sibling(app) {
1543            debug_assert!(previous != child);
1544            child = previous;
1545            debug_assert!(child.attached(app) == attached);
1546        }
1547        Some(child) == equals
1548    }
1549
1550    fn debug_ultimate_next_sibling_of(
1551        self,
1552        app: &App,
1553        mut child: AnyLayer,
1554        equals: Option<AnyLayer>,
1555    ) -> bool {
1556        let attached = self.as_layer().attached(app);
1557        debug_assert!(child.attached(app) == attached);
1558        while let Some(next) = child.next_sibling(app) {
1559            debug_assert!(next != child);
1560            child = next;
1561            debug_assert!(child.attached(app) == attached);
1562        }
1563        Some(child) == equals
1564    }
1565
1566    /// Adds the given layer to the end of this layer's child list.
1567    pub fn append(self, app: &mut App, child: AnyLayer) {
1568        let this = self.as_layer();
1569        debug_assert!(!this.data(app).debug_mutations_locked);
1570        debug_assert!(child != this);
1571        debug_assert!(Some(child) != self.first_child(app));
1572        debug_assert!(Some(child) != self.last_child(app));
1573        debug_assert!(child.parent(app).is_none());
1574        debug_assert!(!child.attached(app));
1575        debug_assert!(child.next_sibling(app).is_none());
1576        debug_assert!(child.previous_sibling(app).is_none());
1577        debug_assert!(child.data(app).parent_handle.layer().is_none());
1578        debug_assert!(self.debug_root(app) != child); // indicates we are about to create a cycle
1579        self.adopt_child(app, child);
1580        let last_child = self.last_child(app);
1581        child.data_mut(app).previous_sibling = last_child;
1582        if let Some(last_child) = last_child {
1583            last_child.data_mut(app).next_sibling = Some(child);
1584        }
1585        let data = self.data_mut(app);
1586        data.last_child = Some(child);
1587        data.first_child.get_or_insert(child);
1588        LayerHandle::set_layer(
1589            app,
1590            |app| &mut child.data_mut(app).parent_handle,
1591            Some(child),
1592        );
1593        debug_assert!(child.attached(app) == this.attached(app));
1594    }
1595
1596    /// The `assert(() { Layer node = this; while (node.parent != null) … }())` walk of `append`
1597    /// and `_adoptChild`: the root above this layer.
1598    fn debug_root(self, app: &App) -> AnyLayer {
1599        let mut node = self.as_layer();
1600        while let Some(parent) = node.parent(app) {
1601            node = parent.as_layer();
1602        }
1603        node
1604    }
1605
1606    fn adopt_child(self, app: &mut App, child: AnyLayer) {
1607        let this = self.as_layer();
1608        debug_assert!(!this.data(app).debug_mutations_locked);
1609        if !this.always_needs_add_to_scene(app) {
1610            this.mark_needs_add_to_scene(app);
1611        }
1612        let callback_count = child.data(app).composition_callback_count;
1613        if callback_count != 0 {
1614            this.update_subtree_composition_observer_count(app, callback_count);
1615        }
1616        debug_assert!(child.data(app).parent.is_none());
1617        debug_assert!(self.debug_root(app) != child); // indicates we are about to create a cycle
1618        child.data_mut(app).parent = Some(self);
1619        if let Some(owner) = this.owner(app) {
1620            child.attach(app, owner);
1621        }
1622        self.redepth_child(app, child);
1623    }
1624
1625    /// Adjust the depth of the given `child` to be greater than this node's own depth.
1626    ///
1627    /// Only call this method from overrides of [`Layer::redepth_children`].
1628    pub fn redepth_child(self, app: &mut App, child: AnyLayer) {
1629        let this = self.as_layer();
1630        debug_assert!(child.owner(app) == this.owner(app));
1631        let depth = this.depth(app);
1632        if child.depth(app) <= depth {
1633            child.data_mut(app).depth = depth + 1;
1634            child.redepth_children(app);
1635        }
1636    }
1637
1638    // Implementation of [Layer.remove].
1639    pub(crate) fn remove_child(self, app: &mut App, child: AnyLayer) {
1640        let this = self.as_layer();
1641        debug_assert!(child.parent(app) == Some(self));
1642        debug_assert!(child.attached(app) == this.attached(app));
1643        debug_assert!(self.debug_ultimate_previous_sibling_of(app, child, self.first_child(app)));
1644        debug_assert!(self.debug_ultimate_next_sibling_of(app, child, self.last_child(app)));
1645        debug_assert!(child.data(app).parent_handle.layer().is_some());
1646        let previous_sibling = child.previous_sibling(app);
1647        let next_sibling = child.next_sibling(app);
1648        match previous_sibling {
1649            None => {
1650                debug_assert!(self.first_child(app) == Some(child));
1651                self.data_mut(app).first_child = next_sibling;
1652            }
1653            Some(previous) => previous.data_mut(app).next_sibling = next_sibling,
1654        }
1655        match next_sibling {
1656            None => {
1657                debug_assert!(self.last_child(app) == Some(child));
1658                self.data_mut(app).last_child = previous_sibling;
1659            }
1660            Some(next) => next.data_mut(app).previous_sibling = previous_sibling,
1661        }
1662        self.debug_check_child_list(app);
1663        let data = child.data_mut(app);
1664        data.previous_sibling = None;
1665        data.next_sibling = None;
1666        self.drop_child(app, child);
1667        LayerHandle::set_layer(app, |app| &mut child.data_mut(app).parent_handle, None);
1668        // The release may have disposed the child; a disposed layer is detached.
1669        debug_assert!(child.debug_disposed(app) || !child.attached(app));
1670    }
1671
1672    /// The asserts of `_removeChild` after the unlink: the list is consistent end to end.
1673    fn debug_check_child_list(self, app: &App) {
1674        let attached = self.as_layer().attached(app);
1675        let first_child = self.first_child(app);
1676        let last_child = self.last_child(app);
1677        debug_assert!(first_child.is_none() == last_child.is_none());
1678        debug_assert!(first_child.is_none_or(|first| first.attached(app) == attached));
1679        debug_assert!(last_child.is_none_or(|last| last.attached(app) == attached));
1680        debug_assert!(
1681            first_child
1682                .is_none_or(|first| self.debug_ultimate_next_sibling_of(app, first, last_child))
1683        );
1684        debug_assert!(
1685            last_child.is_none_or(|last| self.debug_ultimate_previous_sibling_of(
1686                app,
1687                last,
1688                first_child
1689            ))
1690        );
1691    }
1692
1693    fn drop_child(self, app: &mut App, child: AnyLayer) {
1694        let this = self.as_layer();
1695        debug_assert!(!this.data(app).debug_mutations_locked);
1696        if !this.always_needs_add_to_scene(app) {
1697            this.mark_needs_add_to_scene(app);
1698        }
1699        let callback_count = child.data(app).composition_callback_count;
1700        if callback_count != 0 {
1701            this.update_subtree_composition_observer_count(app, -callback_count);
1702        }
1703        debug_assert!(child.data(app).parent == Some(self));
1704        debug_assert!(child.attached(app) == this.attached(app));
1705        child.data_mut(app).parent = None;
1706        if this.attached(app) {
1707            child.detach(app);
1708        }
1709    }
1710
1711    /// Removes all of this layer's children from its child list.
1712    pub fn remove_all_children(self, app: &mut App) {
1713        let this = self.as_layer();
1714        debug_assert!(!this.data(app).debug_mutations_locked);
1715        let mut child = self.first_child(app);
1716        while let Some(layer) = child {
1717            let next = layer.next_sibling(app);
1718            let data = layer.data_mut(app);
1719            data.previous_sibling = None;
1720            data.next_sibling = None;
1721            debug_assert!(layer.attached(app) == this.attached(app));
1722            self.drop_child(app, layer);
1723            LayerHandle::set_layer(app, |app| &mut layer.data_mut(app).parent_handle, None);
1724            child = next;
1725        }
1726        let data = self.data_mut(app);
1727        data.first_child = None;
1728        data.last_child = None;
1729    }
1730
1731    /// Uploads all of this layer's children to the engine.
1732    ///
1733    /// This method is typically used by `add_to_scene` to insert the children into the scene.
1734    /// Subclasses of [`ContainerLayer`] typically override `add_to_scene` to apply effects to
1735    /// the scene using the [`SceneBuilder`] API, then insert their children using
1736    /// `add_children_to_scene`, then reverse the aforementioned effects before returning from
1737    /// `add_to_scene`.
1738    pub fn add_children_to_scene(self, app: &mut App, builder: &mut SceneBuilder) {
1739        let mut child = self.first_child(app);
1740        while let Some(layer) = child {
1741            layer.add_to_scene_with_retained_rendering(app, builder);
1742            child = layer.next_sibling(app);
1743        }
1744    }
1745
1746    /// See [`ContainerLayer::apply_transform`].
1747    pub fn apply_transform(self, app: &App, child: Option<AnyLayer>, transform: &mut Matrix4) {
1748        (self.vtable.apply_transform)(app, self.id, child, transform);
1749    }
1750
1751    /// Returns the descendants of this layer in depth first order.
1752    pub fn depth_first_iterate_children(self, app: &App) -> Vec<AnyLayer> {
1753        let mut children = Vec::new();
1754        let mut child = self.first_child(app);
1755        while let Some(layer) = child {
1756            children.push(layer);
1757            if let Some(container) = layer.as_container_layer() {
1758                children.extend(container.depth_first_iterate_children(app));
1759            }
1760            child = layer.next_sibling(app);
1761        }
1762        children
1763    }
1764}
1765
1766/// Flutter's `OffsetLayer` fields, held under the field `offset_layer`
1767/// ([`offset_layer_accessors!`]).
1768#[derive(Debug)]
1769pub struct OffsetLayerData {
1770    offset: Offset,
1771}
1772
1773impl OffsetLayerData {
1774    /// Flutter's `OffsetLayer({offset})`.
1775    pub const fn new(offset: Offset) -> OffsetLayerData {
1776        OffsetLayerData { offset }
1777    }
1778}
1779
1780impl Default for OffsetLayerData {
1781    /// Flutter's `OffsetLayer()`: `offset` is zero.
1782    fn default() -> OffsetLayerData {
1783        OffsetLayerData::new(Offset::ZERO)
1784    }
1785}
1786
1787/// Implements the [`OffsetLayerMixin`] field accessors for an `offset_layer` field.
1788#[macro_export]
1789macro_rules! offset_layer_accessors {
1790    () => {
1791        fn offset_layer_data(
1792            self: ::inset_foundation::Handle<Self>,
1793            app: &::inset_foundation::App,
1794        ) -> &$crate::OffsetLayerData {
1795            &app.get(self).offset_layer
1796        }
1797        fn offset_layer_data_mut(
1798            self: ::inset_foundation::Handle<Self>,
1799            app: &mut ::inset_foundation::App,
1800        ) -> &mut $crate::OffsetLayerData {
1801            &mut app.get_mut(self).offset_layer
1802        }
1803    };
1804}
1805
1806/// A layer that is displayed at an offset from its parent layer.
1807///
1808/// Offset layers are key to efficient repainting because they are created by repaint boundaries
1809/// in the `RenderObject` tree (see `RenderObject.isRepaintBoundary`). When a render object that
1810/// is a repaint boundary is asked to paint at given offset in a `PaintingContext`, the render
1811/// object first checks whether it needs to repaint itself. If not, it reuses its existing
1812/// [`OffsetLayer`] (and its entire subtree) by mutating its offset property, cutting off the
1813/// paint walk.
1814///
1815/// Flutter's `OffsetLayer` is a concrete class that `TransformLayer`, `OpacityLayer` and
1816/// `ImageFilterLayer` extend: the bodies are here, [`OffsetLayer`] is the concrete leaf.
1817pub trait OffsetLayerMixin: ContainerLayer {
1818    /// Mixin field access.
1819    fn offset_layer_data(self: Handle<Self>, app: &App) -> &OffsetLayerData;
1820
1821    /// See [`offset_layer_data`](Self::offset_layer_data).
1822    fn offset_layer_data_mut(self: Handle<Self>, app: &mut App) -> &mut OffsetLayerData;
1823
1824    /// Dart's implicit upcast of a concrete layer to `OffsetLayer`.
1825    fn as_offset_layer(self: Handle<Self>) -> AnyOffsetLayer {
1826        AnyOffsetLayer {
1827            id: self.id(),
1828            vtable: const { &OffsetLayerVTable::of::<Self>() },
1829        }
1830    }
1831
1832    /// Offset from parent in the parent's coordinate system.
1833    fn offset(self: Handle<Self>, app: &App) -> Offset {
1834        self.offset_layer_data(app).offset
1835    }
1836
1837    /// See [`offset`](Self::offset).
1838    fn set_offset(self: Handle<Self>, app: &mut App, value: Offset) {
1839        self.offset_layer_data_mut(app).offset = value;
1840    }
1841
1842    /// `OffsetLayer.findAnnotations`.
1843    fn find_annotations(
1844        self: Handle<Self>,
1845        app: &App,
1846        result: &mut AnnotationSearch,
1847        local_position: Offset,
1848        only_first: bool,
1849    ) -> bool {
1850        let offset = self.offset(app);
1851        ContainerLayer::find_annotations(self, app, result, local_position - offset, only_first)
1852    }
1853
1854    /// `OffsetLayer.applyTransform`.
1855    fn apply_transform(
1856        self: Handle<Self>,
1857        app: &App,
1858        child: Option<AnyLayer>,
1859        transform: &mut Matrix4,
1860    ) {
1861        debug_assert!(child.is_some());
1862        let offset = self.offset(app);
1863        *transform = transform.then(&Matrix4::translation(
1864            offset.dx() as f32,
1865            offset.dy() as f32,
1866        ));
1867    }
1868
1869    /// `OffsetLayer.addToScene`.
1870    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
1871        // Skia has a fast path for concatenating scale/translation only matrices.
1872        // Hence pushing a translation-only transform layer should be fast. For
1873        // retained rendering, we don't want to push the offset down to each leaf
1874        // node. Otherwise, changing an offset layer on the very high level could
1875        // cascade the change to too many leaves.
1876        let offset = self.offset(app);
1877        builder.push_offset(offset.dx(), offset.dy());
1878        self.as_container_layer()
1879            .add_children_to_scene(app, builder);
1880        let engine_layer = builder.pop();
1881        self.as_layer().set_engine_layer(app, Some(engine_layer));
1882    }
1883}
1884
1885/// The vtable of an [`AnyOffsetLayer`]: the container vtable plus the offset accessors.
1886///
1887/// Public only so [`container_layer_accessors!`] can name it from another crate.
1888#[doc(hidden)]
1889pub struct OffsetLayerVTable {
1890    container: ContainerLayerVTable,
1891    offset_data: fn(&App, HandleId) -> &OffsetLayerData,
1892    offset_data_mut: fn(&mut App, HandleId) -> &mut OffsetLayerData,
1893}
1894
1895impl OffsetLayerVTable {
1896    pub const fn of<T: OffsetLayerMixin>() -> OffsetLayerVTable {
1897        OffsetLayerVTable {
1898            container: ContainerLayerVTable::of::<T>(),
1899            offset_data: |app, id| T::offset_layer_data(resolve(id), app),
1900            offset_data_mut: |app, id| T::offset_layer_data_mut(resolve(id), app),
1901        }
1902    }
1903}
1904
1905/// Erased `OffsetLayer`: what `RenderObject.updateCompositedLayer` returns and
1906/// `PaintingContext` positions.
1907#[derive(Clone, Copy)]
1908pub struct AnyOffsetLayer {
1909    id: HandleId,
1910    vtable: &'static OffsetLayerVTable,
1911}
1912
1913impl PartialEq for AnyOffsetLayer {
1914    fn eq(&self, other: &AnyOffsetLayer) -> bool {
1915        self.id == other.id
1916    }
1917}
1918
1919impl Eq for AnyOffsetLayer {}
1920
1921impl Hash for AnyOffsetLayer {
1922    fn hash<H: Hasher>(&self, state: &mut H) {
1923        self.id.hash(state);
1924    }
1925}
1926
1927impl From<AnyOffsetLayer> for HandleId {
1928    fn from(layer: AnyOffsetLayer) -> HandleId {
1929        layer.id
1930    }
1931}
1932
1933impl Debug for AnyOffsetLayer {
1934    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1935        write!(f, "AnyOffsetLayer({:?})", self.id)
1936    }
1937}
1938
1939impl ErasedLayer for AnyOffsetLayer {
1940    fn as_layer(self) -> AnyLayer {
1941        self.as_container_layer().as_layer()
1942    }
1943}
1944
1945impl AnyOffsetLayer {
1946    fn from_vtable(id: HandleId, vtable: &'static OffsetLayerVTable) -> AnyOffsetLayer {
1947        AnyOffsetLayer { id, vtable }
1948    }
1949
1950    pub fn id(self) -> HandleId {
1951        self.id
1952    }
1953
1954    /// The `ContainerLayer` view of this layer. Free: points into the nested table.
1955    pub fn as_container_layer(self) -> AnyContainerLayer {
1956        AnyContainerLayer::from_vtable(self.id, &self.vtable.container)
1957    }
1958
1959    /// See [`OffsetLayerMixin::offset`].
1960    pub fn offset(self, app: &App) -> Offset {
1961        (self.vtable.offset_data)(app, self.id).offset
1962    }
1963
1964    /// See [`OffsetLayerMixin::set_offset`].
1965    pub fn set_offset(self, app: &mut App, value: Offset) {
1966        if value == self.offset(app) {
1967            return;
1968        }
1969        (self.vtable.offset_data_mut)(app, self.id).offset = value;
1970        if !self.as_layer().always_needs_add_to_scene(app) {
1971            self.as_layer().mark_needs_add_to_scene(app);
1972        }
1973    }
1974}
1975
1976/// Flutter's concrete `OffsetLayer`; the bodies are [`OffsetLayerMixin`].
1977pub struct OffsetLayer {
1978    layer: LayerData,
1979    container_layer: ContainerLayerData,
1980    offset_layer: OffsetLayerData,
1981}
1982
1983impl OffsetLayer {
1984    /// Creates an offset layer.
1985    ///
1986    /// By default, `offset` is zero. It must be set before the compositing phase of the pipeline.
1987    pub fn new(app: &mut App, offset: Offset) -> Handle<OffsetLayer> {
1988        app.create(OffsetLayer {
1989            layer: LayerData::new(),
1990            container_layer: ContainerLayerData::new(),
1991            offset_layer: OffsetLayerData::new(offset),
1992        })
1993    }
1994}
1995
1996impl Layer for OffsetLayer {
1997    crate::layer_accessors!(container);
1998
1999    fn supports_rasterization(self: Handle<Self>, app: &App) -> bool {
2000        ContainerLayer::supports_rasterization(self, app)
2001    }
2002
2003    fn dispose(self: Handle<Self>, app: &mut App) {
2004        ContainerLayer::dispose(self, app);
2005    }
2006
2007    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
2008        ContainerLayer::attach(self, app, owner);
2009    }
2010
2011    fn detach(self: Handle<Self>, app: &mut App) {
2012        ContainerLayer::detach(self, app);
2013    }
2014
2015    fn redepth_children(self: Handle<Self>, app: &mut App) {
2016        ContainerLayer::redepth_children(self, app);
2017    }
2018
2019    fn find_annotations(
2020        self: Handle<Self>,
2021        app: &App,
2022        result: &mut AnnotationSearch,
2023        local_position: Offset,
2024        only_first: bool,
2025    ) -> bool {
2026        OffsetLayerMixin::find_annotations(self, app, result, local_position, only_first)
2027    }
2028
2029    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
2030        OffsetLayerMixin::add_to_scene(self, app, builder);
2031    }
2032
2033    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
2034        ContainerLayer::fire_composition_callbacks(self, app, include_children);
2035    }
2036}
2037
2038impl ContainerLayer for OffsetLayer {
2039    crate::container_layer_accessors!(offset);
2040
2041    fn apply_transform(
2042        self: Handle<Self>,
2043        app: &App,
2044        child: Option<AnyLayer>,
2045        transform: &mut Matrix4,
2046    ) {
2047        OffsetLayerMixin::apply_transform(self, app, child, transform);
2048    }
2049}
2050
2051impl OffsetLayerMixin for OffsetLayer {
2052    crate::offset_layer_accessors!();
2053}
2054
2055/// A key that identifies a group of backdrop filters that share one backdrop.
2056///
2057/// Every `BackdropFilterLayer` with the same key blurs the scene once, as of the first of
2058/// them, which is what Flutter's `BackdropGroup` trades for the cost of one filter pass.
2059#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
2060pub struct BackdropKey(u64);
2061
2062static NEXT_BACKDROP_KEY: AtomicU64 = AtomicU64::new(0);
2063
2064impl BackdropKey {
2065    /// Create a new [`BackdropKey`].
2066    #[expect(
2067        clippy::new_without_default,
2068        reason = "each call creates a distinct key; Default would suggest a neutral value"
2069    )]
2070    pub fn new() -> BackdropKey {
2071        BackdropKey(NEXT_BACKDROP_KEY.fetch_add(1, Ordering::Relaxed))
2072    }
2073
2074    /// dart:ui's `backdropId` for [`SceneBuilder::push_backdrop_filter`].
2075    pub fn id(self) -> u64 {
2076        self.0
2077    }
2078}
2079
2080/// A composite layer that clips its children using a rectangle.
2081///
2082/// When debugging, setting [`debug_disable_clip_layers`](crate::debug::debug_disable_clip_layers)
2083/// to true will cause this layer to be skipped (directly replaced by its children). This can be
2084/// helpful to track down the cause of performance problems.
2085pub struct ClipRectLayer {
2086    layer: LayerData,
2087    container_layer: ContainerLayerData,
2088    clip_rect: Option<Rect>,
2089    clip_behavior: Clip,
2090}
2091
2092impl ClipRectLayer {
2093    /// Creates a layer with a rectangular clip.
2094    ///
2095    /// The [`clip_rect`](Self::clip_rect) argument must not be null before the compositing phase
2096    /// of the pipeline.
2097    ///
2098    /// The [`clip_behavior`](Self::clip_behavior) argument must not be [`Clip::None`].
2099    pub fn new(app: &mut App) -> Handle<ClipRectLayer> {
2100        debug_assert!(Clip::HardEdge != Clip::None);
2101        app.create(ClipRectLayer {
2102            layer: LayerData::new(),
2103            container_layer: ContainerLayerData::new(),
2104            clip_rect: None,
2105            clip_behavior: Clip::HardEdge,
2106        })
2107    }
2108
2109    /// The rectangle to clip in the parent's coordinate system.
2110    ///
2111    /// The scene must be explicitly recomposited after this property is changed (as described at
2112    /// [`Layer`]).
2113    pub fn clip_rect(self: Handle<Self>, app: &App) -> Option<Rect> {
2114        app.get(self).clip_rect
2115    }
2116
2117    /// See [`clip_rect`](Self::clip_rect).
2118    pub fn set_clip_rect(self: Handle<Self>, app: &mut App, value: Option<Rect>) {
2119        if value != app.get(self).clip_rect {
2120            app.get_mut(self).clip_rect = value;
2121            self.as_layer().mark_needs_add_to_scene(app);
2122        }
2123    }
2124
2125    /// Controls how to clip.
2126    ///
2127    /// Must not be set to null or [`Clip::None`].
2128    ///
2129    /// Defaults to [`Clip::HardEdge`].
2130    pub fn clip_behavior(self: Handle<Self>, app: &App) -> Clip {
2131        app.get(self).clip_behavior
2132    }
2133
2134    /// See [`clip_behavior`](Self::clip_behavior).
2135    pub fn set_clip_behavior(self: Handle<Self>, app: &mut App, value: Clip) {
2136        debug_assert!(value != Clip::None);
2137        if value != app.get(self).clip_behavior {
2138            app.get_mut(self).clip_behavior = value;
2139            self.as_layer().mark_needs_add_to_scene(app);
2140        }
2141    }
2142}
2143
2144impl Layer for ClipRectLayer {
2145    crate::layer_accessors!(container);
2146
2147    fn describe_clip_bounds(self: Handle<Self>, app: &App) -> Option<Rect> {
2148        self.clip_rect(app)
2149    }
2150
2151    fn supports_rasterization(self: Handle<Self>, app: &App) -> bool {
2152        ContainerLayer::supports_rasterization(self, app)
2153    }
2154
2155    fn dispose(self: Handle<Self>, app: &mut App) {
2156        ContainerLayer::dispose(self, app);
2157    }
2158
2159    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
2160        ContainerLayer::attach(self, app, owner);
2161    }
2162
2163    fn detach(self: Handle<Self>, app: &mut App) {
2164        ContainerLayer::detach(self, app);
2165    }
2166
2167    fn redepth_children(self: Handle<Self>, app: &mut App) {
2168        ContainerLayer::redepth_children(self, app);
2169    }
2170
2171    fn find_annotations(
2172        self: Handle<Self>,
2173        app: &App,
2174        result: &mut AnnotationSearch,
2175        local_position: Offset,
2176        only_first: bool,
2177    ) -> bool {
2178        if !self
2179            .clip_rect(app)
2180            .expect("clipRect must be set before searching annotations")
2181            .contains(local_position)
2182        {
2183            return false;
2184        }
2185        ContainerLayer::find_annotations(self, app, result, local_position, only_first)
2186    }
2187
2188    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
2189        debug_assert!(self.clip_rect(app).is_some());
2190        let mut enabled = true;
2191        if cfg!(debug_assertions) {
2192            enabled = !crate::debug::debug_disable_clip_layers();
2193        }
2194        if enabled {
2195            let clip_rect = self
2196                .clip_rect(app)
2197                .expect("clipRect must be set before compositing");
2198            let clip_behavior = self.clip_behavior(app);
2199            builder.push_clip_rect(clip_rect, clip_behavior);
2200        }
2201        self.as_container_layer()
2202            .add_children_to_scene(app, builder);
2203        let engine_layer = enabled.then(|| builder.pop());
2204        self.as_layer().set_engine_layer(app, engine_layer);
2205    }
2206
2207    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
2208        ContainerLayer::fire_composition_callbacks(self, app, include_children);
2209    }
2210}
2211
2212impl ContainerLayer for ClipRectLayer {
2213    crate::container_layer_accessors!();
2214}
2215
2216/// A composite layer that clips its children using a rounded rectangle.
2217///
2218/// When debugging, setting [`debug_disable_clip_layers`](crate::debug::debug_disable_clip_layers)
2219/// to true will cause this layer to be skipped (directly replaced by its children). This can be
2220/// helpful to track down the cause of performance problems.
2221pub struct ClipRRectLayer {
2222    layer: LayerData,
2223    container_layer: ContainerLayerData,
2224    clip_rrect: Option<RRect>,
2225    clip_behavior: Clip,
2226}
2227
2228impl ClipRRectLayer {
2229    /// Creates a layer with a rounded-rectangular clip.
2230    ///
2231    /// The [`clip_rrect`](Self::clip_rrect) and [`clip_behavior`](Self::clip_behavior) properties
2232    /// must be non-null before the compositing phase of the pipeline.
2233    pub fn new(app: &mut App) -> Handle<ClipRRectLayer> {
2234        debug_assert!(Clip::AntiAlias != Clip::None);
2235        app.create(ClipRRectLayer {
2236            layer: LayerData::new(),
2237            container_layer: ContainerLayerData::new(),
2238            clip_rrect: None,
2239            clip_behavior: Clip::AntiAlias,
2240        })
2241    }
2242
2243    /// The rounded-rect to clip in the parent's coordinate system.
2244    ///
2245    /// The scene must be explicitly recomposited after this property is changed (as described at
2246    /// [`Layer`]).
2247    pub fn clip_rrect(self: Handle<Self>, app: &App) -> Option<RRect> {
2248        app.get(self).clip_rrect
2249    }
2250
2251    /// See [`clip_rrect`](Self::clip_rrect).
2252    pub fn set_clip_rrect(self: Handle<Self>, app: &mut App, value: Option<RRect>) {
2253        if value != app.get(self).clip_rrect {
2254            app.get_mut(self).clip_rrect = value;
2255            self.as_layer().mark_needs_add_to_scene(app);
2256        }
2257    }
2258
2259    /// Controls how to clip.
2260    ///
2261    /// Must not be set to null or [`Clip::None`].
2262    ///
2263    /// Defaults to [`Clip::AntiAlias`].
2264    pub fn clip_behavior(self: Handle<Self>, app: &App) -> Clip {
2265        app.get(self).clip_behavior
2266    }
2267
2268    /// See [`clip_behavior`](Self::clip_behavior).
2269    pub fn set_clip_behavior(self: Handle<Self>, app: &mut App, value: Clip) {
2270        debug_assert!(value != Clip::None);
2271        if value != app.get(self).clip_behavior {
2272            app.get_mut(self).clip_behavior = value;
2273            self.as_layer().mark_needs_add_to_scene(app);
2274        }
2275    }
2276}
2277
2278impl Layer for ClipRRectLayer {
2279    crate::layer_accessors!(container);
2280
2281    fn describe_clip_bounds(self: Handle<Self>, app: &App) -> Option<Rect> {
2282        self.clip_rrect(app).map(RRect::outer_rect)
2283    }
2284
2285    fn supports_rasterization(self: Handle<Self>, app: &App) -> bool {
2286        ContainerLayer::supports_rasterization(self, app)
2287    }
2288
2289    fn dispose(self: Handle<Self>, app: &mut App) {
2290        ContainerLayer::dispose(self, app);
2291    }
2292
2293    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
2294        ContainerLayer::attach(self, app, owner);
2295    }
2296
2297    fn detach(self: Handle<Self>, app: &mut App) {
2298        ContainerLayer::detach(self, app);
2299    }
2300
2301    fn redepth_children(self: Handle<Self>, app: &mut App) {
2302        ContainerLayer::redepth_children(self, app);
2303    }
2304
2305    fn find_annotations(
2306        self: Handle<Self>,
2307        app: &App,
2308        result: &mut AnnotationSearch,
2309        local_position: Offset,
2310        only_first: bool,
2311    ) -> bool {
2312        if !self
2313            .clip_rrect(app)
2314            .expect("clipRRect must be set before searching annotations")
2315            .contains(local_position)
2316        {
2317            return false;
2318        }
2319        ContainerLayer::find_annotations(self, app, result, local_position, only_first)
2320    }
2321
2322    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
2323        debug_assert!(self.clip_rrect(app).is_some());
2324        let mut enabled = true;
2325        if cfg!(debug_assertions) {
2326            enabled = !crate::debug::debug_disable_clip_layers();
2327        }
2328        if enabled {
2329            let clip_rrect = self
2330                .clip_rrect(app)
2331                .expect("clipRRect must be set before compositing");
2332            let clip_behavior = self.clip_behavior(app);
2333            builder.push_clip_rrect(clip_rrect, clip_behavior);
2334        }
2335        self.as_container_layer()
2336            .add_children_to_scene(app, builder);
2337        let engine_layer = enabled.then(|| builder.pop());
2338        self.as_layer().set_engine_layer(app, engine_layer);
2339    }
2340
2341    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
2342        ContainerLayer::fire_composition_callbacks(self, app, include_children);
2343    }
2344}
2345
2346impl ContainerLayer for ClipRRectLayer {
2347    crate::container_layer_accessors!();
2348}
2349
2350/// A composite layer that clips its children using a path.
2351///
2352/// When debugging, setting [`debug_disable_clip_layers`](crate::debug::debug_disable_clip_layers)
2353/// to true will cause this layer to be skipped (directly replaced by its children). This can be
2354/// helpful to track down the cause of performance problems.
2355pub struct ClipPathLayer {
2356    layer: LayerData,
2357    container_layer: ContainerLayerData,
2358    clip_path: Option<Arc<inset_embedder::Path>>,
2359    clip_behavior: Clip,
2360}
2361
2362impl ClipPathLayer {
2363    /// Creates a layer with a path-based clip.
2364    ///
2365    /// The [`clip_path`](Self::clip_path) and [`clip_behavior`](Self::clip_behavior) properties
2366    /// must be non-null before the compositing phase of the pipeline.
2367    pub fn new(app: &mut App) -> Handle<ClipPathLayer> {
2368        debug_assert!(Clip::AntiAlias != Clip::None);
2369        app.create(ClipPathLayer {
2370            layer: LayerData::new(),
2371            container_layer: ContainerLayerData::new(),
2372            clip_path: None,
2373            clip_behavior: Clip::AntiAlias,
2374        })
2375    }
2376
2377    /// The path to clip in the parent's coordinate system.
2378    ///
2379    /// The scene must be explicitly recomposited after this property is changed (as described at
2380    /// [`Layer`]).
2381    pub fn clip_path(self: Handle<Self>, app: &App) -> Option<&Arc<inset_embedder::Path>> {
2382        app.get(self).clip_path.as_ref()
2383    }
2384
2385    /// See [`clip_path`](Self::clip_path).
2386    pub fn set_clip_path(
2387        self: Handle<Self>,
2388        app: &mut App,
2389        value: Option<Arc<inset_embedder::Path>>,
2390    ) {
2391        app.get_mut(self).clip_path = value;
2392        self.as_layer().mark_needs_add_to_scene(app);
2393    }
2394
2395    /// Controls how to clip.
2396    ///
2397    /// Must not be set to null or [`Clip::None`].
2398    ///
2399    /// Defaults to [`Clip::AntiAlias`].
2400    pub fn clip_behavior(self: Handle<Self>, app: &App) -> Clip {
2401        app.get(self).clip_behavior
2402    }
2403
2404    /// See [`clip_behavior`](Self::clip_behavior).
2405    pub fn set_clip_behavior(self: Handle<Self>, app: &mut App, value: Clip) {
2406        debug_assert!(value != Clip::None);
2407        if value != app.get(self).clip_behavior {
2408            app.get_mut(self).clip_behavior = value;
2409            self.as_layer().mark_needs_add_to_scene(app);
2410        }
2411    }
2412}
2413
2414impl Layer for ClipPathLayer {
2415    crate::layer_accessors!(container);
2416
2417    fn describe_clip_bounds(self: Handle<Self>, app: &App) -> Option<Rect> {
2418        let bounds = app.get(self).clip_path.as_ref()?.bounds();
2419        Some(Rect::from_ltwh(
2420            bounds.x as f64,
2421            bounds.y as f64,
2422            bounds.width as f64,
2423            bounds.height as f64,
2424        ))
2425    }
2426
2427    fn supports_rasterization(self: Handle<Self>, app: &App) -> bool {
2428        ContainerLayer::supports_rasterization(self, app)
2429    }
2430
2431    fn dispose(self: Handle<Self>, app: &mut App) {
2432        ContainerLayer::dispose(self, app);
2433    }
2434
2435    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
2436        ContainerLayer::attach(self, app, owner);
2437    }
2438
2439    fn detach(self: Handle<Self>, app: &mut App) {
2440        ContainerLayer::detach(self, app);
2441    }
2442
2443    fn redepth_children(self: Handle<Self>, app: &mut App) {
2444        ContainerLayer::redepth_children(self, app);
2445    }
2446
2447    fn find_annotations(
2448        self: Handle<Self>,
2449        app: &App,
2450        result: &mut AnnotationSearch,
2451        local_position: Offset,
2452        only_first: bool,
2453    ) -> bool {
2454        let path = app
2455            .get(self)
2456            .clip_path
2457            .as_ref()
2458            .expect("clipPath must be set before searching annotations");
2459        if !path.contains(local_position.into(), FillRule::NonZero) {
2460            return false;
2461        }
2462        ContainerLayer::find_annotations(self, app, result, local_position, only_first)
2463    }
2464
2465    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
2466        debug_assert!(app.get(self).clip_path.is_some());
2467        let mut enabled = true;
2468        if cfg!(debug_assertions) {
2469            enabled = !crate::debug::debug_disable_clip_layers();
2470        }
2471        if enabled {
2472            let clip_path = Arc::clone(
2473                app.get(self)
2474                    .clip_path
2475                    .as_ref()
2476                    .expect("clipPath must be set before compositing"),
2477            );
2478            let clip_behavior = self.clip_behavior(app);
2479            builder.push_clip_path(&clip_path, clip_behavior);
2480        }
2481        self.as_container_layer()
2482            .add_children_to_scene(app, builder);
2483        let engine_layer = enabled.then(|| builder.pop());
2484        self.as_layer().set_engine_layer(app, engine_layer);
2485    }
2486
2487    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
2488        ContainerLayer::fire_composition_callbacks(self, app, include_children);
2489    }
2490}
2491
2492impl ContainerLayer for ClipPathLayer {
2493    crate::container_layer_accessors!();
2494}
2495
2496/// Dart's `MatrixUtils.transformPoint`.
2497fn transform_point(transform: &Matrix4, point: Offset) -> Offset {
2498    let storage = transform.to_flutter_array();
2499    let x = point.dx();
2500    let y = point.dy();
2501    let rx = storage[0] as f64 * x + storage[4] as f64 * y + storage[12] as f64;
2502    let ry = storage[1] as f64 * x + storage[5] as f64 * y + storage[13] as f64;
2503    let rw = storage[3] as f64 * x + storage[7] as f64 * y + storage[15] as f64;
2504    if rw == 1.0 {
2505        Offset::new(rx, ry)
2506    } else {
2507        Offset::new(rx / rw, ry / rw)
2508    }
2509}
2510
2511/// A composited layer that applies a given transformation matrix to its children.
2512///
2513/// This class inherits from [`OffsetLayer`] to make it one of the layers that can be used at the
2514/// root of a `RenderObject` hierarchy.
2515pub struct TransformLayer {
2516    layer: LayerData,
2517    container_layer: ContainerLayerData,
2518    offset_layer: OffsetLayerData,
2519    transform: Option<Matrix4>,
2520    last_effective_transform: Option<Matrix4>,
2521    inverted_transform: Cell<Option<Matrix4>>,
2522    inverse_dirty: Cell<bool>,
2523}
2524
2525impl TransformLayer {
2526    /// Creates a transform layer.
2527    ///
2528    /// The [`transform`](Self::transform) and `offset` properties must be non-null before the
2529    /// compositing phase of the pipeline.
2530    pub fn new(app: &mut App) -> Handle<TransformLayer> {
2531        app.create(TransformLayer {
2532            layer: LayerData::new(),
2533            container_layer: ContainerLayerData::new(),
2534            offset_layer: OffsetLayerData::new(Offset::ZERO),
2535            transform: None,
2536            last_effective_transform: None,
2537            inverted_transform: Cell::new(None),
2538            inverse_dirty: Cell::new(true),
2539        })
2540    }
2541
2542    /// The matrix to apply.
2543    ///
2544    /// The scene must be explicitly recomposited after this property is changed (as described at
2545    /// [`Layer`]).
2546    ///
2547    /// This transform is applied before `offset`, if both are set.
2548    ///
2549    /// The [`transform`](Self::transform) property must be non-null before the compositing phase
2550    /// of the pipeline.
2551    pub fn transform(self: Handle<Self>, app: &App) -> Option<Matrix4> {
2552        app.get(self).transform
2553    }
2554
2555    /// See [`transform`](Self::transform).
2556    pub fn set_transform(self: Handle<Self>, app: &mut App, value: Matrix4) {
2557        debug_assert!(
2558            value
2559                .to_flutter_array()
2560                .iter()
2561                .all(|component| component.is_finite())
2562        );
2563        if app.get(self).transform == Some(value) {
2564            return;
2565        }
2566        app.get_mut(self).transform = Some(value);
2567        app.get(self).inverse_dirty.set(true);
2568        self.as_layer().mark_needs_add_to_scene(app);
2569    }
2570
2571    fn transform_offset(self: Handle<Self>, app: &App, local_position: Offset) -> Option<Offset> {
2572        if app.get(self).inverse_dirty.get() {
2573            let transform = app
2574                .get(self)
2575                .transform
2576                .expect("transform must be set before searching annotations");
2577            app.get(self)
2578                .inverted_transform
2579                .set(remove_perspective_transform(transform).invert());
2580            app.get(self).inverse_dirty.set(false);
2581        }
2582        app.get(self)
2583            .inverted_transform
2584            .get()
2585            .map(|inverted| transform_point(&inverted, local_position))
2586    }
2587}
2588
2589impl Layer for TransformLayer {
2590    crate::layer_accessors!(container);
2591
2592    fn supports_rasterization(self: Handle<Self>, app: &App) -> bool {
2593        ContainerLayer::supports_rasterization(self, app)
2594    }
2595
2596    fn dispose(self: Handle<Self>, app: &mut App) {
2597        ContainerLayer::dispose(self, app);
2598    }
2599
2600    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
2601        ContainerLayer::attach(self, app, owner);
2602    }
2603
2604    fn detach(self: Handle<Self>, app: &mut App) {
2605        ContainerLayer::detach(self, app);
2606    }
2607
2608    fn redepth_children(self: Handle<Self>, app: &mut App) {
2609        ContainerLayer::redepth_children(self, app);
2610    }
2611
2612    fn find_annotations(
2613        self: Handle<Self>,
2614        app: &App,
2615        result: &mut AnnotationSearch,
2616        local_position: Offset,
2617        only_first: bool,
2618    ) -> bool {
2619        let Some(transformed_offset) = self.transform_offset(app, local_position) else {
2620            return false;
2621        };
2622        OffsetLayerMixin::find_annotations(self, app, result, transformed_offset, only_first)
2623    }
2624
2625    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
2626        debug_assert!(self.transform(app).is_some());
2627        let mut last_effective = self
2628            .transform(app)
2629            .expect("transform must be set before compositing");
2630        let offset = self.offset(app);
2631        if offset != Offset::ZERO {
2632            last_effective =
2633                Matrix4::translation(offset.dx() as f32, offset.dy() as f32).then(&last_effective);
2634        }
2635        app.get_mut(self).last_effective_transform = Some(last_effective);
2636        builder.push_transform(&last_effective);
2637        self.as_container_layer()
2638            .add_children_to_scene(app, builder);
2639        let engine_layer = builder.pop();
2640        self.as_layer().set_engine_layer(app, Some(engine_layer));
2641    }
2642
2643    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
2644        ContainerLayer::fire_composition_callbacks(self, app, include_children);
2645    }
2646}
2647
2648impl ContainerLayer for TransformLayer {
2649    crate::container_layer_accessors!(offset);
2650
2651    fn apply_transform(
2652        self: Handle<Self>,
2653        app: &App,
2654        child: Option<AnyLayer>,
2655        transform: &mut Matrix4,
2656    ) {
2657        debug_assert!(child.is_some());
2658        debug_assert!(
2659            app.get(self).last_effective_transform.is_some() || self.transform(app).is_some()
2660        );
2661        let applied = match app.get(self).last_effective_transform {
2662            None => self
2663                .transform(app)
2664                .expect("transform must be set before applyTransform"),
2665            Some(last_effective) => last_effective,
2666        };
2667        *transform = transform.then(&applied);
2668    }
2669}
2670
2671impl OffsetLayerMixin for TransformLayer {
2672    crate::offset_layer_accessors!();
2673}
2674
2675/// A composited layer that makes its children partially transparent.
2676///
2677/// When debugging, setting
2678/// [`debug_disable_opacity_layers`](crate::debug::debug_disable_opacity_layers) to true will
2679/// cause this layer to be skipped (directly replaced by its children). This can be helpful to
2680/// track down the cause of performance problems.
2681///
2682/// Try to avoid an [`OpacityLayer`] with no children. Remove that layer if possible to save some
2683/// tree walks.
2684pub struct OpacityLayer {
2685    layer: LayerData,
2686    container_layer: ContainerLayerData,
2687    offset_layer: OffsetLayerData,
2688    alpha: Option<i32>,
2689}
2690
2691impl OpacityLayer {
2692    /// Creates an opacity layer.
2693    ///
2694    /// The [`alpha`](Self::alpha) property must be non-null before the compositing phase of the
2695    /// pipeline.
2696    pub fn new(app: &mut App) -> Handle<OpacityLayer> {
2697        app.create(OpacityLayer {
2698            layer: LayerData::new(),
2699            container_layer: ContainerLayerData::new(),
2700            offset_layer: OffsetLayerData::new(Offset::ZERO),
2701            alpha: None,
2702        })
2703    }
2704
2705    /// The amount to multiply into the alpha channel.
2706    ///
2707    /// The opacity is expressed as an integer from 0 to 255, where 0 is fully transparent and
2708    /// 255 is fully opaque.
2709    ///
2710    /// The scene must be explicitly recomposited after this property is changed (as described at
2711    /// [`Layer`]).
2712    pub fn alpha(self: Handle<Self>, app: &App) -> Option<i32> {
2713        app.get(self).alpha
2714    }
2715
2716    /// See [`alpha`](Self::alpha).
2717    pub fn set_alpha(self: Handle<Self>, app: &mut App, value: i32) {
2718        if app.get(self).alpha != Some(value) {
2719            app.get_mut(self).alpha = Some(value);
2720            self.as_layer().mark_needs_add_to_scene(app);
2721        }
2722    }
2723}
2724
2725impl Layer for OpacityLayer {
2726    crate::layer_accessors!(container);
2727
2728    fn supports_rasterization(self: Handle<Self>, app: &App) -> bool {
2729        ContainerLayer::supports_rasterization(self, app)
2730    }
2731
2732    fn dispose(self: Handle<Self>, app: &mut App) {
2733        ContainerLayer::dispose(self, app);
2734    }
2735
2736    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
2737        ContainerLayer::attach(self, app, owner);
2738    }
2739
2740    fn detach(self: Handle<Self>, app: &mut App) {
2741        ContainerLayer::detach(self, app);
2742    }
2743
2744    fn redepth_children(self: Handle<Self>, app: &mut App) {
2745        ContainerLayer::redepth_children(self, app);
2746    }
2747
2748    fn find_annotations(
2749        self: Handle<Self>,
2750        app: &App,
2751        result: &mut AnnotationSearch,
2752        local_position: Offset,
2753        only_first: bool,
2754    ) -> bool {
2755        OffsetLayerMixin::find_annotations(self, app, result, local_position, only_first)
2756    }
2757
2758    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
2759        debug_assert!(self.alpha(app).is_some());
2760
2761        // Don't add this layer if there's no child.
2762        let mut enabled = self.as_container_layer().first_child(app).is_some();
2763        if !enabled {
2764            // Ensure the engine layer is disposed.
2765            self.as_layer().set_engine_layer(app, None);
2766            return;
2767        }
2768
2769        if cfg!(debug_assertions) {
2770            enabled = enabled && !crate::debug::debug_disable_opacity_layers();
2771        }
2772
2773        let realized_alpha = self
2774            .alpha(app)
2775            .expect("alpha must be set before compositing");
2776        let offset = self.offset(app);
2777        if enabled && realized_alpha < 255 {
2778            builder.push_opacity(realized_alpha, offset);
2779        } else {
2780            builder.push_offset(offset.dx(), offset.dy());
2781        }
2782        self.as_container_layer()
2783            .add_children_to_scene(app, builder);
2784        let engine_layer = builder.pop();
2785        self.as_layer().set_engine_layer(app, Some(engine_layer));
2786    }
2787
2788    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
2789        ContainerLayer::fire_composition_callbacks(self, app, include_children);
2790    }
2791}
2792
2793impl ContainerLayer for OpacityLayer {
2794    crate::container_layer_accessors!(offset);
2795
2796    fn apply_transform(
2797        self: Handle<Self>,
2798        app: &App,
2799        child: Option<AnyLayer>,
2800        transform: &mut Matrix4,
2801    ) {
2802        OffsetLayerMixin::apply_transform(self, app, child, transform);
2803    }
2804}
2805
2806impl OffsetLayerMixin for OpacityLayer {
2807    crate::offset_layer_accessors!();
2808}
2809
2810/// A composited layer that applies a filter to the existing contents of the scene.
2811pub struct BackdropFilterLayer {
2812    layer: LayerData,
2813    container_layer: ContainerLayerData,
2814    filter: Option<ImageFilter>,
2815    blend_mode: BlendMode,
2816    backdrop_key: Option<BackdropKey>,
2817}
2818
2819impl BackdropFilterLayer {
2820    /// Creates a backdrop filter layer.
2821    ///
2822    /// The [`filter`](Self::filter) property must be non-null before the compositing phase of
2823    /// the pipeline.
2824    ///
2825    /// The [`blend_mode`](Self::blend_mode) property defaults to [`BlendMode::SrcOver`].
2826    pub fn new(app: &mut App) -> Handle<BackdropFilterLayer> {
2827        app.create(BackdropFilterLayer {
2828            layer: LayerData::new(),
2829            container_layer: ContainerLayerData::new(),
2830            filter: None,
2831            blend_mode: BlendMode::SrcOver,
2832            backdrop_key: None,
2833        })
2834    }
2835
2836    /// The filter to apply to the existing contents of the scene.
2837    ///
2838    /// The scene must be explicitly recomposited after this property is changed (as described at
2839    /// [`Layer`]).
2840    pub fn filter(self: Handle<Self>, app: &App) -> Option<&ImageFilter> {
2841        app.get(self).filter.as_ref()
2842    }
2843
2844    /// See [`filter`](Self::filter).
2845    pub fn set_filter(self: Handle<Self>, app: &mut App, value: Option<ImageFilter>) {
2846        app.get_mut(self).filter = value;
2847        self.as_layer().mark_needs_add_to_scene(app);
2848    }
2849
2850    /// The blend mode to use to apply the filtered background content onto the background
2851    /// surface.
2852    ///
2853    /// The default value of this property is [`BlendMode::SrcOver`].
2854    ///
2855    /// The scene must be explicitly recomposited after this property is changed (as described at
2856    /// [`Layer`]).
2857    pub fn blend_mode(self: Handle<Self>, app: &App) -> BlendMode {
2858        app.get(self).blend_mode
2859    }
2860
2861    /// See [`blend_mode`](Self::blend_mode).
2862    pub fn set_blend_mode(self: Handle<Self>, app: &mut App, value: BlendMode) {
2863        if value != app.get(self).blend_mode {
2864            app.get_mut(self).blend_mode = value;
2865            self.as_layer().mark_needs_add_to_scene(app);
2866        }
2867    }
2868
2869    /// The backdrop key that identifies the `BackdropGroup` this filter will apply to.
2870    ///
2871    /// The default value for the backdrop key is `None`, meaning that it's not part of a
2872    /// `BackdropGroup`.
2873    ///
2874    /// The scene must be explicitly recomposited after this property is changed (as described at
2875    /// [`Layer`]).
2876    pub fn backdrop_key(self: Handle<Self>, app: &App) -> Option<BackdropKey> {
2877        app.get(self).backdrop_key
2878    }
2879
2880    /// See [`backdrop_key`](Self::backdrop_key).
2881    pub fn set_backdrop_key(self: Handle<Self>, app: &mut App, value: Option<BackdropKey>) {
2882        if value != app.get(self).backdrop_key {
2883            app.get_mut(self).backdrop_key = value;
2884            self.as_layer().mark_needs_add_to_scene(app);
2885        }
2886    }
2887}
2888
2889impl Layer for BackdropFilterLayer {
2890    crate::layer_accessors!(container);
2891
2892    fn supports_rasterization(self: Handle<Self>, app: &App) -> bool {
2893        ContainerLayer::supports_rasterization(self, app)
2894    }
2895
2896    fn dispose(self: Handle<Self>, app: &mut App) {
2897        ContainerLayer::dispose(self, app);
2898    }
2899
2900    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
2901        ContainerLayer::attach(self, app, owner);
2902    }
2903
2904    fn detach(self: Handle<Self>, app: &mut App) {
2905        ContainerLayer::detach(self, app);
2906    }
2907
2908    fn redepth_children(self: Handle<Self>, app: &mut App) {
2909        ContainerLayer::redepth_children(self, app);
2910    }
2911
2912    fn find_annotations(
2913        self: Handle<Self>,
2914        app: &App,
2915        result: &mut AnnotationSearch,
2916        local_position: Offset,
2917        only_first: bool,
2918    ) -> bool {
2919        ContainerLayer::find_annotations(self, app, result, local_position, only_first)
2920    }
2921
2922    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
2923        debug_assert!(app.get(self).filter.is_some());
2924        let filter = app
2925            .get(self)
2926            .filter
2927            .clone()
2928            .expect("filter must be set before compositing");
2929        let blend_mode = self.blend_mode(app);
2930        let backdrop_id = self.backdrop_key(app).map(BackdropKey::id);
2931        builder.push_backdrop_filter(&filter, blend_mode, backdrop_id);
2932        self.as_container_layer()
2933            .add_children_to_scene(app, builder);
2934        let engine_layer = builder.pop();
2935        self.as_layer().set_engine_layer(app, Some(engine_layer));
2936    }
2937
2938    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
2939        ContainerLayer::fire_composition_callbacks(self, app, include_children);
2940    }
2941}
2942
2943impl ContainerLayer for BackdropFilterLayer {
2944    crate::container_layer_accessors!();
2945}
2946
2947/// An object that a [`LeaderLayer`] can register with.
2948///
2949/// An instance of this class should be provided as the [`LeaderLayer::link`] and the
2950/// [`FollowerLayer::link`] properties to cause the [`FollowerLayer`] to follow the
2951/// [`LeaderLayer`].
2952///
2953/// See also:
2954///
2955///  * `CompositedTransformTarget`, the widget that creates a [`LeaderLayer`].
2956///  * `CompositedTransformFollower`, the widget that creates a [`FollowerLayer`].
2957///  * `RenderLeaderLayer` and `RenderFollowerLayer`, the corresponding render objects.
2958pub struct LayerLink {
2959    leader: Option<Handle<LeaderLayer>>,
2960    debug_previous_leaders: Option<HashSet<Handle<LeaderLayer>>>,
2961    debug_leader_check_scheduled: bool,
2962    /// The total size of the content of the connected [`LeaderLayer`].
2963    ///
2964    /// Generally this should be set by the `RenderObject` that paints on the registered
2965    /// [`LeaderLayer`] (for instance a `RenderLeaderLayer` that shares this link with its
2966    /// followers). This size may be outdated before and during layout.
2967    pub leader_size: Option<Size>,
2968}
2969
2970impl LayerLink {
2971    /// Creates a link with no leader.
2972    pub fn new(app: &mut App) -> Handle<LayerLink> {
2973        app.create(LayerLink {
2974            leader: None,
2975            debug_previous_leaders: None,
2976            debug_leader_check_scheduled: false,
2977            leader_size: None,
2978        })
2979    }
2980
2981    /// The [`LeaderLayer`] connected to this link.
2982    pub fn leader(self: Handle<Self>, app: &App) -> Option<Handle<LeaderLayer>> {
2983        app.get(self).leader
2984    }
2985
2986    fn register_leader(self: Handle<Self>, app: &mut App, leader: Handle<LeaderLayer>) {
2987        debug_assert_ne!(self.leader(app), Some(leader));
2988        if cfg!(debug_assertions)
2989            && let Some(current) = self.leader(app)
2990        {
2991            let previous = app
2992                .get_mut(self)
2993                .debug_previous_leaders
2994                .get_or_insert_with(HashSet::new);
2995            debug_assert!(previous.insert(current));
2996            self.debug_schedule_leaders_clean_up_check(app);
2997        }
2998        app.get_mut(self).leader = Some(leader);
2999    }
3000
3001    fn unregister_leader(self: Handle<Self>, app: &mut App, leader: Handle<LeaderLayer>) {
3002        if self.leader(app) == Some(leader) {
3003            app.get_mut(self).leader = None;
3004        } else if cfg!(debug_assertions) {
3005            let removed = app
3006                .get_mut(self)
3007                .debug_previous_leaders
3008                .as_mut()
3009                .expect("a replaced leader is tracked")
3010                .remove(&leader);
3011            debug_assert!(removed);
3012        }
3013    }
3014
3015    /// Schedules the check as post frame callback to make sure the `_debugPreviousLeaders` is
3016    /// empty.
3017    fn debug_schedule_leaders_clean_up_check(self: Handle<Self>, app: &mut App) {
3018        debug_assert!(app.get(self).debug_previous_leaders.is_some());
3019        if cfg!(debug_assertions) {
3020            if app.get(self).debug_leader_check_scheduled {
3021                return;
3022            }
3023            app.get_mut(self).debug_leader_check_scheduled = true;
3024            SchedulerBinding::add_post_frame_callback(
3025                app,
3026                FrameCallback::handle_method(self, |this, app, _time_stamp| {
3027                    app.get_mut(this).debug_leader_check_scheduled = false;
3028                    debug_assert!(
3029                        app.get(this)
3030                            .debug_previous_leaders
3031                            .as_ref()
3032                            .expect("a replaced leader is tracked")
3033                            .is_empty()
3034                    );
3035                }),
3036                None,
3037            );
3038        }
3039    }
3040}
3041
3042/// A composited layer that can be followed by a [`FollowerLayer`].
3043///
3044/// This layer collapses the accumulated offset into a transform and passes [`Offset::ZERO`] to
3045/// its child layers in the [`Layer::add_to_scene`] / `add_children_to_scene` methods, so that
3046/// [`ContainerLayer::apply_transform`] will work reliably.
3047pub struct LeaderLayer {
3048    layer: LayerData,
3049    container_layer: ContainerLayerData,
3050    /// `None` only while [`Layer::dispose`] takes the retain so it can [`App::release`] it
3051    /// before the arena entry is destroyed.
3052    link: Option<RetainedHandle<Handle<LayerLink>>>,
3053    offset: Offset,
3054}
3055
3056impl LeaderLayer {
3057    /// Creates a leader layer.
3058    ///
3059    /// The [`link`](Self::link) property must not have been provided to any other [`LeaderLayer`]
3060    /// layers that are attached to the layer tree at the same time.
3061    ///
3062    /// The [`offset`](Self::offset) property must be non-null before the compositing phase of
3063    /// the pipeline.
3064    pub fn new(app: &mut App, link: Handle<LayerLink>) -> Handle<LeaderLayer> {
3065        let link = app.retain(link);
3066        app.create(LeaderLayer {
3067            layer: LayerData::new(),
3068            container_layer: ContainerLayerData::new(),
3069            link: Some(link),
3070            offset: Offset::ZERO,
3071        })
3072    }
3073
3074    /// The object with which this layer should register.
3075    ///
3076    /// The link will be established when this layer is [`Layer::attach`]ed, and will be cleared
3077    /// when this layer is [`Layer::detach`]ed.
3078    pub fn link(self: Handle<Self>, app: &App) -> Handle<LayerLink> {
3079        app.get(self)
3080            .link
3081            .as_ref()
3082            .expect("a LeaderLayer holds its link until dispose")
3083            .get()
3084    }
3085
3086    /// See [`link`](Self::link).
3087    pub fn set_link(self: Handle<Self>, app: &mut App, value: Handle<LayerLink>) {
3088        let current = self.link(app);
3089        if current == value {
3090            return;
3091        }
3092        if self.as_layer().attached(app) {
3093            current.unregister_leader(app, self);
3094            value.register_leader(app, self);
3095        }
3096        let retained = app.retain(value);
3097        let old = app
3098            .get_mut(self)
3099            .link
3100            .replace(retained)
3101            .expect("a LeaderLayer holds its link until dispose");
3102        app.release(old);
3103    }
3104
3105    /// Offset from parent in the parent's coordinate system.
3106    ///
3107    /// The scene must be explicitly recomposited after this property is changed (as described at
3108    /// [`Layer`]).
3109    ///
3110    /// The [`offset`](Self::offset) property must be non-null before the compositing phase of
3111    /// the pipeline.
3112    pub fn offset(self: Handle<Self>, app: &App) -> Offset {
3113        app.get(self).offset
3114    }
3115
3116    /// See [`offset`](Self::offset).
3117    pub fn set_offset(self: Handle<Self>, app: &mut App, value: Offset) {
3118        if value == app.get(self).offset {
3119            return;
3120        }
3121        app.get_mut(self).offset = value;
3122        if !self.as_layer().always_needs_add_to_scene(app) {
3123            self.as_layer().mark_needs_add_to_scene(app);
3124        }
3125    }
3126}
3127
3128impl Layer for LeaderLayer {
3129    crate::layer_accessors!(container);
3130
3131    fn supports_rasterization(self: Handle<Self>, app: &App) -> bool {
3132        ContainerLayer::supports_rasterization(self, app)
3133    }
3134
3135    fn dispose(self: Handle<Self>, app: &mut App) {
3136        let link = app
3137            .get_mut(self)
3138            .link
3139            .take()
3140            .expect("a LeaderLayer holds its link until dispose");
3141        ContainerLayer::dispose(self, app);
3142        app.release(link);
3143    }
3144
3145    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
3146        ContainerLayer::attach(self, app, owner);
3147        let link = self.link(app);
3148        link.register_leader(app, self);
3149    }
3150
3151    fn detach(self: Handle<Self>, app: &mut App) {
3152        let link = self.link(app);
3153        link.unregister_leader(app, self);
3154        ContainerLayer::detach(self, app);
3155    }
3156
3157    fn redepth_children(self: Handle<Self>, app: &mut App) {
3158        ContainerLayer::redepth_children(self, app);
3159    }
3160
3161    fn find_annotations(
3162        self: Handle<Self>,
3163        app: &App,
3164        result: &mut AnnotationSearch,
3165        local_position: Offset,
3166        only_first: bool,
3167    ) -> bool {
3168        let offset = self.offset(app);
3169        ContainerLayer::find_annotations(self, app, result, local_position - offset, only_first)
3170    }
3171
3172    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
3173        let offset = self.offset(app);
3174        if offset != Offset::ZERO {
3175            builder.push_transform(&Matrix4::translation(
3176                offset.dx() as f32,
3177                offset.dy() as f32,
3178            ));
3179        }
3180        self.as_container_layer()
3181            .add_children_to_scene(app, builder);
3182        let engine_layer = (offset != Offset::ZERO).then(|| builder.pop());
3183        self.as_layer().set_engine_layer(app, engine_layer);
3184    }
3185
3186    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
3187        ContainerLayer::fire_composition_callbacks(self, app, include_children);
3188    }
3189}
3190
3191impl ContainerLayer for LeaderLayer {
3192    crate::container_layer_accessors!();
3193
3194    /// Applies the transform that would be applied when compositing the given child to the given
3195    /// matrix.
3196    ///
3197    /// See [`ContainerLayer::apply_transform`] for details.
3198    ///
3199    /// The `child` argument may be null, as the same transform is applied to all children.
3200    fn apply_transform(
3201        self: Handle<Self>,
3202        app: &App,
3203        _child: Option<AnyLayer>,
3204        transform: &mut Matrix4,
3205    ) {
3206        let offset = self.offset(app);
3207        if offset != Offset::ZERO {
3208            *transform = transform.then(&Matrix4::translation(
3209                offset.dx() as f32,
3210                offset.dy() as f32,
3211            ));
3212        }
3213    }
3214}
3215
3216/// A composited layer that applies a transformation matrix to its children such that they are
3217/// positioned to match a [`LeaderLayer`].
3218///
3219/// If any of the ancestors of this layer have a degenerate matrix (e.g. scaling by zero), then
3220/// the [`FollowerLayer`] will not be able to transform its child to the coordinate space of the
3221/// [`LeaderLayer`].
3222///
3223/// A [`linked_offset`](FollowerLayer::linked_offset) property can be provided to further offset
3224/// the child layer from the leader layer, for example if the child is to follow the linked layer
3225/// at a distance rather than directly overlapping it.
3226pub struct FollowerLayer {
3227    layer: LayerData,
3228    container_layer: ContainerLayerData,
3229    /// `None` only while [`Layer::dispose`] takes the retain so it can [`App::release`] it
3230    /// before the arena entry is destroyed.
3231    link: Option<RetainedHandle<Handle<LayerLink>>>,
3232    show_when_unlinked: bool,
3233    unlinked_offset: Offset,
3234    linked_offset: Offset,
3235    last_offset: Option<Offset>,
3236    last_transform: Option<Matrix4>,
3237    inverted_transform: Cell<Option<Matrix4>>,
3238    inverse_dirty: Cell<bool>,
3239}
3240
3241impl FollowerLayer {
3242    /// Creates a follower layer.
3243    ///
3244    /// The [`unlinked_offset`](Self::unlinked_offset), [`linked_offset`](Self::linked_offset),
3245    /// and [`show_when_unlinked`](Self::show_when_unlinked) properties must be non-null before
3246    /// the compositing phase of the pipeline.
3247    pub fn new(app: &mut App, link: Handle<LayerLink>) -> Handle<FollowerLayer> {
3248        let link = app.retain(link);
3249        app.create(FollowerLayer {
3250            layer: LayerData::new(),
3251            container_layer: ContainerLayerData::new(),
3252            link: Some(link),
3253            show_when_unlinked: true,
3254            unlinked_offset: Offset::ZERO,
3255            linked_offset: Offset::ZERO,
3256            last_offset: None,
3257            last_transform: None,
3258            inverted_transform: Cell::new(None),
3259            inverse_dirty: Cell::new(true),
3260        })
3261    }
3262
3263    /// The link to the [`LeaderLayer`].
3264    ///
3265    /// The same object should be provided to a [`LeaderLayer`] that is earlier in the layer
3266    /// tree. When this layer is composited, it will apply a transform that moves its children
3267    /// to match the position of the [`LeaderLayer`].
3268    pub fn link(self: Handle<Self>, app: &App) -> Handle<LayerLink> {
3269        app.get(self)
3270            .link
3271            .as_ref()
3272            .expect("a FollowerLayer holds its link until dispose")
3273            .get()
3274    }
3275
3276    /// See [`link`](Self::link).
3277    pub fn set_link(self: Handle<Self>, app: &mut App, value: Handle<LayerLink>) {
3278        if self.link(app) == value {
3279            return;
3280        }
3281        let retained = app.retain(value);
3282        let old = app
3283            .get_mut(self)
3284            .link
3285            .replace(retained)
3286            .expect("a FollowerLayer holds its link until dispose");
3287        app.release(old);
3288    }
3289
3290    /// Whether to show the layer's contents when the [`link`](Self::link) does not point to a
3291    /// [`LeaderLayer`].
3292    ///
3293    /// When the layer is linked, children layers are positioned such that they have the same
3294    /// global position as the linked [`LeaderLayer`].
3295    ///
3296    /// When the layer is not linked, then: if [`show_when_unlinked`](Self::show_when_unlinked)
3297    /// is true, children are positioned as if the [`FollowerLayer`] was a [`ContainerLayer`];
3298    /// if it is false, then children are hidden.
3299    ///
3300    /// The [`show_when_unlinked`](Self::show_when_unlinked) property must be non-null before the
3301    /// compositing phase of the pipeline.
3302    pub fn show_when_unlinked(self: Handle<Self>, app: &App) -> bool {
3303        app.get(self).show_when_unlinked
3304    }
3305
3306    /// See [`show_when_unlinked`](Self::show_when_unlinked).
3307    pub fn set_show_when_unlinked(self: Handle<Self>, app: &mut App, value: bool) {
3308        app.get_mut(self).show_when_unlinked = value;
3309    }
3310
3311    /// Offset from parent in the parent's coordinate system, used when the layer is not linked
3312    /// to a [`LeaderLayer`].
3313    ///
3314    /// The scene must be explicitly recomposited after this property is changed (as described at
3315    /// [`Layer`]).
3316    ///
3317    /// The [`unlinked_offset`](Self::unlinked_offset) property must be non-null before the
3318    /// compositing phase of the pipeline.
3319    ///
3320    /// See also:
3321    ///
3322    ///  * [`linked_offset`](Self::linked_offset), for when the layers are linked.
3323    pub fn unlinked_offset(self: Handle<Self>, app: &App) -> Offset {
3324        app.get(self).unlinked_offset
3325    }
3326
3327    /// See [`unlinked_offset`](Self::unlinked_offset).
3328    pub fn set_unlinked_offset(self: Handle<Self>, app: &mut App, value: Offset) {
3329        app.get_mut(self).unlinked_offset = value;
3330    }
3331
3332    /// Offset from the origin of the leader layer to the origin of the child layers, used when
3333    /// the layer is linked to a [`LeaderLayer`].
3334    ///
3335    /// The scene must be explicitly recomposited after this property is changed (as described at
3336    /// [`Layer`]).
3337    ///
3338    /// The [`linked_offset`](Self::linked_offset) property must be non-null before the
3339    /// compositing phase of the pipeline.
3340    ///
3341    /// See also:
3342    ///
3343    ///  * [`unlinked_offset`](Self::unlinked_offset), for when the layer is not linked.
3344    pub fn linked_offset(self: Handle<Self>, app: &App) -> Offset {
3345        app.get(self).linked_offset
3346    }
3347
3348    /// See [`linked_offset`](Self::linked_offset).
3349    pub fn set_linked_offset(self: Handle<Self>, app: &mut App, value: Offset) {
3350        app.get_mut(self).linked_offset = value;
3351    }
3352
3353    fn transform_offset(self: Handle<Self>, app: &App, local_position: Offset) -> Option<Offset> {
3354        if app.get(self).inverse_dirty.get() {
3355            let last = self.get_last_transform(app).expect(
3356                "FollowerLayer._transformOffset requires getLastTransform after addToScene",
3357            );
3358            app.get(self).inverted_transform.set(last.invert());
3359            app.get(self).inverse_dirty.set(false);
3360        }
3361        let inverted = app.get(self).inverted_transform.get()?;
3362        let storage = inverted.to_flutter_array();
3363        let x = local_position.dx();
3364        let y = local_position.dy();
3365        let rx = storage[0] as f64 * x + storage[4] as f64 * y + storage[12] as f64;
3366        let ry = storage[1] as f64 * x + storage[5] as f64 * y + storage[13] as f64;
3367        let linked_offset = self.linked_offset(app);
3368        Some(Offset::new(
3369            rx - linked_offset.dx(),
3370            ry - linked_offset.dy(),
3371        ))
3372    }
3373
3374    /// The transform that was used during the last composition phase.
3375    ///
3376    /// If the [`link`](Self::link) was not linked to a [`LeaderLayer`], or if this layer has a
3377    /// degenerate matrix applied, then this will be `None`.
3378    ///
3379    /// This method returns a new [`Matrix4`] instance each time it is invoked.
3380    pub fn get_last_transform(self: Handle<Self>, app: &App) -> Option<Matrix4> {
3381        let last_transform = app.get(self).last_transform?;
3382        let last_offset = app
3383            .get(self)
3384            .last_offset
3385            .expect("lastOffset is set with lastTransform");
3386        Some(
3387            Matrix4::translation(-last_offset.dx() as f32, -last_offset.dy() as f32)
3388                .then(&last_transform),
3389        )
3390    }
3391
3392    /// Call [`ContainerLayer::apply_transform`] for each layer in the provided list.
3393    ///
3394    /// The list is in reverse order (deepest first). The first layer will be treated as the
3395    /// child of the second, and so forth. The first layer in the list won't have
3396    /// `apply_transform` called on it. The first layer may be null.
3397    fn collect_transform_for_layer_chain(
3398        app: &App,
3399        layers: &[Option<AnyContainerLayer>],
3400    ) -> Matrix4 {
3401        let mut result = Matrix4::IDENTITY;
3402        for index in (1..layers.len()).rev() {
3403            if let Some(layer) = layers[index] {
3404                let child = layers[index - 1].map(AnyContainerLayer::as_layer);
3405                layer.apply_transform(app, child, &mut result);
3406            }
3407        }
3408        result
3409    }
3410
3411    /// Find the common ancestor of two layers `a` and `b` by searching towards the root of the
3412    /// tree, and append each ancestor of `a` or `b` visited along the path to `ancestors_a` and
3413    /// `ancestors_b` respectively.
3414    ///
3415    /// Returns `None` if `a` `b` do not share a common ancestor, in which case the results in
3416    /// `ancestors_a` and `ancestors_b` are undefined.
3417    fn paths_to_common_ancestor(
3418        app: &App,
3419        a: Option<AnyLayer>,
3420        b: Option<AnyLayer>,
3421        ancestors_a: &mut Vec<Option<AnyContainerLayer>>,
3422        ancestors_b: &mut Vec<Option<AnyContainerLayer>>,
3423    ) -> Option<AnyLayer> {
3424        let (a, b) = (a?, b?);
3425        if a == b {
3426            return Some(a);
3427        }
3428        if a.depth(app) < b.depth(app) {
3429            ancestors_b.push(b.parent(app));
3430            return Self::paths_to_common_ancestor(
3431                app,
3432                Some(a),
3433                b.parent(app).map(AnyContainerLayer::as_layer),
3434                ancestors_a,
3435                ancestors_b,
3436            );
3437        } else if a.depth(app) > b.depth(app) {
3438            ancestors_a.push(a.parent(app));
3439            return Self::paths_to_common_ancestor(
3440                app,
3441                a.parent(app).map(AnyContainerLayer::as_layer),
3442                Some(b),
3443                ancestors_a,
3444                ancestors_b,
3445            );
3446        }
3447        ancestors_a.push(a.parent(app));
3448        ancestors_b.push(b.parent(app));
3449        Self::paths_to_common_ancestor(
3450            app,
3451            a.parent(app).map(AnyContainerLayer::as_layer),
3452            b.parent(app).map(AnyContainerLayer::as_layer),
3453            ancestors_a,
3454            ancestors_b,
3455        )
3456    }
3457
3458    fn debug_check_leader_before_follower(
3459        app: &App,
3460        leader_to_common_ancestor: &[Option<AnyContainerLayer>],
3461        follower_to_common_ancestor: &[Option<AnyContainerLayer>],
3462    ) -> bool {
3463        if follower_to_common_ancestor.len() <= 1 {
3464            return false;
3465        }
3466        if leader_to_common_ancestor.len() <= 1 {
3467            return true;
3468        }
3469        let leader_subtree_below_ancestor = leader_to_common_ancestor
3470            [leader_to_common_ancestor.len() - 2]
3471            .expect("the leader subtree below the ancestor is a layer");
3472        let follower_subtree_below_ancestor = follower_to_common_ancestor
3473            [follower_to_common_ancestor.len() - 2]
3474            .expect("the follower subtree below the ancestor is a layer");
3475        let mut sibling = Some(leader_subtree_below_ancestor.as_layer());
3476        while let Some(layer) = sibling {
3477            if layer == follower_subtree_below_ancestor.as_layer() {
3478                return true;
3479            }
3480            sibling = layer.next_sibling(app);
3481        }
3482        false
3483    }
3484
3485    /// Populate `_lastTransform` given the current state of the tree.
3486    fn establish_transform(self: Handle<Self>, app: &mut App) {
3487        app.get_mut(self).last_transform = None;
3488        let Some(leader) = self.link(app).leader(app) else {
3489            return;
3490        };
3491        debug_assert_eq!(
3492            leader.as_layer().owner(app),
3493            self.as_layer().owner(app),
3494            "Linked LeaderLayer anchor is not in the same layer tree as the FollowerLayer."
3495        );
3496
3497        let mut forward_layers = vec![Some(leader.as_container_layer())];
3498        let mut inverse_layers = vec![Some(self.as_container_layer())];
3499        let ancestor = Self::paths_to_common_ancestor(
3500            app,
3501            Some(leader.as_layer()),
3502            Some(self.as_layer()),
3503            &mut forward_layers,
3504            &mut inverse_layers,
3505        );
3506        debug_assert!(
3507            ancestor.is_some(),
3508            "LeaderLayer and FollowerLayer do not have a common ancestor."
3509        );
3510        debug_assert!(
3511            Self::debug_check_leader_before_follower(app, &forward_layers, &inverse_layers),
3512            "LeaderLayer anchor must come before FollowerLayer in paint order, but the reverse \
3513             was true."
3514        );
3515
3516        let mut forward_transform = Self::collect_transform_for_layer_chain(app, &forward_layers);
3517        leader
3518            .as_container_layer()
3519            .apply_transform(app, None, &mut forward_transform);
3520        let linked_offset = self.linked_offset(app);
3521        forward_transform = forward_transform.then(&Matrix4::translation(
3522            linked_offset.dx() as f32,
3523            linked_offset.dy() as f32,
3524        ));
3525
3526        let inverse_transform = Self::collect_transform_for_layer_chain(app, &inverse_layers);
3527        let Some(inverse_transform) = inverse_transform.invert() else {
3528            return;
3529        };
3530        app.get_mut(self).last_transform = Some(inverse_transform.then(&forward_transform));
3531        app.get(self).inverse_dirty.set(true);
3532    }
3533}
3534
3535impl Layer for FollowerLayer {
3536    crate::layer_accessors!(container);
3537
3538    /// A [`FollowerLayer`] copies changes from a [`LeaderLayer`] that could be anywhere in the
3539    /// layer tree, and that leader layer could change without notifying the follower layer.
3540    /// Therefore a follower layer's `add_to_scene` is always called.
3541    fn always_needs_add_to_scene(self: Handle<Self>, _app: &App) -> bool {
3542        true
3543    }
3544
3545    fn supports_rasterization(self: Handle<Self>, app: &App) -> bool {
3546        ContainerLayer::supports_rasterization(self, app)
3547    }
3548
3549    fn dispose(self: Handle<Self>, app: &mut App) {
3550        let link = app
3551            .get_mut(self)
3552            .link
3553            .take()
3554            .expect("a FollowerLayer holds its link until dispose");
3555        ContainerLayer::dispose(self, app);
3556        app.release(link);
3557    }
3558
3559    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
3560        ContainerLayer::attach(self, app, owner);
3561    }
3562
3563    fn detach(self: Handle<Self>, app: &mut App) {
3564        ContainerLayer::detach(self, app);
3565    }
3566
3567    fn redepth_children(self: Handle<Self>, app: &mut App) {
3568        ContainerLayer::redepth_children(self, app);
3569    }
3570
3571    fn find_annotations(
3572        self: Handle<Self>,
3573        app: &App,
3574        result: &mut AnnotationSearch,
3575        local_position: Offset,
3576        only_first: bool,
3577    ) -> bool {
3578        if self.link(app).leader(app).is_none() {
3579            if self.show_when_unlinked(app) {
3580                return ContainerLayer::find_annotations(
3581                    self,
3582                    app,
3583                    result,
3584                    local_position - self.unlinked_offset(app),
3585                    only_first,
3586                );
3587            }
3588            return false;
3589        }
3590        let Some(transformed_offset) = self.transform_offset(app, local_position) else {
3591            return false;
3592        };
3593        ContainerLayer::find_annotations(self, app, result, transformed_offset, only_first)
3594    }
3595
3596    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
3597        if self.link(app).leader(app).is_none() && !self.show_when_unlinked(app) {
3598            app.get_mut(self).last_transform = None;
3599            app.get_mut(self).last_offset = None;
3600            app.get(self).inverse_dirty.set(true);
3601            self.as_layer().set_engine_layer(app, None);
3602            return;
3603        }
3604        self.establish_transform(app);
3605        if app.get(self).last_transform.is_some() {
3606            let unlinked_offset = self.unlinked_offset(app);
3607            app.get_mut(self).last_offset = Some(unlinked_offset);
3608            let last_transform = app
3609                .get(self)
3610                .last_transform
3611                .expect("lastTransform was just set");
3612            builder.push_transform(&last_transform);
3613            self.as_container_layer()
3614                .add_children_to_scene(app, builder);
3615            let engine_layer = builder.pop();
3616            self.as_layer().set_engine_layer(app, Some(engine_layer));
3617        } else {
3618            app.get_mut(self).last_offset = None;
3619            let unlinked_offset = self.unlinked_offset(app);
3620            let matrix =
3621                Matrix4::translation(unlinked_offset.dx() as f32, unlinked_offset.dy() as f32);
3622            builder.push_transform(&matrix);
3623            self.as_container_layer()
3624                .add_children_to_scene(app, builder);
3625            let engine_layer = builder.pop();
3626            self.as_layer().set_engine_layer(app, Some(engine_layer));
3627        }
3628        app.get(self).inverse_dirty.set(true);
3629    }
3630
3631    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
3632        ContainerLayer::fire_composition_callbacks(self, app, include_children);
3633    }
3634}
3635
3636impl ContainerLayer for FollowerLayer {
3637    crate::container_layer_accessors!();
3638
3639    fn apply_transform(
3640        self: Handle<Self>,
3641        app: &App,
3642        child: Option<AnyLayer>,
3643        transform: &mut Matrix4,
3644    ) {
3645        debug_assert!(child.is_some());
3646        if let Some(last_transform) = app.get(self).last_transform {
3647            *transform = transform.then(&last_transform);
3648        } else {
3649            let unlinked_offset = self.unlinked_offset(app);
3650            *transform = transform.then(&Matrix4::translation(
3651                unlinked_offset.dx() as f32,
3652                unlinked_offset.dy() as f32,
3653            ));
3654        }
3655    }
3656}
3657
3658/// A composited layer which annotates its children with a value. Pushing this layer to the tree
3659/// is the common way of adding an annotation.
3660///
3661/// An annotation is an optional object of any type that, when attached with a layer, can be
3662/// retrieved using [`AnyLayer::find`] or [`AnyLayer::find_all_annotations`] with a position. The
3663/// search process is done recursively, controlled by a concept of being opaque to a type of
3664/// annotation, explained in the document of [`Layer::find_annotations`].
3665///
3666/// When an annotation search arrives, this layer defers the same search to each of this layer's
3667/// children, respecting their opacity. Then it adds this layer's annotation if all of the
3668/// following restrictions are met:
3669///
3670/// * The target type must be identical to the annotated type `T`.
3671/// * If [`size`](Self::size) is provided, the target position must be contained within the
3672///   rectangle formed by [`size`](Self::size) and [`offset`](Self::offset).
3673///
3674/// This layer is opaque to a type of annotation if any child is also opaque, or if
3675/// [`opaque`](Self::opaque) is true and the layer's annotation is added.
3676pub struct AnnotatedRegionLayer {
3677    layer: LayerData,
3678    container_layer: ContainerLayerData,
3679    value: Rc<dyn Any>,
3680    size: Option<Size>,
3681    offset: Offset,
3682    opaque: bool,
3683}
3684
3685impl AnnotatedRegionLayer {
3686    /// Creates a new layer that annotates its children with `value`.
3687    pub fn new(app: &mut App, value: Rc<dyn Any>) -> Handle<AnnotatedRegionLayer> {
3688        app.create(AnnotatedRegionLayer {
3689            layer: LayerData::new(),
3690            container_layer: ContainerLayerData::new(),
3691            value,
3692            size: None,
3693            offset: Offset::ZERO,
3694            opaque: false,
3695        })
3696    }
3697
3698    /// The annotated object, which is added to the result if all restrictions are met.
3699    pub fn value(self: Handle<Self>, app: &App) -> &Rc<dyn Any> {
3700        &app.get(self).value
3701    }
3702
3703    /// The size of the annotated object.
3704    ///
3705    /// If [`size`](Self::size) is provided, then the annotation is found only if the target
3706    /// position is contained by the rectangle formed by [`size`](Self::size) and
3707    /// [`offset`](Self::offset). Otherwise no such restriction is applied, and clipping can only
3708    /// be done by the ancestor layers.
3709    pub fn size(self: Handle<Self>, app: &App) -> Option<Size> {
3710        app.get(self).size
3711    }
3712
3713    /// See [`size`](Self::size).
3714    pub fn set_size(self: Handle<Self>, app: &mut App, value: Option<Size>) {
3715        app.get_mut(self).size = value;
3716    }
3717
3718    /// The position of the annotated object.
3719    ///
3720    /// The [`offset`](Self::offset) defaults to [`Offset::ZERO`] if not provided, and is ignored
3721    /// if [`size`](Self::size) is not set.
3722    ///
3723    /// The [`offset`](Self::offset) only offsets the clipping rectangle, and does not affect how
3724    /// the painting or annotation search is propagated to its children.
3725    pub fn offset(self: Handle<Self>, app: &App) -> Offset {
3726        app.get(self).offset
3727    }
3728
3729    /// See [`offset`](Self::offset).
3730    pub fn set_offset(self: Handle<Self>, app: &mut App, value: Offset) {
3731        app.get_mut(self).offset = value;
3732    }
3733
3734    /// Whether the annotation of this layer should be opaque during an annotation search of type
3735    /// `T`, preventing siblings visually behind it from being searched.
3736    ///
3737    /// If [`opaque`](Self::opaque) is true, and this layer does add its annotation
3738    /// [`value`](Self::value), then the layer will always be opaque during the search.
3739    ///
3740    /// If [`opaque`](Self::opaque) is false, or if this layer does not add its annotation, then
3741    /// the opacity of this layer will be the one returned by the children, meaning that it will
3742    /// be opaque if any child is opaque.
3743    ///
3744    /// The [`opaque`](Self::opaque) defaults to false.
3745    ///
3746    /// The [`opaque`](Self::opaque) is effectively useless during [`AnyLayer::find`] (more
3747    /// specifically, [`Layer::find_annotations`] with `only_first: true`), since the search
3748    /// process then skips the remaining tree after finding the first annotation.
3749    ///
3750    /// See also:
3751    ///
3752    ///  * [`Layer::find_annotations`], which explains the concept of being opaque to a type of
3753    ///    annotation as the return value.
3754    ///  * `HitTestBehavior`, which controls similar logic when hit-testing in the render tree.
3755    pub fn opaque(self: Handle<Self>, app: &App) -> bool {
3756        app.get(self).opaque
3757    }
3758
3759    /// See [`opaque`](Self::opaque).
3760    pub fn set_opaque(self: Handle<Self>, app: &mut App, value: bool) {
3761        app.get_mut(self).opaque = value;
3762    }
3763}
3764
3765impl Layer for AnnotatedRegionLayer {
3766    crate::layer_accessors!(container);
3767
3768    fn supports_rasterization(self: Handle<Self>, app: &App) -> bool {
3769        ContainerLayer::supports_rasterization(self, app)
3770    }
3771
3772    fn dispose(self: Handle<Self>, app: &mut App) {
3773        ContainerLayer::dispose(self, app);
3774    }
3775
3776    fn attach(self: Handle<Self>, app: &mut App, owner: HandleId) {
3777        ContainerLayer::attach(self, app, owner);
3778    }
3779
3780    fn detach(self: Handle<Self>, app: &mut App) {
3781        ContainerLayer::detach(self, app);
3782    }
3783
3784    fn redepth_children(self: Handle<Self>, app: &mut App) {
3785        ContainerLayer::redepth_children(self, app);
3786    }
3787
3788    /// Searches the subtree for annotations of the searched type at the location `local_position`,
3789    /// then adds the annotation [`value`](Self::value) if applicable.
3790    ///
3791    /// This method always searches its children, and if any child returns `true`, the remaining
3792    /// children are skipped. Regardless of what the children return, this method then adds this
3793    /// layer's annotation if all of the following restrictions are met:
3794    ///
3795    /// * The target type must be identical to the annotated type `T`.
3796    /// * If [`size`](Self::size) is provided, the target position must be contained within the
3797    ///   rectangle formed by [`size`](Self::size) and [`offset`](Self::offset).
3798    ///
3799    /// This search process respects `only_first`, meaning that when `only_first` is true, the
3800    /// search will stop when it finds the first annotation from the children, and the layer's
3801    /// own annotation is checked only when none is given by the children.
3802    ///
3803    /// The return value is true if any child returns `true`, or if [`opaque`](Self::opaque) is
3804    /// true and the layer's annotation is added.
3805    ///
3806    /// For explanation of layer annotations, parameters and return value, refer to
3807    /// [`Layer::find_annotations`].
3808    fn find_annotations(
3809        self: Handle<Self>,
3810        app: &App,
3811        result: &mut AnnotationSearch,
3812        local_position: Offset,
3813        only_first: bool,
3814    ) -> bool {
3815        let mut is_absorbed =
3816            ContainerLayer::find_annotations(self, app, result, local_position, only_first);
3817        if !result.is_empty() && only_first {
3818            return is_absorbed;
3819        }
3820        let (value, size, offset, opaque) = {
3821            let this = app.get(self);
3822            (Rc::clone(&this.value), this.size, this.offset, this.opaque)
3823        };
3824        if let Some(size) = size
3825            && !(offset & size).contains(local_position)
3826        {
3827            return is_absorbed;
3828        }
3829        if result.accepts(&*value) {
3830            is_absorbed = is_absorbed || opaque;
3831            result.add(value, local_position - offset);
3832        }
3833        is_absorbed
3834    }
3835
3836    fn add_to_scene(self: Handle<Self>, app: &mut App, builder: &mut SceneBuilder) {
3837        ContainerLayer::add_to_scene(self, app, builder);
3838    }
3839
3840    fn fire_composition_callbacks(self: Handle<Self>, app: &mut App, include_children: bool) {
3841        ContainerLayer::fire_composition_callbacks(self, app, include_children);
3842    }
3843}
3844
3845impl ContainerLayer for AnnotatedRegionLayer {
3846    crate::container_layer_accessors!();
3847}
3848
3849#[cfg(test)]
3850mod tests {
3851    use inset_foundation::AppCell;
3852
3853    use super::*;
3854
3855    fn offset_layer(app: &mut App) -> AnyLayer {
3856        OffsetLayer::new(app, Offset::ZERO).as_layer()
3857    }
3858
3859    #[test]
3860    fn append_links_children_in_order_and_adopts_them() {
3861        let cell = AppCell::new();
3862        let mut app = cell.borrow_mut();
3863        let parent = OffsetLayer::new(&mut app, Offset::ZERO).as_container_layer();
3864        let a = offset_layer(&mut app);
3865        let b = offset_layer(&mut app);
3866        parent.append(&mut app, a);
3867        parent.append(&mut app, b);
3868        assert_eq!(parent.first_child(&app), Some(a));
3869        assert_eq!(parent.last_child(&app), Some(b));
3870        assert_eq!(a.next_sibling(&app), Some(b));
3871        assert_eq!(b.previous_sibling(&app), Some(a));
3872        assert_eq!(a.parent(&app), Some(parent));
3873        assert_eq!(a.depth(&app), 1);
3874        assert_eq!(a.debug_handle_count(&app), 1, "the parent handle");
3875    }
3876
3877    #[test]
3878    fn a_layer_is_disposed_when_its_last_handle_is_released() {
3879        let cell = AppCell::new();
3880        let mut app = cell.borrow_mut();
3881        let layer = offset_layer(&mut app);
3882        let handle = app.create(LayerHandle::<AnyLayer>::new());
3883        LayerHandle::set_layer(&mut app, |app| app.get_mut(handle), Some(layer));
3884        assert_eq!(layer.debug_handle_count(&app), 1);
3885        LayerHandle::set_layer(&mut app, |app| app.get_mut(handle), None);
3886        assert!(layer.debug_disposed(&app));
3887        assert!(
3888            !app.contains(layer.id()),
3889            "dispose destroys the arena entry"
3890        );
3891    }
3892
3893    #[test]
3894    fn removing_a_child_releases_the_parent_handle_and_disposes_it() {
3895        let cell = AppCell::new();
3896        let mut app = cell.borrow_mut();
3897        let parent = OffsetLayer::new(&mut app, Offset::ZERO).as_container_layer();
3898        let child = offset_layer(&mut app);
3899        parent.append(&mut app, child);
3900        child.remove(&mut app);
3901        assert!(!parent.has_children(&app));
3902        assert!(child.debug_disposed(&app));
3903    }
3904
3905    #[test]
3906    fn a_child_kept_by_another_handle_survives_removal() {
3907        let cell = AppCell::new();
3908        let mut app = cell.borrow_mut();
3909        let parent = OffsetLayer::new(&mut app, Offset::ZERO).as_container_layer();
3910        let child = offset_layer(&mut app);
3911        let handle = app.create(LayerHandle::<AnyLayer>::new());
3912        LayerHandle::set_layer(&mut app, |app| app.get_mut(handle), Some(child));
3913        parent.append(&mut app, child);
3914        child.remove(&mut app);
3915        assert!(!child.debug_disposed(&app));
3916        assert_eq!(child.parent(&app), None);
3917        LayerHandle::set_layer(&mut app, |app| app.get_mut(handle), None);
3918        assert!(child.debug_disposed(&app));
3919    }
3920
3921    #[test]
3922    fn attach_and_detach_walk_the_subtree() {
3923        let cell = AppCell::new();
3924        let mut app = cell.borrow_mut();
3925        let owner = app.create(());
3926        let root = OffsetLayer::new(&mut app, Offset::ZERO).as_container_layer();
3927        let child = offset_layer(&mut app);
3928        root.append(&mut app, child);
3929        root.as_layer().attach(&mut app, owner.id());
3930        assert!(child.attached(&app));
3931        let late = offset_layer(&mut app);
3932        root.append(&mut app, late);
3933        assert!(
3934            late.attached(&app),
3935            "appending to an attached tree attaches"
3936        );
3937        root.as_layer().detach(&mut app);
3938        assert!(!child.attached(&app));
3939        assert!(!late.attached(&app));
3940    }
3941
3942    #[test]
3943    fn disposing_a_container_disposes_children_it_alone_held() {
3944        let cell = AppCell::new();
3945        let mut app = cell.borrow_mut();
3946        let parent = OffsetLayer::new(&mut app, Offset::ZERO).as_container_layer();
3947        let child = offset_layer(&mut app);
3948        parent.append(&mut app, child);
3949        let handle = app.create(LayerHandle::<AnyContainerLayer>::new());
3950        LayerHandle::set_layer(&mut app, |app| app.get_mut(handle), Some(parent));
3951        LayerHandle::set_layer(&mut app, |app| app.get_mut(handle), None);
3952        assert!(parent.as_layer().debug_disposed(&app));
3953        assert!(child.debug_disposed(&app));
3954    }
3955
3956    #[test]
3957    fn a_picture_layer_is_a_leaf_that_holds_its_picture() {
3958        let cell = AppCell::new();
3959        let mut app = cell.borrow_mut();
3960        let layer = PictureLayer::new(&mut app, Rect::from_ltwh(0.0, 0.0, 10.0, 10.0));
3961        let picture = Arc::new(inset_embedder::Canvas::new().build());
3962        layer.set_picture(&mut app, Some(picture));
3963        assert!(layer.picture(&app).is_some());
3964        assert!(layer.as_layer().as_container_layer().is_none());
3965        let mut builder = SceneBuilder::new();
3966        layer.as_layer().add_to_scene(&mut app, &mut builder);
3967        let _scene = builder.build();
3968    }
3969
3970    #[test]
3971    fn composition_callbacks_fire_on_build_scene_and_detach() {
3972        use std::cell::Cell;
3973        let cell = AppCell::new();
3974        let mut app = cell.borrow_mut();
3975        let owner = app.create(());
3976        let root = OffsetLayer::new(&mut app, Offset::ZERO).as_container_layer();
3977        let child = offset_layer(&mut app);
3978        root.append(&mut app, child);
3979        let fired = Rc::new(Cell::new(0));
3980        let remove = {
3981            let fired = Rc::clone(&fired);
3982            child
3983                .add_composition_callback(&mut app, Rc::new(move |_, _| fired.set(fired.get() + 1)))
3984        };
3985        assert!(root.as_layer().subtree_has_composition_callbacks(&app));
3986        let _scene = root.build_scene(&mut app, SceneBuilder::new());
3987        assert_eq!(fired.get(), 1);
3988        root.as_layer().attach(&mut app, owner.id());
3989        root.as_layer().detach(&mut app);
3990        assert_eq!(fired.get(), 2, "detach fires once more");
3991        remove(&mut app);
3992        assert!(!root.as_layer().subtree_has_composition_callbacks(&app));
3993    }
3994
3995    #[test]
3996    fn find_walks_children_back_to_front_through_offsets() {
3997        struct Tag(&'static str);
3998        struct Annotated {
3999            layer: LayerData,
4000            tag: Rc<Tag>,
4001        }
4002        impl Layer for Annotated {
4003            crate::layer_accessors!();
4004            fn find_annotations(
4005                self: Handle<Self>,
4006                app: &App,
4007                result: &mut AnnotationSearch,
4008                local_position: Offset,
4009                _only_first: bool,
4010            ) -> bool {
4011                let tag = Rc::clone(&app.get(self).tag);
4012                if result.accepts(&*tag) {
4013                    result.add(tag, local_position);
4014                }
4015                false
4016            }
4017            fn add_to_scene(self: Handle<Self>, _app: &mut App, _builder: &mut SceneBuilder) {}
4018        }
4019        let cell = AppCell::new();
4020        let mut app = cell.borrow_mut();
4021        let root = OffsetLayer::new(&mut app, Offset::new(10.0, 0.0)).as_container_layer();
4022        for name in ["back", "front"] {
4023            let layer = app.create(Annotated {
4024                layer: LayerData::new(),
4025                tag: Rc::new(Tag(name)),
4026            });
4027            root.append(&mut app, layer.as_layer());
4028        }
4029        let found = root.as_layer().find::<Tag>(&app, Offset::new(15.0, 5.0));
4030        assert_eq!(found.map(|tag| tag.0), Some("front"));
4031        let all = root
4032            .as_layer()
4033            .find_all_annotations::<Tag>(&app, Offset::new(15.0, 5.0));
4034        assert_eq!(all.entries().len(), 2);
4035        assert_eq!(all.entries()[0].local_position, Offset::new(5.0, 5.0));
4036        assert!(root.as_layer().find::<String>(&app, Offset::ZERO).is_none());
4037    }
4038
4039    /// An opacity layer over one leaf under a root, with a frame's scene built: the shape
4040    /// retained rendering acts on.
4041    /// A picture layer that draws a square: content a scene keeps, where it
4042    /// drops a subtree that draws nothing.
4043    fn drawn_layer(app: &mut App) -> AnyLayer {
4044        let square = Rect::from_ltwh(0.0, 0.0, 10.0, 10.0);
4045        let mut canvas = inset_embedder::Canvas::new();
4046        canvas.draw_rect(square, &inset_embedder::Paint::default());
4047        let layer = PictureLayer::new(app, square);
4048        layer.set_picture(app, Some(Arc::new(canvas.build())));
4049        layer.as_layer()
4050    }
4051
4052    fn retained_tree(app: &mut App) -> (Handle<OffsetLayer>, Handle<OpacityLayer>) {
4053        let root = OffsetLayer::new(app, Offset::ZERO);
4054        let opacity = OpacityLayer::new(app);
4055        opacity.set_alpha(app, 128);
4056        let leaf = drawn_layer(app);
4057        opacity.as_container_layer().append(app, leaf);
4058        root.as_container_layer().append(app, opacity.as_layer());
4059        let _scene = root
4060            .as_container_layer()
4061            .build_scene(app, SceneBuilder::new());
4062        (root, opacity)
4063    }
4064
4065    /// A surface's layer is retained with its ancestors, as Flutter's `PlatformViewLayer` is:
4066    /// the scene keeps it, and its placement is worked out from the tree every frame.
4067    #[test]
4068    fn a_surface_layer_is_retained_and_its_surface_placed_every_frame() {
4069        let cell = AppCell::new();
4070        let mut app = cell.borrow_mut();
4071        let root = OffsetLayer::new(&mut app, Offset::new(10.0, 5.0));
4072        let inner = OffsetLayer::new(&mut app, Offset::ZERO);
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        inner
4080            .as_container_layer()
4081            .append(&mut app, layer.as_layer());
4082        root.as_container_layer().append(&mut app, inner.as_layer());
4083        let mut first_engine_layer = None;
4084        for _frame in 0..2 {
4085            let scene = root
4086                .as_container_layer()
4087                .build_scene(&mut app, SceneBuilder::new());
4088            let placement = inset_embedder::slices(&scene)
4089                .surfaces()
4090                .next()
4091                .cloned()
4092                .expect("placed");
4093            assert!(Arc::ptr_eq(&placement.surface, &surface));
4094            assert_eq!(placement.bounds(), Rect::from_ltwh(11.0, 7.0, 30.0, 20.0));
4095            let engine_layer = inner.as_layer().engine_layer(&app).expect("recorded");
4096            let first = first_engine_layer.get_or_insert_with(|| Arc::clone(&engine_layer));
4097            assert!(Arc::ptr_eq(first, &engine_layer), "retained");
4098        }
4099        assert!(!layer.as_layer().always_needs_add_to_scene(&app));
4100    }
4101
4102    #[test]
4103    fn an_unchanged_subtree_is_retained_across_scenes() {
4104        let cell = AppCell::new();
4105        let mut app = cell.borrow_mut();
4106        let (root, opacity) = retained_tree(&mut app);
4107        let recorded = opacity.as_layer().engine_layer(&app).expect("recorded");
4108        assert!(!opacity.as_layer().needs_add_to_scene(&app));
4109
4110        let scene = root
4111            .as_container_layer()
4112            .build_scene(&mut app, SceneBuilder::new());
4113        let retained = opacity.as_layer().engine_layer(&app).expect("recorded");
4114        assert!(
4115            Arc::ptr_eq(&recorded, &retained),
4116            "the same node is retained"
4117        );
4118        let root_node = root
4119            .as_layer()
4120            .engine_layer(&app)
4121            .expect("the root is built again");
4122        assert!(
4123            root_node.children.iter().any(|child| matches!(
4124                child,
4125                inset_embedder::Layer::Container(container) if Arc::ptr_eq(container, &retained)
4126            )),
4127            "added again: {:?}",
4128            root_node.children
4129        );
4130        assert_eq!(
4131            inset_embedder::flattened_ops(&inset_embedder::slices(&scene).picture_with_room())
4132                .iter()
4133                .filter(|op| matches!(op, inset_embedder::valo::Op::SaveLayer { .. }))
4134                .count(),
4135            1,
4136            "the retained opacity layer still draws"
4137        );
4138    }
4139
4140    #[test]
4141    fn a_changed_property_re_records_the_subtree() {
4142        let cell = AppCell::new();
4143        let mut app = cell.borrow_mut();
4144        let (root, opacity) = retained_tree(&mut app);
4145        let recorded = opacity.as_layer().engine_layer(&app).expect("recorded");
4146
4147        opacity.set_alpha(&mut app, 200);
4148        assert!(opacity.as_layer().needs_add_to_scene(&app));
4149        let _scene = root
4150            .as_container_layer()
4151            .build_scene(&mut app, SceneBuilder::new());
4152        let again = opacity.as_layer().engine_layer(&app).expect("recorded");
4153        assert!(
4154            !Arc::ptr_eq(&recorded, &again),
4155            "a new node for the new alpha"
4156        );
4157        assert!(!opacity.as_layer().needs_add_to_scene(&app));
4158    }
4159
4160    #[test]
4161    fn appending_a_child_marks_the_parent_and_its_ancestors_at_build() {
4162        let cell = AppCell::new();
4163        let mut app = cell.borrow_mut();
4164        let (root, opacity) = retained_tree(&mut app);
4165        assert!(!root.as_layer().needs_add_to_scene(&app));
4166
4167        let leaf = offset_layer(&mut app);
4168        opacity.as_container_layer().append(&mut app, leaf);
4169        assert!(opacity.as_layer().needs_add_to_scene(&app));
4170        assert!(
4171            !root.as_layer().needs_add_to_scene(&app),
4172            "the mark does not climb until the scene is built"
4173        );
4174        root.as_layer().update_subtree_needs_add_to_scene(&mut app);
4175        assert!(root.as_layer().needs_add_to_scene(&app));
4176    }
4177
4178    #[test]
4179    fn a_follower_layer_always_re_records() {
4180        let cell = AppCell::new();
4181        let mut app = cell.borrow_mut();
4182        let link = LayerLink::new(&mut app);
4183        let follower = FollowerLayer::new(&mut app, link);
4184        let child = offset_layer(&mut app);
4185        follower.as_container_layer().append(&mut app, child);
4186        for _ in 0..2 {
4187            let _scene = follower
4188                .as_container_layer()
4189                .build_scene(&mut app, SceneBuilder::new());
4190            assert!(
4191                follower.as_layer().needs_add_to_scene(&app)
4192                    || follower.as_layer().always_needs_add_to_scene(&app)
4193            );
4194        }
4195        let first = follower.as_layer().engine_layer(&app).expect("recorded");
4196        let _scene = follower
4197            .as_container_layer()
4198            .build_scene(&mut app, SceneBuilder::new());
4199        let second = follower.as_layer().engine_layer(&app).expect("recorded");
4200        assert!(!Arc::ptr_eq(&first, &second), "never retained");
4201    }
4202
4203    fn tag(app: &mut App, n: u32) -> Handle<AnnotatedRegionLayer> {
4204        AnnotatedRegionLayer::new(app, Rc::new(n))
4205    }
4206
4207    #[test]
4208    fn clip_layers_reject_annotations_outside_the_clip() {
4209        let cell = AppCell::new();
4210        let mut app = cell.borrow_mut();
4211        let rect = ClipRectLayer::new(&mut app);
4212        rect.set_clip_rect(&mut app, Some(Rect::from_ltwh(0.0, 0.0, 50.0, 50.0)));
4213        let child = tag(&mut app, 7);
4214        rect.as_container_layer().append(&mut app, child.as_layer());
4215        assert_eq!(
4216            rect.as_layer()
4217                .find::<u32>(&app, Offset::new(10.0, 10.0))
4218                .as_deref(),
4219            Some(&7)
4220        );
4221        assert!(
4222            rect.as_layer()
4223                .find::<u32>(&app, Offset::new(60.0, 10.0))
4224                .is_none(),
4225            "outside the clip"
4226        );
4227
4228        let rrect = ClipRRectLayer::new(&mut app);
4229        rrect.set_clip_rrect(
4230            &mut app,
4231            Some(RRect::from_rect_and_radius(
4232                Rect::from_ltwh(0.0, 0.0, 50.0, 50.0),
4233                inset_embedder::Radius::circular(4.0),
4234            )),
4235        );
4236        let child = tag(&mut app, 8);
4237        rrect
4238            .as_container_layer()
4239            .append(&mut app, child.as_layer());
4240        assert_eq!(
4241            rrect
4242                .as_layer()
4243                .find::<u32>(&app, Offset::new(10.0, 10.0))
4244                .as_deref(),
4245            Some(&8)
4246        );
4247        assert!(
4248            rrect
4249                .as_layer()
4250                .find::<u32>(&app, Offset::new(60.0, 10.0))
4251                .is_none()
4252        );
4253
4254        let mut path = inset_embedder::PathBuilder::new();
4255        path.rect(Rect::from_ltwh(0.0, 0.0, 50.0, 50.0).into());
4256        let clip_path = ClipPathLayer::new(&mut app);
4257        clip_path.set_clip_path(&mut app, Some(path.build()));
4258        let child = tag(&mut app, 9);
4259        clip_path
4260            .as_container_layer()
4261            .append(&mut app, child.as_layer());
4262        assert_eq!(
4263            clip_path
4264                .as_layer()
4265                .find::<u32>(&app, Offset::new(10.0, 10.0))
4266                .as_deref(),
4267            Some(&9)
4268        );
4269        assert!(
4270            clip_path
4271                .as_layer()
4272                .find::<u32>(&app, Offset::new(60.0, 10.0))
4273                .is_none()
4274        );
4275    }
4276
4277    #[test]
4278    fn transform_layer_transforms_the_annotation_position() {
4279        let cell = AppCell::new();
4280        let mut app = cell.borrow_mut();
4281        let layer = TransformLayer::new(&mut app);
4282        layer.set_transform(&mut app, Matrix4::translation(10.0, 0.0));
4283        let region = tag(&mut app, 7);
4284        region.set_size(&mut app, Some(Size::new(20.0, 20.0)));
4285        layer
4286            .as_container_layer()
4287            .append(&mut app, region.as_layer());
4288        assert!(
4289            layer
4290                .as_layer()
4291                .find::<u32>(&app, Offset::new(15.0, 5.0))
4292                .is_some()
4293        );
4294        assert!(
4295            layer
4296                .as_layer()
4297                .find::<u32>(&app, Offset::new(5.0, 5.0))
4298                .is_none(),
4299            "left of the translated region"
4300        );
4301    }
4302
4303    #[test]
4304    fn opacity_layer_build_scene_succeeds_at_255_and_128() {
4305        let cell = AppCell::new();
4306        let mut app = cell.borrow_mut();
4307        for alpha in [255, 128] {
4308            let layer = OpacityLayer::new(&mut app);
4309            layer.set_alpha(&mut app, alpha);
4310            let child = OffsetLayer::new(&mut app, Offset::ZERO);
4311            layer
4312                .as_container_layer()
4313                .append(&mut app, child.as_layer());
4314            let _scene = layer
4315                .as_container_layer()
4316                .build_scene(&mut app, SceneBuilder::new());
4317        }
4318        let empty = OpacityLayer::new(&mut app);
4319        empty.set_alpha(&mut app, 128);
4320        let _scene = empty
4321            .as_container_layer()
4322            .build_scene(&mut app, SceneBuilder::new());
4323    }
4324
4325    #[test]
4326    fn layer_link_register_unregister_and_leader_getter() {
4327        let cell = AppCell::new();
4328        let mut app = cell.borrow_mut();
4329        let owner = app.create(());
4330        let link = LayerLink::new(&mut app);
4331        assert!(link.leader(&app).is_none());
4332        let leader = LeaderLayer::new(&mut app, link);
4333        leader.as_layer().attach(&mut app, owner.id());
4334        assert_eq!(link.leader(&app), Some(leader));
4335        leader.as_layer().detach(&mut app);
4336        assert!(link.leader(&app).is_none());
4337    }
4338
4339    #[test]
4340    fn leader_layer_attach_registers_and_detach_unregisters() {
4341        let cell = AppCell::new();
4342        let mut app = cell.borrow_mut();
4343        let owner = app.create(());
4344        let root = OffsetLayer::new(&mut app, Offset::ZERO);
4345        let link = LayerLink::new(&mut app);
4346        let leader = LeaderLayer::new(&mut app, link);
4347        root.as_container_layer()
4348            .append(&mut app, leader.as_layer());
4349        root.as_layer().attach(&mut app, owner.id());
4350        assert_eq!(link.leader(&app), Some(leader));
4351        root.as_layer().detach(&mut app);
4352        assert!(link.leader(&app).is_none());
4353    }
4354
4355    #[test]
4356    fn a_replaced_leader_leaves_the_links_new_leader_in_place() {
4357        let cell = AppCell::new();
4358        let mut app = cell.borrow_mut();
4359        let owner = app.create(());
4360        let link = LayerLink::new(&mut app);
4361        let leader1 = LeaderLayer::new(&mut app, link);
4362        let leader2 = LeaderLayer::new(&mut app, link);
4363        leader1.as_layer().attach(&mut app, owner.id());
4364        leader2.as_layer().attach(&mut app, owner.id());
4365        assert_eq!(link.leader(&app), Some(leader2));
4366        leader2.as_layer().detach(&mut app);
4367        leader1.as_layer().detach(&mut app);
4368        assert!(link.leader(&app).is_none());
4369    }
4370
4371    #[test]
4372    fn switching_the_link_of_an_attached_leader_does_not_crash() {
4373        let cell = AppCell::new();
4374        let mut app = cell.borrow_mut();
4375        let owner = app.create(());
4376        let link = LayerLink::new(&mut app);
4377        let leader = LeaderLayer::new(&mut app, link);
4378        leader.as_layer().attach(&mut app, owner.id());
4379        let link2 = LayerLink::new(&mut app);
4380        leader.set_link(&mut app, link2);
4381        leader.as_layer().detach(&mut app);
4382        assert_eq!(leader.link(&app), link2);
4383        assert!(link.leader(&app).is_none());
4384        assert!(link2.leader(&app).is_none());
4385    }
4386
4387    #[test]
4388    fn follower_get_last_transform_after_build_scene_matches_the_leader_offset() {
4389        let cell = AppCell::new();
4390        let mut app = cell.borrow_mut();
4391        let owner = app.create(());
4392        let root = OffsetLayer::new(&mut app, Offset::ZERO);
4393        let link = LayerLink::new(&mut app);
4394        let leader = LeaderLayer::new(&mut app, link);
4395        leader.set_offset(&mut app, Offset::new(10.0, 20.0));
4396        let follower = FollowerLayer::new(&mut app, link);
4397        root.as_container_layer()
4398            .append(&mut app, leader.as_layer());
4399        root.as_container_layer()
4400            .append(&mut app, follower.as_layer());
4401        root.as_layer().attach(&mut app, owner.id());
4402        let _scene = root
4403            .as_container_layer()
4404            .build_scene(&mut app, SceneBuilder::new());
4405        assert_eq!(
4406            follower.get_last_transform(&app).unwrap(),
4407            Matrix4::translation(10.0, 20.0)
4408        );
4409    }
4410
4411    #[test]
4412    fn follower_with_show_when_unlinked_false_pushes_nothing() {
4413        let cell = AppCell::new();
4414        let mut app = cell.borrow_mut();
4415        let link = LayerLink::new(&mut app);
4416        let follower = FollowerLayer::new(&mut app, link);
4417        follower.set_show_when_unlinked(&mut app, false);
4418        let child = offset_layer(&mut app);
4419        follower.as_container_layer().append(&mut app, child);
4420        let _scene = follower
4421            .as_container_layer()
4422            .build_scene(&mut app, SceneBuilder::new());
4423        assert!(follower.get_last_transform(&app).is_none());
4424    }
4425
4426    #[test]
4427    fn annotated_region_layer_find_with_size_offset_and_opaque() {
4428        let cell = AppCell::new();
4429        let mut app = cell.borrow_mut();
4430        let root = OffsetLayer::new(&mut app, Offset::ZERO);
4431        let behind = tag(&mut app, 1);
4432        let front = tag(&mut app, 2);
4433        front.set_opaque(&mut app, true);
4434        root.as_container_layer()
4435            .append(&mut app, behind.as_layer());
4436        root.as_container_layer().append(&mut app, front.as_layer());
4437        let result = root
4438            .as_layer()
4439            .find_all_annotations::<u32>(&app, Offset::ZERO);
4440        assert_eq!(
4441            result
4442                .annotations()
4443                .map(|value| **value)
4444                .collect::<Vec<_>>(),
4445            vec![2],
4446            "an opaque region hides its siblings"
4447        );
4448
4449        let root = OffsetLayer::new(&mut app, Offset::ZERO);
4450        let first = tag(&mut app, 1);
4451        let second = tag(&mut app, 2);
4452        root.as_container_layer().append(&mut app, first.as_layer());
4453        root.as_container_layer()
4454            .append(&mut app, second.as_layer());
4455        let result = root
4456            .as_layer()
4457            .find_all_annotations::<u32>(&app, Offset::ZERO);
4458        assert_eq!(
4459            result
4460                .annotations()
4461                .map(|value| **value)
4462                .collect::<Vec<_>>(),
4463            vec![2, 1],
4464            "front to back when neither is opaque"
4465        );
4466
4467        let sized = tag(&mut app, 3);
4468        sized.set_size(&mut app, Some(Size::new(20.0, 20.0)));
4469        sized.set_offset(&mut app, Offset::new(90.0, 90.0));
4470        assert!(
4471            sized
4472                .as_layer()
4473                .find::<u32>(&app, Offset::new(95.0, 95.0))
4474                .is_some()
4475        );
4476        assert!(
4477            sized.as_layer().find::<u32>(&app, Offset::ZERO).is_none(),
4478            "outside the sized region"
4479        );
4480    }
4481}