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