script/dom/webxr/
xrrenderstate.rs1use std::cell::Cell;
6
7use dom_struct::dom_struct;
8use js::rust::MutableHandleValue;
9use script_bindings::cell::DomRefCell;
10use script_bindings::reflector::{Reflector, reflect_dom_object};
11use webxr_api::SubImages;
12
13use crate::dom::bindings::codegen::Bindings::XRRenderStateBinding::XRRenderStateMethods;
14use crate::dom::bindings::num::Finite;
15use crate::dom::bindings::reflector::DomGlobal;
16use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
17use crate::dom::bindings::utils::to_frozen_array;
18use crate::dom::window::Window;
19use crate::dom::xrlayer::XRLayer;
20use crate::dom::xrwebgllayer::XRWebGLLayer;
21use crate::script_runtime::{CanGc, JSContext};
22
23#[dom_struct]
24pub(crate) struct XRRenderState {
25 reflector_: Reflector,
26 depth_near: Cell<f64>,
27 depth_far: Cell<f64>,
28 inline_vertical_fov: Cell<Option<f64>>,
29 base_layer: MutNullableDom<XRWebGLLayer>,
30 layers: DomRefCell<Vec<Dom<XRLayer>>>,
31}
32
33impl XRRenderState {
34 pub(crate) fn new_inherited(
35 depth_near: f64,
36 depth_far: f64,
37 inline_vertical_fov: Option<f64>,
38 layer: Option<&XRWebGLLayer>,
39 layers: Vec<&XRLayer>,
40 ) -> XRRenderState {
41 debug_assert!(layer.is_none() || layers.is_empty());
42 XRRenderState {
43 reflector_: Reflector::new(),
44 depth_near: Cell::new(depth_near),
45 depth_far: Cell::new(depth_far),
46 inline_vertical_fov: Cell::new(inline_vertical_fov),
47 base_layer: MutNullableDom::new(layer),
48 layers: DomRefCell::new(layers.into_iter().map(Dom::from_ref).collect()),
49 }
50 }
51
52 pub(crate) fn new(
53 window: &Window,
54 depth_near: f64,
55 depth_far: f64,
56 inline_vertical_fov: Option<f64>,
57 layer: Option<&XRWebGLLayer>,
58 layers: Vec<&XRLayer>,
59 can_gc: CanGc,
60 ) -> DomRoot<XRRenderState> {
61 reflect_dom_object(
62 Box::new(XRRenderState::new_inherited(
63 depth_near,
64 depth_far,
65 inline_vertical_fov,
66 layer,
67 layers,
68 )),
69 window,
70 can_gc,
71 )
72 }
73
74 pub(crate) fn clone_object(&self) -> DomRoot<Self> {
75 XRRenderState::new(
76 self.global().as_window(),
77 self.depth_near.get(),
78 self.depth_far.get(),
79 self.inline_vertical_fov.get(),
80 self.base_layer.get().as_deref(),
81 self.layers.borrow().iter().map(|x| &**x).collect(),
82 CanGc::deprecated_note(),
83 )
84 }
85
86 pub(crate) fn set_depth_near(&self, depth: f64) {
87 self.depth_near.set(depth)
88 }
89 pub(crate) fn set_depth_far(&self, depth: f64) {
90 self.depth_far.set(depth)
91 }
92 pub(crate) fn set_inline_vertical_fov(&self, fov: f64) {
93 debug_assert!(self.inline_vertical_fov.get().is_some());
94 self.inline_vertical_fov.set(Some(fov))
95 }
96 pub(crate) fn set_base_layer(&self, layer: Option<&XRWebGLLayer>) {
97 self.base_layer.set(layer)
98 }
99 pub(crate) fn set_layers(&self, layers: Vec<&XRLayer>) {
100 *self.layers.borrow_mut() = layers.into_iter().map(Dom::from_ref).collect();
101 }
102 pub(crate) fn with_layers<F, R>(&self, f: F) -> R
103 where
104 F: FnOnce(&[Dom<XRLayer>]) -> R,
105 {
106 let layers = self.layers.borrow();
107 f(&layers)
108 }
109 pub(crate) fn has_sub_images(&self, sub_images: &[SubImages]) -> bool {
110 if let Some(base_layer) = self.base_layer.get() {
111 match sub_images.len() {
112 0 => base_layer.layer_id().is_none(),
114 1 => base_layer.layer_id() == Some(sub_images[0].layer_id),
117 _ => false,
118 }
119 } else {
120 let layers = self.layers.borrow();
122 sub_images.len() == layers.len() &&
123 sub_images
124 .iter()
125 .zip(layers.iter())
126 .all(|(sub_image, layer)| Some(sub_image.layer_id) == layer.layer_id())
127 }
128 }
129}
130
131impl XRRenderStateMethods<crate::DomTypeHolder> for XRRenderState {
132 fn DepthNear(&self) -> Finite<f64> {
134 Finite::wrap(self.depth_near.get())
135 }
136
137 fn DepthFar(&self) -> Finite<f64> {
139 Finite::wrap(self.depth_far.get())
140 }
141
142 fn GetInlineVerticalFieldOfView(&self) -> Option<Finite<f64>> {
144 self.inline_vertical_fov.get().map(Finite::wrap)
145 }
146
147 fn GetBaseLayer(&self) -> Option<DomRoot<XRWebGLLayer>> {
149 self.base_layer.get()
150 }
151
152 fn Layers(&self, cx: JSContext, can_gc: CanGc, retval: MutableHandleValue) {
154 let layers = self.layers.borrow();
156 let layers: Vec<&XRLayer> = layers.iter().map(|x| &**x).collect();
157 to_frozen_array(&layers[..], cx, retval, can_gc)
158 }
159}