mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Allow webvr thread consumers to request input data
This commit is contained in:
parent
623507187b
commit
c1a8605c3d
4 changed files with 39 additions and 11 deletions
|
@ -12,7 +12,7 @@ use std::fmt;
|
||||||
use std::num::NonZeroU32;
|
use std::num::NonZeroU32;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use webrender_api::{DocumentId, ImageKey, PipelineId};
|
use webrender_api::{DocumentId, ImageKey, PipelineId};
|
||||||
use webvr_traits::WebVRFutureFrameData;
|
use webvr_traits::WebVRPoseInformation;
|
||||||
|
|
||||||
/// Helper function that creates a WebGL channel (WebGLSender, WebGLReceiver) to be used in WebGLCommands.
|
/// Helper function that creates a WebGL channel (WebGLSender, WebGLReceiver) to be used in WebGLCommands.
|
||||||
pub use crate::webgl_channel::webgl_channel;
|
pub use crate::webgl_channel::webgl_channel;
|
||||||
|
@ -508,9 +508,13 @@ pub enum WebVRCommand {
|
||||||
/// Synchronize the pose information to be used in the frame.
|
/// Synchronize the pose information to be used in the frame.
|
||||||
SyncPoses(
|
SyncPoses(
|
||||||
WebVRDeviceId,
|
WebVRDeviceId,
|
||||||
|
// near
|
||||||
f64,
|
f64,
|
||||||
|
// far
|
||||||
f64,
|
f64,
|
||||||
WebGLSender<Result<WebVRFutureFrameData, ()>>,
|
// sync gamepads too
|
||||||
|
bool,
|
||||||
|
WebGLSender<Result<WebVRPoseInformation, ()>>,
|
||||||
),
|
),
|
||||||
/// Submit the frame to a VR device using the specified texture coordinates.
|
/// Submit the frame to a VR device using the specified texture coordinates.
|
||||||
SubmitFrame(WebVRDeviceId, [f32; 4], [f32; 4]),
|
SubmitFrame(WebVRDeviceId, [f32; 4], [f32; 4]),
|
||||||
|
|
|
@ -51,7 +51,7 @@ use std::mem;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use webvr_traits::{WebVRDisplayData, WebVRDisplayEvent, WebVRFrameData, WebVRFutureFrameData};
|
use webvr_traits::{WebVRDisplayData, WebVRDisplayEvent, WebVRFrameData, WebVRPoseInformation};
|
||||||
use webvr_traits::{WebVRLayer, WebVRMsg};
|
use webvr_traits::{WebVRLayer, WebVRMsg};
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
@ -86,7 +86,7 @@ pub struct VRDisplay {
|
||||||
// Compositor VRFrameData synchonization
|
// Compositor VRFrameData synchonization
|
||||||
frame_data_status: Cell<VRFrameDataStatus>,
|
frame_data_status: Cell<VRFrameDataStatus>,
|
||||||
#[ignore_malloc_size_of = "closures are hard"]
|
#[ignore_malloc_size_of = "closures are hard"]
|
||||||
frame_data_receiver: DomRefCell<Option<WebGLReceiver<Result<WebVRFutureFrameData, ()>>>>,
|
frame_data_receiver: DomRefCell<Option<WebGLReceiver<Result<WebVRPoseInformation, ()>>>>,
|
||||||
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>,
|
||||||
|
@ -726,8 +726,13 @@ impl VRDisplay {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Run Sync Poses in parallell on Render thread
|
// Run Sync Poses in parallell on Render thread
|
||||||
let msg =
|
let msg = WebVRCommand::SyncPoses(
|
||||||
WebVRCommand::SyncPoses(display_id, near, far, sync_sender.clone());
|
display_id,
|
||||||
|
near,
|
||||||
|
far,
|
||||||
|
false,
|
||||||
|
sync_sender.clone(),
|
||||||
|
);
|
||||||
api_sender.send_vr(msg).unwrap();
|
api_sender.send_vr(msg).unwrap();
|
||||||
} else {
|
} else {
|
||||||
let _ = wakeup_receiver.recv();
|
let _ = wakeup_receiver.recv();
|
||||||
|
@ -808,8 +813,8 @@ impl VRDisplay {
|
||||||
fn sync_frame_data(&self) {
|
fn sync_frame_data(&self) {
|
||||||
let status = if let Some(receiver) = self.frame_data_receiver.borrow().as_ref() {
|
let status = if let Some(receiver) = self.frame_data_receiver.borrow().as_ref() {
|
||||||
match receiver.recv().unwrap() {
|
match receiver.recv().unwrap() {
|
||||||
Ok(future_data) => {
|
Ok(pose) => {
|
||||||
*self.frame_data.borrow_mut() = future_data.block();
|
*self.frame_data.borrow_mut() = pose.frame.block();
|
||||||
VRFrameDataStatus::Synced
|
VRFrameDataStatus::Synced
|
||||||
},
|
},
|
||||||
Err(()) => VRFrameDataStatus::Exit,
|
Err(()) => VRFrameDataStatus::Exit,
|
||||||
|
|
|
@ -16,7 +16,7 @@ use std::collections::hash_map::Entry;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::{thread, time};
|
use std::{thread, time};
|
||||||
use webvr_traits::webvr::*;
|
use webvr_traits::webvr::*;
|
||||||
use webvr_traits::{WebVRMsg, WebVRResult};
|
use webvr_traits::{WebVRMsg, WebVRPoseInformation, WebVRResult};
|
||||||
|
|
||||||
/// WebVRThread owns native VRDisplays, handles their life cycle inside Servo and
|
/// WebVRThread owns native VRDisplays, handles their life cycle inside Servo and
|
||||||
/// acts a doorman for untrusted VR requests from DOM Objects. These are the key components
|
/// acts a doorman for untrusted VR requests from DOM Objects. These are the key components
|
||||||
|
@ -386,10 +386,23 @@ impl webgl::WebVRRenderHandler for WebVRCompositorHandler {
|
||||||
unsafe { (*compositor.0).start_present(None) };
|
unsafe { (*compositor.0).start_present(None) };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
webgl::WebVRCommand::SyncPoses(compositor_id, near, far, sender) => {
|
webgl::WebVRCommand::SyncPoses(compositor_id, near, far, get_gamepads, sender) => {
|
||||||
if let Some(compositor) = self.compositors.get(&compositor_id) {
|
if let Some(compositor) = self.compositors.get(&compositor_id) {
|
||||||
let pose = unsafe { (*compositor.0).future_frame_data(near, far) };
|
let pose = unsafe { (*compositor.0).future_frame_data(near, far) };
|
||||||
let _ = sender.send(Ok(pose));
|
let mut pose_information = WebVRPoseInformation {
|
||||||
|
frame: pose,
|
||||||
|
gamepads: vec![],
|
||||||
|
};
|
||||||
|
if get_gamepads {
|
||||||
|
let gamepads = unsafe { (*compositor.0).fetch_gamepads() };
|
||||||
|
if let Ok(gamepads) = gamepads {
|
||||||
|
for gamepad in gamepads {
|
||||||
|
let g = gamepad.borrow();
|
||||||
|
pose_information.gamepads.push((g.id(), g.state()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let _ = sender.send(Ok(pose_information));
|
||||||
} else {
|
} else {
|
||||||
let _ = sender.send(Err(()));
|
let _ = sender.send(Err(()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,3 +30,9 @@ pub use rust_webvr_api::VRLayer as WebVRLayer;
|
||||||
pub use rust_webvr_api::VRMainThreadHeartbeat as WebVRMainThreadHeartbeat;
|
pub use rust_webvr_api::VRMainThreadHeartbeat as WebVRMainThreadHeartbeat;
|
||||||
pub use rust_webvr_api::VRPose as WebVRPose;
|
pub use rust_webvr_api::VRPose as WebVRPose;
|
||||||
pub use rust_webvr_api::VRStageParameters as WebVRStageParameters;
|
pub use rust_webvr_api::VRStageParameters as WebVRStageParameters;
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct WebVRPoseInformation {
|
||||||
|
pub frame: WebVRFutureFrameData,
|
||||||
|
pub gamepads: Vec<(u32, WebVRGamepadState)>,
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue