Skip to main content

inset_rendering/
layer.rs

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