mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Hook input code into new webxr crate
This commit is contained in:
parent
0d5d1a3dc4
commit
b654b6007a
5 changed files with 54 additions and 55 deletions
|
@ -486,7 +486,12 @@ unsafe_no_jsmanaged_fields!(WebGLVersion);
|
||||||
unsafe_no_jsmanaged_fields!(WebGLSLVersion);
|
unsafe_no_jsmanaged_fields!(WebGLSLVersion);
|
||||||
unsafe_no_jsmanaged_fields!(MediaList);
|
unsafe_no_jsmanaged_fields!(MediaList);
|
||||||
unsafe_no_jsmanaged_fields!(WebVRGamepadData, WebVRGamepadState, WebVRGamepadHand);
|
unsafe_no_jsmanaged_fields!(WebVRGamepadData, WebVRGamepadState, WebVRGamepadHand);
|
||||||
unsafe_no_jsmanaged_fields!(webxr_api::Registry, webxr_api::Session, webxr_api::Frame);
|
unsafe_no_jsmanaged_fields!(
|
||||||
|
webxr_api::Registry,
|
||||||
|
webxr_api::Session,
|
||||||
|
webxr_api::Frame,
|
||||||
|
webxr_api::InputSource
|
||||||
|
);
|
||||||
unsafe_no_jsmanaged_fields!(ScriptToConstellationChan);
|
unsafe_no_jsmanaged_fields!(ScriptToConstellationChan);
|
||||||
unsafe_no_jsmanaged_fields!(InteractiveMetrics);
|
unsafe_no_jsmanaged_fields!(InteractiveMetrics);
|
||||||
unsafe_no_jsmanaged_fields!(InteractiveWindow);
|
unsafe_no_jsmanaged_fields!(InteractiveWindow);
|
||||||
|
|
|
@ -20,7 +20,7 @@ use crate::dom::bindings::inheritance::Castable;
|
||||||
use crate::dom::bindings::num::Finite;
|
use crate::dom::bindings::num::Finite;
|
||||||
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
|
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
|
||||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
|
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
|
||||||
use crate::dom::bindings::root::{Dom, DomRoot, MutDom, MutNullableDom};
|
use crate::dom::bindings::root::{DomRoot, MutDom, MutNullableDom};
|
||||||
use crate::dom::bindings::str::DOMString;
|
use crate::dom::bindings::str::DOMString;
|
||||||
use crate::dom::event::Event;
|
use crate::dom::event::Event;
|
||||||
use crate::dom::eventtarget::EventTarget;
|
use crate::dom::eventtarget::EventTarget;
|
||||||
|
@ -33,7 +33,6 @@ use crate::dom::vrframedata::VRFrameData;
|
||||||
use crate::dom::vrpose::VRPose;
|
use crate::dom::vrpose::VRPose;
|
||||||
use crate::dom::vrstageparameters::VRStageParameters;
|
use crate::dom::vrstageparameters::VRStageParameters;
|
||||||
use crate::dom::webglrenderingcontext::WebGLRenderingContext;
|
use crate::dom::webglrenderingcontext::WebGLRenderingContext;
|
||||||
use crate::dom::xrinputsource::XRInputSource;
|
|
||||||
use crate::script_runtime::CommonScriptMsg;
|
use crate::script_runtime::CommonScriptMsg;
|
||||||
use crate::script_runtime::ScriptThreadEventCategory::WebVREvent;
|
use crate::script_runtime::ScriptThreadEventCategory::WebVREvent;
|
||||||
use crate::task_source::{TaskSource, TaskSourceName};
|
use crate::task_source::{TaskSource, TaskSourceName};
|
||||||
|
@ -43,7 +42,6 @@ use dom_struct::dom_struct;
|
||||||
use ipc_channel::ipc::IpcSender;
|
use ipc_channel::ipc::IpcSender;
|
||||||
use profile_traits::ipc;
|
use profile_traits::ipc;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
@ -85,10 +83,6 @@ pub struct VRDisplay {
|
||||||
running_display_raf: Cell<bool>,
|
running_display_raf: Cell<bool>,
|
||||||
paused: Cell<bool>,
|
paused: Cell<bool>,
|
||||||
stopped_on_pause: Cell<bool>,
|
stopped_on_pause: Cell<bool>,
|
||||||
/// Have inputs been initialized? (i.e, has getInputSources() been called?)
|
|
||||||
/// XR only
|
|
||||||
initialized_inputs: Cell<bool>,
|
|
||||||
input_sources: DomRefCell<HashMap<u32, Dom<XRInputSource>>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe_no_jsmanaged_fields!(WebVRDisplayData);
|
unsafe_no_jsmanaged_fields!(WebVRDisplayData);
|
||||||
|
@ -112,8 +106,6 @@ struct VRRAFUpdate {
|
||||||
/// Number uniquely identifying the WebGL context
|
/// Number uniquely identifying the WebGL context
|
||||||
/// so that we may setup/tear down VR compositors as things change
|
/// so that we may setup/tear down VR compositors as things change
|
||||||
context_id: usize,
|
context_id: usize,
|
||||||
/// Do we need input data?
|
|
||||||
needs_inputs: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type VRRAFUpdateSender = Sender<Result<VRRAFUpdate, ()>>;
|
type VRRAFUpdateSender = Sender<Result<VRRAFUpdate, ()>>;
|
||||||
|
@ -161,8 +153,6 @@ impl VRDisplay {
|
||||||
// This flag is set when the Display was presenting when it received a VR Pause event.
|
// This flag is set when the Display was presenting when it received a VR Pause event.
|
||||||
// When the VR Resume event is received and the flag is set, VR presentation automatically restarts.
|
// When the VR Resume event is received and the flag is set, VR presentation automatically restarts.
|
||||||
stopped_on_pause: Cell::new(false),
|
stopped_on_pause: Cell::new(false),
|
||||||
initialized_inputs: Cell::new(false),
|
|
||||||
input_sources: DomRefCell::new(HashMap::new()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -610,7 +600,6 @@ impl VRDisplay {
|
||||||
depth_far: self.depth_far.get(),
|
depth_far: self.depth_far.get(),
|
||||||
api_sender: self.api_sender(),
|
api_sender: self.api_sender(),
|
||||||
context_id: self.context_id(),
|
context_id: self.context_id(),
|
||||||
needs_inputs: self.initialized_inputs.get(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -635,7 +624,6 @@ impl VRDisplay {
|
||||||
let (raf_sender, raf_receiver) = unbounded();
|
let (raf_sender, raf_receiver) = unbounded();
|
||||||
let (wakeup_sender, wakeup_receiver) = unbounded();
|
let (wakeup_sender, wakeup_receiver) = unbounded();
|
||||||
*self.raf_wakeup_sender.borrow_mut() = Some(wakeup_sender);
|
*self.raf_wakeup_sender.borrow_mut() = Some(wakeup_sender);
|
||||||
let mut needs_inputs = false;
|
|
||||||
|
|
||||||
// The render loop at native headset frame rate is implemented using a dedicated thread.
|
// The render loop at native headset frame rate is implemented using a dedicated thread.
|
||||||
// Every loop iteration syncs pose data with the HMD, submits the pixels to the display and waits for Vsync.
|
// Every loop iteration syncs pose data with the HMD, submits the pixels to the display and waits for Vsync.
|
||||||
|
@ -676,7 +664,7 @@ impl VRDisplay {
|
||||||
display_id,
|
display_id,
|
||||||
near,
|
near,
|
||||||
far,
|
far,
|
||||||
needs_inputs,
|
false,
|
||||||
sync_sender.clone(),
|
sync_sender.clone(),
|
||||||
);
|
);
|
||||||
api_sender.send_vr(msg).unwrap();
|
api_sender.send_vr(msg).unwrap();
|
||||||
|
@ -702,7 +690,6 @@ impl VRDisplay {
|
||||||
if let Ok(update) = raf_receiver.recv().unwrap() {
|
if let Ok(update) = raf_receiver.recv().unwrap() {
|
||||||
near = update.depth_near;
|
near = update.depth_near;
|
||||||
far = update.depth_far;
|
far = update.depth_far;
|
||||||
needs_inputs = update.needs_inputs;
|
|
||||||
if update.context_id != context_id {
|
if update.context_id != context_id {
|
||||||
if let Some(ref api_sender) = update.api_sender {
|
if let Some(ref api_sender) = update.api_sender {
|
||||||
api_sender
|
api_sender
|
||||||
|
@ -759,14 +746,6 @@ impl VRDisplay {
|
||||||
match receiver.recv().unwrap() {
|
match receiver.recv().unwrap() {
|
||||||
Ok(pose) => {
|
Ok(pose) => {
|
||||||
*self.frame_data.borrow_mut() = pose.frame.block();
|
*self.frame_data.borrow_mut() = pose.frame.block();
|
||||||
if self.initialized_inputs.get() {
|
|
||||||
let inputs = self.input_sources.borrow();
|
|
||||||
for (id, state) in pose.gamepads {
|
|
||||||
if let Some(input) = inputs.get(&id) {
|
|
||||||
input.update_state(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
VRFrameDataStatus::Synced
|
VRFrameDataStatus::Synced
|
||||||
},
|
},
|
||||||
Err(()) => VRFrameDataStatus::Exit,
|
Err(()) => VRFrameDataStatus::Exit,
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
|
||||||
use crate::dom::bindings::codegen::Bindings::XRInputSourceBinding;
|
use crate::dom::bindings::codegen::Bindings::XRInputSourceBinding;
|
||||||
use crate::dom::bindings::codegen::Bindings::XRInputSourceBinding::{
|
use crate::dom::bindings::codegen::Bindings::XRInputSourceBinding::{
|
||||||
XRHandedness, XRInputSourceMethods,
|
XRHandedness, XRInputSourceMethods,
|
||||||
|
@ -10,33 +9,27 @@ use crate::dom::bindings::codegen::Bindings::XRInputSourceBinding::{
|
||||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
||||||
use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
|
use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::xrsession::{ApiPose, XRSession};
|
use crate::dom::xrsession::XRSession;
|
||||||
use crate::dom::xrspace::XRSpace;
|
use crate::dom::xrspace::XRSpace;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use webvr_traits::{WebVRGamepadData, WebVRGamepadHand, WebVRGamepadState};
|
use webxr_api::{Handedness, InputId, InputSource};
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct XRInputSource {
|
pub struct XRInputSource {
|
||||||
reflector: Reflector,
|
reflector: Reflector,
|
||||||
session: Dom<XRSession>,
|
session: Dom<XRSession>,
|
||||||
#[ignore_malloc_size_of = "Defined in rust-webvr"]
|
#[ignore_malloc_size_of = "Defined in rust-webvr"]
|
||||||
data: WebVRGamepadData,
|
info: InputSource,
|
||||||
#[ignore_malloc_size_of = "Defined in rust-webvr"]
|
#[ignore_malloc_size_of = "Defined in rust-webvr"]
|
||||||
state: DomRefCell<WebVRGamepadState>,
|
|
||||||
target_ray_space: MutNullableDom<XRSpace>,
|
target_ray_space: MutNullableDom<XRSpace>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XRInputSource {
|
impl XRInputSource {
|
||||||
pub fn new_inherited(
|
pub fn new_inherited(session: &XRSession, info: InputSource) -> XRInputSource {
|
||||||
session: &XRSession,
|
|
||||||
data: WebVRGamepadData,
|
|
||||||
state: WebVRGamepadState,
|
|
||||||
) -> XRInputSource {
|
|
||||||
XRInputSource {
|
XRInputSource {
|
||||||
reflector: Reflector::new(),
|
reflector: Reflector::new(),
|
||||||
session: Dom::from_ref(session),
|
session: Dom::from_ref(session),
|
||||||
data,
|
info,
|
||||||
state: DomRefCell::new(state),
|
|
||||||
target_ray_space: Default::default(),
|
target_ray_space: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,32 +37,27 @@ impl XRInputSource {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
global: &GlobalScope,
|
global: &GlobalScope,
|
||||||
session: &XRSession,
|
session: &XRSession,
|
||||||
data: WebVRGamepadData,
|
info: InputSource,
|
||||||
state: WebVRGamepadState,
|
|
||||||
) -> DomRoot<XRInputSource> {
|
) -> DomRoot<XRInputSource> {
|
||||||
reflect_dom_object(
|
reflect_dom_object(
|
||||||
Box::new(XRInputSource::new_inherited(session, data, state)),
|
Box::new(XRInputSource::new_inherited(session, info)),
|
||||||
global,
|
global,
|
||||||
XRInputSourceBinding::Wrap,
|
XRInputSourceBinding::Wrap,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_state(&self, state: WebVRGamepadState) {
|
pub fn id(&self) -> InputId {
|
||||||
*self.state.borrow_mut() = state;
|
self.info.id
|
||||||
}
|
|
||||||
|
|
||||||
pub fn pose(&self) -> ApiPose {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XRInputSourceMethods for XRInputSource {
|
impl XRInputSourceMethods for XRInputSource {
|
||||||
/// https://immersive-web.github.io/webxr/#dom-xrinputsource-handedness
|
/// https://immersive-web.github.io/webxr/#dom-xrinputsource-handedness
|
||||||
fn Handedness(&self) -> XRHandedness {
|
fn Handedness(&self) -> XRHandedness {
|
||||||
match self.data.hand {
|
match self.info.handedness {
|
||||||
WebVRGamepadHand::Unknown => XRHandedness::None,
|
Handedness::None => XRHandedness::None,
|
||||||
WebVRGamepadHand::Left => XRHandedness::Left,
|
Handedness::Left => XRHandedness::Left,
|
||||||
WebVRGamepadHand::Right => XRHandedness::Right,
|
Handedness::Right => XRHandedness::Right,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ use crate::dom::bindings::inheritance::Castable;
|
||||||
use crate::dom::bindings::num::Finite;
|
use crate::dom::bindings::num::Finite;
|
||||||
use crate::dom::bindings::refcounted::Trusted;
|
use crate::dom::bindings::refcounted::Trusted;
|
||||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
|
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
|
||||||
use crate::dom::bindings::root::{DomRoot, MutDom, MutNullableDom};
|
use crate::dom::bindings::root::{Dom, DomRoot, MutDom, MutNullableDom};
|
||||||
use crate::dom::eventtarget::EventTarget;
|
use crate::dom::eventtarget::EventTarget;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::promise::Promise;
|
use crate::dom::promise::Promise;
|
||||||
|
@ -58,6 +58,7 @@ pub struct XRSession {
|
||||||
raf_callback_list: DomRefCell<Vec<(i32, Option<Rc<XRFrameRequestCallback>>)>>,
|
raf_callback_list: DomRefCell<Vec<(i32, Option<Rc<XRFrameRequestCallback>>)>>,
|
||||||
#[ignore_malloc_size_of = "defined in ipc-channel"]
|
#[ignore_malloc_size_of = "defined in ipc-channel"]
|
||||||
raf_sender: DomRefCell<Option<IpcSender<(f64, Frame)>>>,
|
raf_sender: DomRefCell<Option<IpcSender<(f64, Frame)>>>,
|
||||||
|
input_sources: DomRefCell<Vec<Dom<XRInputSource>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XRSession {
|
impl XRSession {
|
||||||
|
@ -76,16 +77,27 @@ impl XRSession {
|
||||||
next_raf_id: Cell::new(0),
|
next_raf_id: Cell::new(0),
|
||||||
raf_callback_list: DomRefCell::new(vec![]),
|
raf_callback_list: DomRefCell::new(vec![]),
|
||||||
raf_sender: DomRefCell::new(None),
|
raf_sender: DomRefCell::new(None),
|
||||||
|
input_sources: DomRefCell::new(vec![]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(global: &GlobalScope, session: Session) -> DomRoot<XRSession> {
|
pub fn new(global: &GlobalScope, session: Session) -> DomRoot<XRSession> {
|
||||||
let render_state = XRRenderState::new(global, 0.1, 1000.0, None);
|
let render_state = XRRenderState::new(global, 0.1, 1000.0, None);
|
||||||
reflect_dom_object(
|
let ret = reflect_dom_object(
|
||||||
Box::new(XRSession::new_inherited(session, &render_state)),
|
Box::new(XRSession::new_inherited(session, &render_state)),
|
||||||
global,
|
global,
|
||||||
XRSessionBinding::Wrap,
|
XRSessionBinding::Wrap,
|
||||||
)
|
);
|
||||||
|
{
|
||||||
|
let mut input_sources = ret.input_sources.borrow_mut();
|
||||||
|
for info in ret.session.borrow().initial_inputs() {
|
||||||
|
// XXXManishearth we should be able to listen for updates
|
||||||
|
// to the input sources
|
||||||
|
let input = XRInputSource::new(global, &ret, *info);
|
||||||
|
input_sources.push(Dom::from_ref(&input));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_session<F: FnOnce(&Session)>(&self, with: F) {
|
pub fn with_session<F: FnOnce(&Session)>(&self, with: F) {
|
||||||
|
@ -268,7 +280,11 @@ impl XRSessionMethods for XRSession {
|
||||||
|
|
||||||
/// https://immersive-web.github.io/webxr/#dom-xrsession-getinputsources
|
/// https://immersive-web.github.io/webxr/#dom-xrsession-getinputsources
|
||||||
fn GetInputSources(&self) -> Vec<DomRoot<XRInputSource>> {
|
fn GetInputSources(&self) -> Vec<DomRoot<XRInputSource>> {
|
||||||
unimplemented!()
|
self.input_sources
|
||||||
|
.borrow()
|
||||||
|
.iter()
|
||||||
|
.map(|x| DomRoot::from_ref(&**x))
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ use crate::dom::eventtarget::EventTarget;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::xrinputsource::XRInputSource;
|
use crate::dom::xrinputsource::XRInputSource;
|
||||||
use crate::dom::xrreferencespace::XRReferenceSpace;
|
use crate::dom::xrreferencespace::XRReferenceSpace;
|
||||||
use crate::dom::xrsession::{ApiPose, XRSession};
|
use crate::dom::xrsession::{cast_transform, ApiPose, XRSession};
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use webxr_api::Frame;
|
use webxr_api::Frame;
|
||||||
|
|
||||||
|
@ -61,7 +61,18 @@ impl XRSpace {
|
||||||
if let Some(reference) = self.downcast::<XRReferenceSpace>() {
|
if let Some(reference) = self.downcast::<XRReferenceSpace>() {
|
||||||
reference.get_pose(base_pose)
|
reference.get_pose(base_pose)
|
||||||
} else if let Some(source) = self.input_source.get() {
|
} else if let Some(source) = self.input_source.get() {
|
||||||
source.pose()
|
// XXXManishearth we should be able to request frame information
|
||||||
|
// for inputs when necessary instead of always loading it
|
||||||
|
//
|
||||||
|
// Also, the below code is quadratic, so this API may need an overhaul anyway
|
||||||
|
let id = source.id();
|
||||||
|
// XXXManishearth once we have dynamic inputs we'll need to handle this better
|
||||||
|
let frame = base_pose
|
||||||
|
.inputs
|
||||||
|
.iter()
|
||||||
|
.find(|i| i.id == id)
|
||||||
|
.expect("no input found");
|
||||||
|
cast_transform(frame.target_ray_origin)
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue