1use euclid::{Point2D, RigidTransform3D};
8use profile_traits::generic_callback::GenericCallback as ProfileGenericCallback;
9
10use crate::{
11 ContextId, EnvironmentBlendMode, Error, Event, Floor, Frame, HitTestId, HitTestSource,
12 InputSource, LayerId, LayerInit, Native, Quitter, Session, SessionBuilder, SessionInit,
13 SessionMode, Viewports,
14};
15
16pub trait DiscoveryAPI<GL>: 'static {
18 fn request_session(
19 &mut self,
20 mode: SessionMode,
21 init: &SessionInit,
22 xr: SessionBuilder<GL>,
23 ) -> Result<Session, Error>;
24 fn supports_session(&self, mode: SessionMode) -> bool;
25}
26
27pub trait DeviceAPI: 'static {
29 fn create_layer(&mut self, context_id: ContextId, init: LayerInit) -> Result<LayerId, Error>;
31
32 fn destroy_layer(&mut self, context_id: ContextId, layer_id: LayerId);
34
35 fn floor_transform(&self) -> Option<RigidTransform3D<f32, Native, Floor>>;
37
38 fn viewports(&self) -> Viewports;
39
40 fn begin_animation_frame(&mut self, layers: &[(ContextId, LayerId)]) -> Option<Frame>;
42
43 fn end_animation_frame(&mut self, layers: &[(ContextId, LayerId)]);
45
46 fn initial_inputs(&self) -> Vec<InputSource>;
49
50 fn set_event_dest(&mut self, dest: ProfileGenericCallback<Event>);
52
53 fn quit(&mut self);
55
56 fn set_quitter(&mut self, quitter: Quitter);
57
58 fn update_clip_planes(&mut self, near: f32, far: f32);
59
60 fn environment_blend_mode(&self) -> EnvironmentBlendMode {
61 EnvironmentBlendMode::Opaque
63 }
64
65 fn granted_features(&self) -> &[String];
66
67 fn request_hit_test(&mut self, _source: HitTestSource) {
68 panic!("This device does not support requesting hit tests");
69 }
70
71 fn cancel_hit_test(&mut self, _id: HitTestId) {
72 panic!("This device does not support hit tests");
73 }
74
75 fn update_frame_rate(&mut self, rate: f32) -> f32 {
76 rate
77 }
78
79 fn supported_frame_rates(&self) -> Vec<f32> {
80 Vec::new()
81 }
82
83 fn reference_space_bounds(&self) -> Option<Vec<Point2D<f32, Floor>>> {
84 None
85 }
86}
87
88impl<GL: 'static> DiscoveryAPI<GL> for Box<dyn DiscoveryAPI<GL>> {
89 fn request_session(
90 &mut self,
91 mode: SessionMode,
92 init: &SessionInit,
93 xr: SessionBuilder<GL>,
94 ) -> Result<Session, Error> {
95 (**self).request_session(mode, init, xr)
96 }
97
98 fn supports_session(&self, mode: SessionMode) -> bool {
99 (**self).supports_session(mode)
100 }
101}