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