Allow webvr thread consumers to request input data

This commit is contained in:
Manish Goregaokar 2019-04-23 10:16:56 -07:00
parent 623507187b
commit c1a8605c3d
4 changed files with 39 additions and 11 deletions

View file

@ -12,7 +12,7 @@ use std::fmt;
use std::num::NonZeroU32;
use std::ops::Deref;
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.
pub use crate::webgl_channel::webgl_channel;
@ -508,9 +508,13 @@ pub enum WebVRCommand {
/// Synchronize the pose information to be used in the frame.
SyncPoses(
WebVRDeviceId,
// near
f64,
// far
f64,
WebGLSender<Result<WebVRFutureFrameData, ()>>,
// sync gamepads too
bool,
WebGLSender<Result<WebVRPoseInformation, ()>>,
),
/// Submit the frame to a VR device using the specified texture coordinates.
SubmitFrame(WebVRDeviceId, [f32; 4], [f32; 4]),

View file

@ -51,7 +51,7 @@ use std::mem;
use std::ops::Deref;
use std::rc::Rc;
use std::thread;
use webvr_traits::{WebVRDisplayData, WebVRDisplayEvent, WebVRFrameData, WebVRFutureFrameData};
use webvr_traits::{WebVRDisplayData, WebVRDisplayEvent, WebVRFrameData, WebVRPoseInformation};
use webvr_traits::{WebVRLayer, WebVRMsg};
#[dom_struct]
@ -86,7 +86,7 @@ pub struct VRDisplay {
// Compositor VRFrameData synchonization
frame_data_status: Cell<VRFrameDataStatus>,
#[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>,
paused: Cell<bool>,
stopped_on_pause: Cell<bool>,
@ -726,8 +726,13 @@ impl VRDisplay {
.unwrap();
// Run Sync Poses in parallell on Render thread
let msg =
WebVRCommand::SyncPoses(display_id, near, far, sync_sender.clone());
let msg = WebVRCommand::SyncPoses(
display_id,
near,
far,
false,
sync_sender.clone(),
);
api_sender.send_vr(msg).unwrap();
} else {
let _ = wakeup_receiver.recv();
@ -808,8 +813,8 @@ impl VRDisplay {
fn sync_frame_data(&self) {
let status = if let Some(receiver) = self.frame_data_receiver.borrow().as_ref() {
match receiver.recv().unwrap() {
Ok(future_data) => {
*self.frame_data.borrow_mut() = future_data.block();
Ok(pose) => {
*self.frame_data.borrow_mut() = pose.frame.block();
VRFrameDataStatus::Synced
},
Err(()) => VRFrameDataStatus::Exit,

View file

@ -16,7 +16,7 @@ use std::collections::hash_map::Entry;
use std::collections::{HashMap, HashSet};
use std::{thread, time};
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
/// 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) };
}
},
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) {
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 {
let _ = sender.send(Err(()));
}

View file

@ -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::VRPose as WebVRPose;
pub use rust_webvr_api::VRStageParameters as WebVRStageParameters;
#[derive(Deserialize, Serialize)]
pub struct WebVRPoseInformation {
pub frame: WebVRFutureFrameData,
pub gamepads: Vec<(u32, WebVRGamepadState)>,
}