1use std::fmt::Debug;
6use std::num::NonZeroU32;
7use std::sync::atomic::{AtomicUsize, Ordering};
8
9use euclid::{Rect, Size2D};
10use malloc_size_of_derive::MallocSizeOf;
11use serde::{Deserialize, Serialize};
12
13use crate::{Error, Viewport, Viewports};
14
15#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
16pub struct ContextId(pub u64);
17
18pub trait GLTypes {
19 type Device;
20 type Context;
21 type Bindings;
22}
23
24pub trait GLContexts<GL: GLTypes> {
25 fn device(&self, context_id: ContextId) -> Option<GL::Device>;
26 fn bindings(&mut self, context_id: ContextId) -> Option<&GL::Bindings>;
27 fn context(&mut self, context_id: ContextId) -> Option<&mut GL::Context>;
28}
29
30impl GLTypes for () {
31 type Bindings = ();
32 type Device = ();
33 type Context = ();
34}
35
36impl GLContexts<()> for () {
37 fn device(&self, _: ContextId) -> Option<()> {
38 Some(())
39 }
40
41 fn context(&mut self, _: ContextId) -> Option<&mut ()> {
42 Some(self)
43 }
44
45 fn bindings(&mut self, _: ContextId) -> Option<&()> {
46 Some(self)
47 }
48}
49
50pub trait LayerGrandManagerAPI<GL: GLTypes> {
51 fn create_layer_manager(&self, factory: LayerManagerFactory<GL>)
52 -> Result<LayerManager, Error>;
53
54 fn clone_layer_grand_manager(&self) -> LayerGrandManager<GL>;
55}
56
57pub struct LayerGrandManager<GL>(Box<dyn Send + LayerGrandManagerAPI<GL>>);
58
59impl<GL: GLTypes> Clone for LayerGrandManager<GL> {
60 fn clone(&self) -> Self {
61 self.0.clone_layer_grand_manager()
62 }
63}
64
65impl<GL> Debug for LayerGrandManager<GL> {
66 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
67 "LayerGrandManager(...)".fmt(fmt)
68 }
69}
70
71impl<GL: GLTypes> LayerGrandManager<GL> {
72 pub fn new<GM>(grand_manager: GM) -> LayerGrandManager<GL>
73 where
74 GM: 'static + Send + LayerGrandManagerAPI<GL>,
75 {
76 LayerGrandManager(Box::new(grand_manager))
77 }
78
79 pub fn create_layer_manager<F, M>(&self, factory: F) -> Result<LayerManager, Error>
80 where
81 F: 'static + Send + FnOnce(&mut dyn GLContexts<GL>) -> Result<M, Error>,
82 M: 'static + LayerManagerAPI<GL>,
83 {
84 self.0
85 .create_layer_manager(LayerManagerFactory::new(factory))
86 }
87}
88
89pub trait LayerManagerAPI<GL: GLTypes> {
90 fn create_layer(
91 &mut self,
92 contexts: &mut dyn GLContexts<GL>,
93 context_id: ContextId,
94 init: LayerInit,
95 ) -> Result<LayerId, Error>;
96
97 fn destroy_layer(
98 &mut self,
99 contexts: &mut dyn GLContexts<GL>,
100 context_id: ContextId,
101 layer_id: LayerId,
102 );
103
104 fn layers(&self) -> &[(ContextId, LayerId)];
105
106 fn begin_frame(
107 &mut self,
108 contexts: &mut dyn GLContexts<GL>,
109 layers: &[(ContextId, LayerId)],
110 ) -> Result<Vec<SubImages>, Error>;
111
112 fn end_frame(
113 &mut self,
114 contexts: &mut dyn GLContexts<GL>,
115 layers: &[(ContextId, LayerId)],
116 ) -> Result<(), Error>;
117}
118
119pub struct LayerManager(Box<dyn Send + LayerManagerAPI<()>>);
120
121impl Debug for LayerManager {
122 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
123 "LayerManager(...)".fmt(fmt)
124 }
125}
126
127impl LayerManager {
128 pub fn create_layer(
129 &mut self,
130 context_id: ContextId,
131 init: LayerInit,
132 ) -> Result<LayerId, Error> {
133 self.0.create_layer(&mut (), context_id, init)
134 }
135
136 pub fn destroy_layer(&mut self, context_id: ContextId, layer_id: LayerId) {
137 self.0.destroy_layer(&mut (), context_id, layer_id);
138 }
139
140 pub fn begin_frame(
141 &mut self,
142 layers: &[(ContextId, LayerId)],
143 ) -> Result<Vec<SubImages>, Error> {
144 self.0.begin_frame(&mut (), layers)
145 }
146
147 pub fn end_frame(&mut self, layers: &[(ContextId, LayerId)]) -> Result<(), Error> {
148 self.0.end_frame(&mut (), layers)
149 }
150}
151
152impl LayerManager {
153 pub fn new<M>(manager: M) -> LayerManager
154 where
155 M: 'static + Send + LayerManagerAPI<()>,
156 {
157 LayerManager(Box::new(manager))
158 }
159}
160
161impl Drop for LayerManager {
162 fn drop(&mut self) {
163 log::debug!("Dropping LayerManager");
164 let layers: Vec<_> = self.0.layers().to_vec();
165 for (context_id, layer_id) in layers.into_iter() {
166 self.destroy_layer(context_id, layer_id);
167 }
168 }
169}
170
171#[expect(clippy::type_complexity)]
172pub struct LayerManagerFactory<GL: GLTypes>(
173 Box<dyn Send + FnOnce(&mut dyn GLContexts<GL>) -> Result<Box<dyn LayerManagerAPI<GL>>, Error>>,
174);
175
176impl<GL: GLTypes> Debug for LayerManagerFactory<GL> {
177 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
178 "LayerManagerFactory(...)".fmt(fmt)
179 }
180}
181
182impl<GL: GLTypes> LayerManagerFactory<GL> {
183 pub fn new<F, M>(factory: F) -> LayerManagerFactory<GL>
184 where
185 F: 'static + Send + FnOnce(&mut dyn GLContexts<GL>) -> Result<M, Error>,
186 M: 'static + LayerManagerAPI<GL>,
187 {
188 LayerManagerFactory(Box::new(move |contexts| Ok(Box::new(factory(contexts)?))))
189 }
190
191 pub fn build(
192 self,
193 contexts: &mut dyn GLContexts<GL>,
194 ) -> Result<Box<dyn LayerManagerAPI<GL>>, Error> {
195 (self.0)(contexts)
196 }
197}
198
199#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Deserialize, Serialize, MallocSizeOf)]
200pub struct LayerId(usize);
201
202static NEXT_LAYER_ID: AtomicUsize = AtomicUsize::new(0);
203
204impl Default for LayerId {
205 fn default() -> Self {
206 LayerId(NEXT_LAYER_ID.fetch_add(1, Ordering::SeqCst))
207 }
208}
209
210#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
211pub enum LayerInit {
212 WebGLLayer {
214 antialias: bool,
215 depth: bool,
216 stencil: bool,
217 alpha: bool,
218 ignore_depth_values: bool,
219 framebuffer_scale_factor: f32,
220 },
221 ProjectionLayer {
223 depth: bool,
224 stencil: bool,
225 alpha: bool,
226 scale_factor: f32,
227 },
228 }
230
231impl LayerInit {
232 pub fn texture_size(&self, viewports: &Viewports) -> Size2D<i32, Viewport> {
233 match self {
234 LayerInit::WebGLLayer {
235 framebuffer_scale_factor: scale,
236 ..
237 } |
238 LayerInit::ProjectionLayer {
239 scale_factor: scale,
240 ..
241 } => {
242 let native_size = viewports
243 .viewports
244 .iter()
245 .fold(Rect::zero(), |acc, view| acc.union(view))
246 .size;
247 (native_size.to_f32() * *scale).to_i32()
248 },
249 }
250 }
251}
252
253#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
255pub enum LayerLayout {
256 Mono,
259 StereoLeftRight,
261 StereoTopBottom,
263}
264
265#[derive(Clone, Debug, Deserialize, Serialize, MallocSizeOf)]
266pub struct SubImages {
267 pub layer_id: LayerId,
268 pub sub_image: Option<SubImage>,
269 pub view_sub_images: Vec<SubImage>,
270}
271
272#[derive(Clone, Debug, Deserialize, Serialize, MallocSizeOf)]
274pub struct SubImage {
275 pub color_texture: Option<NonZeroU32>,
276 pub depth_stencil_texture: Option<NonZeroU32>,
277 pub texture_array_index: Option<u32>,
278 pub viewport: Rect<i32, Viewport>,
279}