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