Skip to main content

inset_embedder/
composition.rs

1//! Native surfaces the OS compositor shows beside the framework's picture: the capability a
2//! host with a compositor hands out, and the surface a producer feeds from a thread of its
3//! own. The macOS host's `os/macos/composition` module, in `inset-embedder-winit`, says why it is
4//! shaped as it is. A producer that paces by the screen's refreshes waits on the platform's
5//! [`VsyncWaiter`](crate::VsyncWaiter).
6//!
7//! The invariant: a surface is on screen only where a frame's [`Scene`](crate::Scene) places
8//! it, and the host, not the framework, owns the native object behind it.
9
10use std::any::Any;
11use std::sync::Arc;
12
13use crate::ViewId;
14
15/// The host's compositor, as an app reaches it.
16pub trait Compositor: Send + Sync {
17    /// A surface of `view`'s, shown wherever a frame's scene places it, fed by a producer
18    /// from any thread. `opaque` says whether its buffers carry alpha the compositor must
19    /// blend. The surface goes when its last handle does: the producer's, and those of the
20    /// frames that place it.
21    fn open_surface(&self, view: ViewId, opaque: bool) -> Arc<dyn Surface>;
22}
23
24/// One surface. Every method may be called from any thread.
25///
26/// The handle is the surface's identity: a scene places the `Arc` itself, so only a surface
27/// that exists can be placed, and it lives while anything shows it. A host gets its own
28/// type back from a placed surface by downcasting through `Any`.
29pub trait Surface: Any + Send + Sync {
30    /// Shows `buffer` from the compositor's next frame on. Returns once the host holds the
31    /// buffer, not once it is on screen. `released` runs, on any thread, when the compositor
32    /// has finished with the buffer and the producer may draw into it again. On Apple
33    /// platforms the host learns that from `IOSurfaceIsInUse` at the surface's next present,
34    /// or when the surface goes, so a producer there never waits for a buffer to come back: it
35    /// draws into one it knows is free, or a new one.
36    fn present(&self, buffer: Buffer, released: Box<dyn FnOnce() + Send + Sync>);
37}
38
39/// What a producer draws into and hands over: the platform's own type.
40#[cfg(target_vendor = "apple")]
41pub type Buffer = objc2_core_foundation::CFRetained<objc2_io_surface::IOSurfaceRef>;
42
43/// A platform with no host that composites: no buffer can exist, so
44/// [`Surface::present`] cannot be called, and [`Platform::compositor`](crate::Platform::compositor)
45/// answers `None`.
46#[cfg(not(target_vendor = "apple"))]
47pub enum Buffer {}