aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/xrrenderstate.rs
diff options
context:
space:
mode:
authoryvt <i@yvt.jp>2021-07-10 17:24:27 +0900
committeryvt <i@yvt.jp>2021-07-10 17:55:42 +0900
commit01a7de50ab1843d85295f9dccad7f4c099e7208c (patch)
treeee53fb6e8889deb7b880ee969e6c662e6128d210 /components/script/dom/xrrenderstate.rs
parentff8d2cdbbfc7a9dc7f38b7dd47cb350fde39388f (diff)
parent94b613fbdaa2b98f2179fc0bbda13c64e6fa0d38 (diff)
downloadservo-01a7de50ab1843d85295f9dccad7f4c099e7208c.tar.gz
servo-01a7de50ab1843d85295f9dccad7f4c099e7208c.zip
Merge remote-tracking branch 'upstream/master' into feat-cow-infra
`tests/wpt/web-platform-tests/html/browsers/origin/cross-origin-objects/cross-origin-objects.html` was reverted to the upstream version.
Diffstat (limited to 'components/script/dom/xrrenderstate.rs')
-rw-r--r--components/script/dom/xrrenderstate.rs162
1 files changed, 162 insertions, 0 deletions
diff --git a/components/script/dom/xrrenderstate.rs b/components/script/dom/xrrenderstate.rs
new file mode 100644
index 00000000000..71e6d873814
--- /dev/null
+++ b/components/script/dom/xrrenderstate.rs
@@ -0,0 +1,162 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+use crate::dom::bindings::cell::DomRefCell;
+use crate::dom::bindings::codegen::Bindings::XRRenderStateBinding::XRRenderStateMethods;
+use crate::dom::bindings::num::Finite;
+use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
+use crate::dom::bindings::root::Dom;
+use crate::dom::bindings::root::{DomRoot, MutNullableDom};
+use crate::dom::bindings::utils::to_frozen_array;
+use crate::dom::globalscope::GlobalScope;
+use crate::dom::xrlayer::XRLayer;
+use crate::dom::xrwebgllayer::XRWebGLLayer;
+use crate::script_runtime::JSContext;
+use dom_struct::dom_struct;
+use js::jsval::JSVal;
+use std::cell::Cell;
+use webxr_api::SubImages;
+
+#[dom_struct]
+pub struct XRRenderState {
+ reflector_: Reflector,
+ depth_near: Cell<f64>,
+ depth_far: Cell<f64>,
+ inline_vertical_fov: Cell<Option<f64>>,
+ base_layer: MutNullableDom<XRWebGLLayer>,
+ layers: DomRefCell<Vec<Dom<XRLayer>>>,
+}
+
+impl XRRenderState {
+ pub fn new_inherited(
+ depth_near: f64,
+ depth_far: f64,
+ inline_vertical_fov: Option<f64>,
+ layer: Option<&XRWebGLLayer>,
+ layers: Vec<&XRLayer>,
+ ) -> XRRenderState {
+ debug_assert!(layer.is_none() || layers.is_empty());
+ XRRenderState {
+ reflector_: Reflector::new(),
+ depth_near: Cell::new(depth_near),
+ depth_far: Cell::new(depth_far),
+ inline_vertical_fov: Cell::new(inline_vertical_fov),
+ base_layer: MutNullableDom::new(layer),
+ layers: DomRefCell::new(
+ layers
+ .into_iter()
+ .map(|layer| Dom::from_ref(layer))
+ .collect(),
+ ),
+ }
+ }
+
+ pub fn new(
+ global: &GlobalScope,
+ depth_near: f64,
+ depth_far: f64,
+ inline_vertical_fov: Option<f64>,
+ layer: Option<&XRWebGLLayer>,
+ layers: Vec<&XRLayer>,
+ ) -> DomRoot<XRRenderState> {
+ reflect_dom_object(
+ Box::new(XRRenderState::new_inherited(
+ depth_near,
+ depth_far,
+ inline_vertical_fov,
+ layer,
+ layers,
+ )),
+ global,
+ )
+ }
+
+ pub fn clone_object(&self) -> DomRoot<Self> {
+ XRRenderState::new(
+ &self.global(),
+ self.depth_near.get(),
+ self.depth_far.get(),
+ self.inline_vertical_fov.get(),
+ self.base_layer.get().as_ref().map(|x| &**x),
+ self.layers.borrow().iter().map(|x| &**x).collect(),
+ )
+ }
+
+ pub fn set_depth_near(&self, depth: f64) {
+ self.depth_near.set(depth)
+ }
+ pub fn set_depth_far(&self, depth: f64) {
+ self.depth_far.set(depth)
+ }
+ pub fn set_inline_vertical_fov(&self, fov: f64) {
+ debug_assert!(self.inline_vertical_fov.get().is_some());
+ self.inline_vertical_fov.set(Some(fov))
+ }
+ pub fn set_base_layer(&self, layer: Option<&XRWebGLLayer>) {
+ self.base_layer.set(layer)
+ }
+ pub fn set_layers(&self, layers: Vec<&XRLayer>) {
+ *self.layers.borrow_mut() = layers
+ .into_iter()
+ .map(|layer| Dom::from_ref(layer))
+ .collect();
+ }
+ pub fn with_layers<F, R>(&self, f: F) -> R
+ where
+ F: FnOnce(&[Dom<XRLayer>]) -> R,
+ {
+ let layers = self.layers.borrow();
+ f(&*layers)
+ }
+ pub fn has_sub_images(&self, sub_images: &[SubImages]) -> bool {
+ if let Some(base_layer) = self.base_layer.get() {
+ match sub_images.len() {
+ // For inline sessions, there may be a base layer, but it won't have a framebuffer
+ 0 => base_layer.layer_id() == None,
+ // For immersive sessions, the base layer will have a framebuffer,
+ // so we make sure the layer id's match up
+ 1 => base_layer.layer_id() == Some(sub_images[0].layer_id),
+ _ => false,
+ }
+ } else {
+ // The layers API is only for immersive sessions
+ let layers = self.layers.borrow();
+ sub_images.len() == layers.len() &&
+ sub_images
+ .iter()
+ .zip(layers.iter())
+ .all(|(sub_image, layer)| Some(sub_image.layer_id) == layer.layer_id())
+ }
+ }
+}
+
+impl XRRenderStateMethods for XRRenderState {
+ /// https://immersive-web.github.io/webxr/#dom-xrrenderstate-depthnear
+ fn DepthNear(&self) -> Finite<f64> {
+ Finite::wrap(self.depth_near.get())
+ }
+
+ /// https://immersive-web.github.io/webxr/#dom-xrrenderstate-depthfar
+ fn DepthFar(&self) -> Finite<f64> {
+ Finite::wrap(self.depth_far.get())
+ }
+
+ /// https://immersive-web.github.io/webxr/#dom-xrrenderstate-inlineverticalfieldofview
+ fn GetInlineVerticalFieldOfView(&self) -> Option<Finite<f64>> {
+ self.inline_vertical_fov.get().map(Finite::wrap)
+ }
+
+ /// https://immersive-web.github.io/webxr/#dom-xrrenderstate-baselayer
+ fn GetBaseLayer(&self) -> Option<DomRoot<XRWebGLLayer>> {
+ self.base_layer.get()
+ }
+
+ /// https://immersive-web.github.io/layers/#dom-xrrenderstate-layers
+ fn Layers(&self, cx: JSContext) -> JSVal {
+ // TODO: cache this array?
+ let layers = self.layers.borrow();
+ let layers: Vec<&XRLayer> = layers.iter().map(|x| &**x).collect();
+ to_frozen_array(&layers[..], cx)
+ }
+}