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;
11use std::future::Future;
1213/// A graphics compositor that can draw to windows.
14pub trait Compositor: Sized {
15/// The iced renderer of the backend.
16type Renderer;
1718/// The surface of the backend.
19type Surface;
2021/// Creates a new [`Compositor`].
22fn new<W: Window + Clone>(
23 settings: Settings,
24 compatible_window: W,
25 ) -> impl Future<Output = Result<Self, Error>> {
26Self::with_backend(settings, compatible_window, None)
27 }
2829/// Creates a new [`Compositor`] with a backend preference.
30 ///
31 /// If the backend does not match the preference, it will return
32 /// [`Error::GraphicsAdapterNotFound`].
33fn with_backend<W: Window + Clone>(
34 _settings: Settings,
35 _compatible_window: W,
36 _backend: Option<&str>,
37 ) -> impl Future<Output = Result<Self, Error>>;
3839/// Creates a [`Self::Renderer`] for the [`Compositor`].
40fn create_renderer(&self) -> Self::Renderer;
4142/// Crates a new [`Surface`] for the given window.
43 ///
44 /// [`Surface`]: Self::Surface
45fn create_surface<W: Window + Clone>(
46&mut self,
47 window: W,
48 width: u32,
49 height: u32,
50 ) -> Self::Surface;
5152/// Configures a new [`Surface`] with the given dimensions.
53 ///
54 /// [`Surface`]: Self::Surface
55fn configure_surface(
56&mut self,
57 surface: &mut Self::Surface,
58 width: u32,
59 height: u32,
60 );
6162/// Returns [`Information`] used by this [`Compositor`].
63fn fetch_information(&self) -> Information;
6465/// Loads a font from its bytes.
66fn load_font(&mut self, font: Cow<'static, [u8]>) {
67crate::text::font_system()
68 .write()
69 .expect("Write to font system")
70 .load_font(font);
71 }
7273/// Presents the [`Renderer`] primitives to the next frame of the given [`Surface`].
74 ///
75 /// [`Renderer`]: Self::Renderer
76 /// [`Surface`]: Self::Surface
77fn present<T: AsRef<str>>(
78&mut self,
79 renderer: &mut Self::Renderer,
80 surface: &mut Self::Surface,
81 viewport: &Viewport,
82 background_color: Color,
83 overlay: &[T],
84 ) -> Result<(), SurfaceError>;
8586/// Screenshots the current [`Renderer`] primitives to an offscreen texture, and returns the bytes of
87 /// the texture ordered as `RGBA` in the `sRGB` color space.
88 ///
89 /// [`Renderer`]: Self::Renderer
90fn screenshot<T: AsRef<str>>(
91&mut self,
92 renderer: &mut Self::Renderer,
93 viewport: &Viewport,
94 background_color: Color,
95 overlay: &[T],
96 ) -> Vec<u8>;
97}
9899/// A window that can be used in a [`Compositor`].
100///
101/// This is just a convenient super trait of the `raw-window-handle`
102/// traits.
103pub trait Window:
104 HasWindowHandle + HasDisplayHandle + MaybeSend + MaybeSync + 'static
105{
106}
107108impl<T> Window for T where
109T: HasWindowHandle + HasDisplayHandle + MaybeSend + MaybeSync + 'static
110{
111}
112113/// Defines the default compositor of a renderer.
114pub trait Default {
115/// The compositor of the renderer.
116type Compositor: Compositor<Renderer = Self>;
117}
118119/// Result of an unsuccessful call to [`Compositor::present`].
120#[derive(Clone, PartialEq, Eq, Debug, Error)]
121pub enum SurfaceError {
122/// A timeout was encountered while trying to acquire the next frame.
123#[error(
124"A timeout was encountered while trying to acquire the next frame"
125)]
126Timeout,
127/// The underlying surface has changed, and therefore the surface must be updated.
128#[error(
129"The underlying surface has changed, and therefore the surface must be updated."
130)]
131Outdated,
132/// The swap chain has been lost and needs to be recreated.
133#[error("The surface has been lost and needs to be recreated")]
134Lost,
135/// There is no more memory left to allocate a new frame.
136#[error("There is no more memory left to allocate a new frame")]
137OutOfMemory,
138/// Resize Error
139#[error("Resize Error")]
140Resize,
141/// Invalid dimensions
142#[error("Invalid dimensions")]
143InvalidDimensions,
144/// Present Error
145#[error("Present Error")]
146Present(String),
147/// Present Error
148#[error("No damage to present")]
149NoDamage,
150}
151152/// Contains information about the graphics (e.g. graphics adapter, graphics backend).
153#[derive(Debug)]
154pub struct Information {
155/// Contains the graphics adapter.
156pub adapter: String,
157/// Contains the graphics backend.
158pub backend: String,
159}
160161#[cfg(debug_assertions)]
162impl Compositor for () {
163type Renderer = ();
164type Surface = ();
165166async fn with_backend<W: Window + Clone>(
167 _settings: Settings,
168 _compatible_window: W,
169 _preferred_backend: Option<&str>,
170 ) -> Result<Self, Error> {
171Ok(())
172 }
173174fn create_renderer(&self) -> Self::Renderer {}
175176fn create_surface<W: Window + Clone>(
177&mut self,
178 _window: W,
179 _width: u32,
180 _height: u32,
181 ) -> Self::Surface {
182 }
183184fn configure_surface(
185&mut self,
186 _surface: &mut Self::Surface,
187 _width: u32,
188 _height: u32,
189 ) {
190 }
191192fn load_font(&mut self, _font: Cow<'static, [u8]>) {}
193194fn fetch_information(&self) -> Information {
195 Information {
196 adapter: String::from("Null Renderer"),
197 backend: String::from("Null"),
198 }
199 }
200201fn present<T: AsRef<str>>(
202&mut self,
203 _renderer: &mut Self::Renderer,
204 _surface: &mut Self::Surface,
205 _viewport: &Viewport,
206 _background_color: Color,
207 _overlay: &[T],
208 ) -> Result<(), SurfaceError> {
209Ok(())
210 }
211212fn screenshot<T: AsRef<str>>(
213&mut self,
214 _renderer: &mut Self::Renderer,
215 _viewport: &Viewport,
216 _background_color: Color,
217 _overlay: &[T],
218 ) -> Vec<u8> {
219vec![]
220 }
221}
222223#[cfg(debug_assertions)]
224impl Default for () {
225type Compositor = ();
226}