1use crate::core;
4use crate::core::Color;
5use crate::core::font;
6use crate::core::renderer;
7use crate::futures::{MaybeSend, MaybeSync};
8use crate::{Antialiasing, Error, Shell, Viewport};
9
10use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
11use thiserror::Error;
12
13use std::borrow::Cow;
14
15pub trait Compositor: Sized {
17 type Renderer;
19
20 type Surface;
22
23 fn new(
25 settings: Settings,
26 display: impl Display + Clone,
27 compatible_window: impl Window + Clone,
28 shell: Shell,
29 ) -> impl Future<Output = Result<Self, Error>> {
30 Self::with_backend(settings, display, compatible_window, shell, None)
31 }
32
33 fn with_backend(
38 settings: Settings,
39 display: impl Display + Clone,
40 compatible_window: impl Window + Clone,
41 shell: Shell,
42 backend: Option<&str>,
43 ) -> impl Future<Output = Result<Self, Error>>;
44
45 fn create_renderer(&self, settings: renderer::Settings) -> Self::Renderer;
47
48 fn create_surface<W: Window + Clone>(
52 &mut self,
53 window: W,
54 width: u32,
55 height: u32,
56 ) -> Self::Surface;
57
58 fn configure_surface(&mut self, surface: &mut Self::Surface, width: u32, height: u32);
62
63 fn information(&self) -> Information;
65
66 fn load_font(&mut self, font: Cow<'static, [u8]>) -> Result<(), font::Error> {
68 crate::text::font_system()
69 .write()
70 .expect("Write to font system")
71 .load_font(font);
72
73 Ok(())
75 }
76
77 fn list_fonts(&mut self) -> Result<Vec<font::Family>, font::Error> {
79 use std::collections::BTreeSet;
80
81 let font_system = crate::text::font_system()
82 .read()
83 .expect("Read from font system");
84
85 let families = BTreeSet::from_iter(font_system.families());
86
87 Ok(families.into_iter().map(font::Family::name).collect())
88 }
89
90 fn present(
95 &mut self,
96 renderer: &mut Self::Renderer,
97 surface: &mut Self::Surface,
98 viewport: &Viewport,
99 background_color: Color,
100 on_pre_present: impl FnOnce(),
101 ) -> Result<(), SurfaceError>;
102
103 fn screenshot(
108 &mut self,
109 renderer: &mut Self::Renderer,
110 viewport: &Viewport,
111 background_color: Color,
112 ) -> Vec<u8>;
113}
114
115#[derive(Debug, Clone, Copy, PartialEq)]
117pub struct Settings {
118 pub antialiasing: Option<Antialiasing>,
122
123 pub vsync: bool,
127}
128
129impl ::core::default::Default for Settings {
130 fn default() -> Settings {
131 Settings {
132 antialiasing: None,
133 vsync: true,
134 }
135 }
136}
137
138impl From<&core::Settings> for Settings {
139 fn from(settings: &core::Settings) -> Self {
140 Self {
141 antialiasing: settings.antialiasing.then_some(Antialiasing::MSAAx4),
142 vsync: settings.vsync,
143 }
144 }
145}
146
147pub trait Window: HasWindowHandle + HasDisplayHandle + MaybeSend + MaybeSync + 'static {}
152
153impl<T> Window for T where T: HasWindowHandle + HasDisplayHandle + MaybeSend + MaybeSync + 'static {}
154
155pub trait Display: HasDisplayHandle + MaybeSend + MaybeSync + 'static {}
160
161impl<T> Display for T where T: HasDisplayHandle + MaybeSend + MaybeSync + 'static {}
162
163pub trait Default {
165 type Compositor: Compositor<Renderer = Self>;
167}
168
169#[derive(Clone, PartialEq, Eq, Debug, Error)]
171pub enum SurfaceError {
172 #[error("A timeout was encountered while trying to acquire the next frame")]
174 Timeout,
175 #[error("The underlying surface has changed, and therefore the surface must be updated.")]
177 Outdated,
178 #[error("The surface has been lost and needs to be recreated")]
180 Lost,
181 #[error("There is no more memory left to allocate a new frame")]
183 OutOfMemory,
184 #[error("Acquiring a texture failed with a generic error")]
186 Other,
187}
188
189#[derive(Debug)]
191pub struct Information {
192 pub adapter: String,
194 pub backend: String,
196}
197
198#[cfg(debug_assertions)]
199impl Compositor for () {
200 type Renderer = ();
201 type Surface = ();
202
203 async fn with_backend(
204 _settings: Settings,
205 _display: impl Display,
206 _compatible_window: impl Window + Clone,
207 _shell: Shell,
208 _preferred_backend: Option<&str>,
209 ) -> Result<Self, Error> {
210 Ok(())
211 }
212
213 fn create_renderer(&self, _settings: renderer::Settings) -> Self::Renderer {}
214
215 fn create_surface<W: Window + Clone>(
216 &mut self,
217 _window: W,
218 _width: u32,
219 _height: u32,
220 ) -> Self::Surface {
221 }
222
223 fn configure_surface(&mut self, _surface: &mut Self::Surface, _width: u32, _height: u32) {}
224
225 fn load_font(&mut self, _font: Cow<'static, [u8]>) -> Result<(), font::Error> {
226 Ok(())
227 }
228
229 fn list_fonts(&mut self) -> Result<Vec<font::Family>, font::Error> {
230 Ok(Vec::new())
231 }
232
233 fn information(&self) -> Information {
234 Information {
235 adapter: String::from("Null Renderer"),
236 backend: String::from("Null"),
237 }
238 }
239
240 fn present(
241 &mut self,
242 _renderer: &mut Self::Renderer,
243 _surface: &mut Self::Surface,
244 _viewport: &Viewport,
245 _background_color: Color,
246 _on_pre_present: impl FnOnce(),
247 ) -> Result<(), SurfaceError> {
248 Ok(())
249 }
250
251 fn screenshot(
252 &mut self,
253 _renderer: &mut Self::Renderer,
254 _viewport: &Viewport,
255 _background_color: Color,
256 ) -> Vec<u8> {
257 vec![]
258 }
259}
260
261#[cfg(debug_assertions)]
262impl Default for () {
263 type Compositor = ();
264}