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