Skip to main content

ferroui_base/rendering/composition/
mod.rs

1//! The composition renderer.
2//!
3//! # Architecture and threading
4//!
5//! As upstream, there are two compositors. The [`Compositor`] lives on the
6//! UI thread together with the composition objects; the
7//! [`server::ServerCompositor`] owns the server-side counterparts of those
8//! objects and renders them. They exchange data in one direction only,
9//! through batches: at commit the UI-thread compositor serializes the
10//! changes of its objects into a [`transport::CommittedBatch`] and enqueues
11//! it; at the start of each frame the server compositor applies the queued
12//! batches.
13//!
14//! The object model of the UI thread is `Rc`-based and thread-affine, so
15//! the two sides are kept apart by construction rather than by locks:
16//!
17//! * UI-thread objects never hold their server counterpart. They hold a
18//!   [`server::ServerObjectId`], a plain value. A server object is created
19//!   by the server compositor itself, from a factory carried by the batch
20//!   ([`Compositor::create_server_object`]); changes and disposal refer to
21//!   it by id. Server objects therefore need not be `Send`: they are
22//!   created, mutated and dropped on the render thread only.
23//! * The batch queue ([`server::BatchQueue`]) is the only crossing point.
24//!   What may cross is exactly what a [`transport::BatchObject`] can hold
25//!   plus plain values.
26//! * The few values the UI thread reads back (the clock, the readback
27//!   indices, batch completion) are `Send + Sync` types shared through
28//!   `Arc`.
29//!
30//! Today the server compositor runs on the thread of its compositor in
31//! every configuration: the render loop may tick on any thread (its tasks
32//! are `Send + Sync`), and a tick that arrives elsewhere is marshalled to
33//! the compositor's dispatcher. Running the server on a dedicated render
34//! thread is blocked by one thing outside this module: the platform
35//! resource handles carried by batches (`std::sync::Arc<dyn IGeometryImpl>`,
36//! `std::sync::Arc<crate::platform::SharedBitmapImpl>`, `std::sync::Arc<dyn IGlyphRunImpl>`, immutable brushes and
37//! pens) are `Rc`-based and so are the render contracts the server draws
38//! with. Once those are shareable across threads, the remaining steps are
39//! local: require `Send` on the `Job`, `Create` and `Value` payloads of
40//! `BatchObject`, make the batch queue a mutex-protected queue, and
41//! construct the server compositor on the render thread. No `unsafe` is
42//! used anywhere in the composition renderer.
43//!
44//! The browser target has no threads; it uses the same single-thread mode
45//! with a UI-thread render timer.
46
47pub mod animations;
48pub mod brushes;
49pub mod drawing;
50pub mod expressions;
51pub mod generated;
52pub mod hit_testing;
53pub mod server;
54#[cfg(any(test, feature = "testing"))]
55pub mod testing;
56pub mod transport;
57
58mod composition_cache_mode;
59mod composition_custom_visual;
60mod composition_custom_visual_handler;
61mod composition_draw_list_visual;
62mod composition_drawing_surface;
63mod composition_external_memory;
64mod composition_interop;
65mod composition_experimental_acrylic_visual;
66mod composition_gradient_stop;
67mod composition_object;
68mod composition_options;
69mod composition_property_set;
70mod composition_solid_color_visual;
71mod composition_surface;
72mod composition_surface_visual;
73mod composition_target;
74mod compositing_renderer;
75mod compositor_factories;
76mod container_visual;
77mod element_composition_preview;
78mod visual;
79mod visual_collection;
80mod composition_transparency_level;
81mod compositor;
82mod enums;
83mod i_composition_object_host;
84mod i_composition_target_debug_events;
85mod i_compositor_serializable;
86mod matrix_utils;
87mod render_interface_feature;
88
89pub use composition_cache_mode::{CompositionBitmapCache, CompositionCacheMode};
90pub use composition_custom_visual::CompositionCustomVisual;
91pub use composition_custom_visual_handler::{CompositionCustomVisualHandler, ICompositionCustomVisualHandler};
92pub use composition_drawing_surface::CompositionDrawingSurface;
93pub use composition_external_memory::{
94    CompositionGpuImportedImageSynchronizationCapabilities, ICompositionGpuImportedObject, ICompositionGpuInterop,
95    ICompositionImportableSharedGpuContextImage, ICompositionImportableSharedGpuContextObject,
96    ICompositionImportableSharedGpuContextSemaphore, ICompositionImportedGpuImage, ICompositionImportedGpuSemaphore,
97};
98pub use composition_interop::{
99    CompositionGpuImportedObjectBase, CompositionImportedGpuImage, CompositionImportedGpuSemaphore, CompositionInterop,
100    IServerGpuImportedObject, ServerGpuImportedObjectBase, ServerImportedGpuImage,
101    ServerImportedGpuSemaphore,
102};
103pub use composition_draw_list_visual::{CompositionDrawListVisual, ICompositionDrawListVisualExtension};
104pub use brushes::{
105    CompositionBrush, CompositionConicGradientBrush, CompositionGradientBrush, CompositionLinearGradientBrush,
106    CompositionRadialGradientBrush, CompositionSolidColorBrush,
107};
108pub use composition_experimental_acrylic_visual::CompositionExperimentalAcrylicVisual;
109pub use composition_gradient_stop::CompositionGradientStop;
110pub use composition_object::{AsCompositionObject, CompositionObject, ICompositionObjectAnimations};
111pub use composition_options::CompositionOptions;
112pub use composition_property_set::{CompositionGetValueStatus, CompositionPropertySet};
113pub use composition_solid_color_visual::CompositionSolidColorVisual;
114pub use composition_surface::CompositionSurface;
115pub use composition_surface_visual::CompositionSurfaceVisual;
116pub use composition_target::CompositionTarget;
117pub use compositing_renderer::CompositingRenderer;
118pub use container_visual::CompositionContainerVisual;
119pub use element_composition_preview::ElementComposition;
120pub use server::RenderSurfaces;
121pub use visual::CompositionVisual;
122pub use visual_collection::CompositionVisualCollection;
123pub use composition_transparency_level::CompositionTransparencyLevel;
124pub use compositor::{
125    CompositionVisualSnapshotError, Compositor, ICompositorScheduler, LocalFuture, ServerJobError, ServerJobTask,
126};
127pub use enums::{CompositionBlendMode, CompositionGradientExtendMode, CompositionStretch, CompositionTileMode};
128pub use i_composition_object_host::{ICompositionObject, ICompositionObjectHost, PendingAnimations};
129pub use i_composition_target_debug_events::ICompositionTargetDebugEvents;
130pub use i_compositor_serializable::ICompositorSerializable;
131pub use matrix_utils::MatrixUtils;
132pub use render_interface_feature::RenderInterfaceFeature;
133// The key frame animation classes are generated into the namespace of the
134// compositor upstream.
135pub use animations::{
136    BooleanKeyFrameAnimation, ColorKeyFrameAnimation, DoubleKeyFrameAnimation, QuaternionKeyFrameAnimation,
137    RelativePointKeyFrameAnimation, RelativeScalarKeyFrameAnimation, ScalarKeyFrameAnimation, Vector2KeyFrameAnimation,
138    Vector3DKeyFrameAnimation, Vector3KeyFrameAnimation, Vector4KeyFrameAnimation, VectorKeyFrameAnimation,
139};
140
141#[cfg(test)]
142mod compositor_tests;
143#[cfg(test)]
144mod render_thread_tests;
145#[cfg(test)]
146mod composition_drawing_surface_tests;
147#[cfg(test)]
148pub(crate) mod test_compositor;