1//! A compositor is responsible for initializing a renderer and managing window
2//! surfaces.
3use crate::core::Color;
4use crate::futures::{MaybeSend, MaybeSync};
5use crate::{Error, Settings, Viewport};
67use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
8use thiserror::Error;
910use std::borrow::Cow;
1112/// A graphics compositor that can draw to windows.
13pub trait Compositor: Sized {
14/// The iced renderer of the backend.
15type Renderer;
1617/// The surface of the backend.
18type Surface;
1920/// Creates a new [`Compositor`].
21fn new<W: Window + Clone>(
22 settings: Settings,
23 compatible_window: W,
24 ) -> impl Future<Output = Result<Self, Error>> {
25Self::with_backend(settings, compatible_window, None)
26 }
2728/// Creates a new [`Compositor`] with a backend preference.
29 ///
30 /// If the backend does not match the preference, it will return
31 /// [`Error::GraphicsAdapterNotFound`].
32fn with_backend<W: Window + Clone>(
33 _settings: Settings,
34 _compatible_window: W,
35 _backend: Option<&str>,
36 ) -> impl Future<Output = Result<Self, Error>>;
3738/// Creates a [`Self::Renderer`] for the [`Compositor`].
39fn create_renderer(&self) -> Self::Renderer;
4041/// Crates a new [`Surface`] for the given window.
42 ///
43 /// [`Surface`]: Self::Surface
44fn create_surface<W: Window + Clone>(
45&mut self,
46 window: W,
47 width: u32,
48 height: u32,
49 ) -> Self::Surface;
5051/// Configures a new [`Surface`] with the given dimensions.
52 ///
53 /// [`Surface`]: Self::Surface
54fn configure_surface(
55&mut self,
56 surface: &mut Self::Surface,
57 width: u32,
58 height: u32,
59 );
6061/// Returns [`Information`] used by this [`Compositor`].
62fn fetch_information(&self) -> Information;
6364/// Loads a font from its bytes.
65fn load_font(&mut self, font: Cow<'static, [u8]>) {
66crate::text::font_system()
67 .write()
68 .expect("Write to font system")
69 .load_font(font);
70 }
7172/// Presents the [`Renderer`] primitives to the next frame of the given [`Surface`].
73 ///
74 /// [`Renderer`]: Self::Renderer
75 /// [`Surface`]: Self::Surface
76fn present<T: AsRef<str>>(
77&mut self,
78 renderer: &mut Self::Renderer,
79 surface: &mut Self::Surface,
80 viewport: &Viewport,
81 background_color: Color,
82 overlay: &[T],
83 ) -> Result<(), SurfaceError>;
8485/// Screenshots the current [`Renderer`] primitives to an offscreen texture, and returns the bytes of
86 /// the texture ordered as `RGBA` in the `sRGB` color space.
87 ///
88 /// [`Renderer`]: Self::Renderer
89fn screenshot<T: AsRef<str>>(
90&mut self,
91 renderer: &mut Self::Renderer,
92 viewport: &Viewport,
93 background_color: Color,
94 overlay: &[T],
95 ) -> Vec<u8>;
96}
9798/// A window that can be used in a [`Compositor`].
99///
100/// This is just a convenient super trait of the `raw-window-handle`
101/// traits.
102pub trait Window:
103 HasWindowHandle + HasDisplayHandle + MaybeSend + MaybeSync + 'static
104{
105}
106107impl<T> Window for T where
108T: HasWindowHandle + HasDisplayHandle + MaybeSend + MaybeSync + 'static
109{
110}
111112/// Defines the default compositor of a renderer.
113pub trait Default {
114/// The compositor of the renderer.
115type Compositor: Compositor<Renderer = Self>;
116}
117118/// Result of an unsuccessful call to [`Compositor::present`].
119#[derive(Clone, PartialEq, Eq, Debug, Error)]
120pub enum SurfaceError {
121/// A timeout was encountered while trying to acquire the next frame.
122#[error("A timeout was encountered while trying to acquire the next frame")]
123Timeout,
124/// The underlying surface has changed, and therefore the surface must be updated.
125#[error(
126"The underlying surface has changed, and therefore the surface must be updated."
127)]
128Outdated,
129/// The swap chain has been lost and needs to be recreated.
130#[error("The surface has been lost and needs to be recreated")]
131Lost,
132/// There is no more memory left to allocate a new frame.
133#[error("There is no more memory left to allocate a new frame")]
134OutOfMemory,
135/// Acquiring a texture failed with a generic error.
136#[error("Acquiring a texture failed with a generic error")]
137Other,
138}
139140/// Contains information about the graphics (e.g. graphics adapter, graphics backend).
141#[derive(Debug)]
142pub struct Information {
143/// Contains the graphics adapter.
144pub adapter: String,
145/// Contains the graphics backend.
146pub backend: String,
147}
148149#[cfg(debug_assertions)]
150impl Compositor for () {
151type Renderer = ();
152type Surface = ();
153154async fn with_backend<W: Window + Clone>(
155 _settings: Settings,
156 _compatible_window: W,
157 _preferred_backend: Option<&str>,
158 ) -> Result<Self, Error> {
159Ok(())
160 }
161162fn create_renderer(&self) -> Self::Renderer {}
163164fn create_surface<W: Window + Clone>(
165&mut self,
166 _window: W,
167 _width: u32,
168 _height: u32,
169 ) -> Self::Surface {
170 }
171172fn configure_surface(
173&mut self,
174 _surface: &mut Self::Surface,
175 _width: u32,
176 _height: u32,
177 ) {
178 }
179180fn load_font(&mut self, _font: Cow<'static, [u8]>) {}
181182fn fetch_information(&self) -> Information {
183 Information {
184 adapter: String::from("Null Renderer"),
185 backend: String::from("Null"),
186 }
187 }
188189fn present<T: AsRef<str>>(
190&mut self,
191 _renderer: &mut Self::Renderer,
192 _surface: &mut Self::Surface,
193 _viewport: &Viewport,
194 _background_color: Color,
195 _overlay: &[T],
196 ) -> Result<(), SurfaceError> {
197Ok(())
198 }
199200fn screenshot<T: AsRef<str>>(
201&mut self,
202 _renderer: &mut Self::Renderer,
203 _viewport: &Viewport,
204 _background_color: Color,
205 _overlay: &[T],
206 ) -> Vec<u8> {
207vec![]
208 }
209}
210211#[cfg(debug_assertions)]
212impl Default for () {
213type Compositor = ();
214}