Skip to content

Commit

Permalink
Use webvr future_frame_data to avoid blocking the WebGL thread
Browse files Browse the repository at this point in the history
  • Loading branch information
Alan Jeffrey committed Feb 25, 2019
1 parent a28e15e commit a4b0e97
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 21 deletions.
18 changes: 10 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Expand Up @@ -15,6 +15,9 @@ opt-level = 3
# lto = false

[patch.crates-io]
rust-webvr-api = { git = "https://github.com/asajeffrey/rust-webvr.git", branch = "future-frame-data" }
rust-webvr = { git = "https://github.com/asajeffrey/rust-webvr.git", branch = "future-frame-data" }

# If you need to temporarily test Servo with a local fork of some upstream
# crate, add that here. Use the form:
#
Expand Down
1 change: 1 addition & 0 deletions components/canvas_traits/Cargo.toml
Expand Up @@ -27,3 +27,4 @@ serde = "1.0"
serde_bytes = "0.10"
servo_config = {path = "../config"}
webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}
webvr_traits = {path = "../webvr_traits"}
9 changes: 7 additions & 2 deletions components/canvas_traits/webgl.rs
Expand Up @@ -7,12 +7,12 @@ use gleam::gl;
use ipc_channel::ipc::{IpcBytesReceiver, IpcBytesSender, IpcSharedMemory};
use offscreen_gl_context::{GLContextAttributes, GLLimits};
use pixels::PixelFormat;
use serde_bytes::ByteBuf;
use std::borrow::Cow;
use std::fmt;
use std::num::NonZeroU32;
use std::ops::Deref;
use webrender_api::{DocumentId, ImageKey, PipelineId};
use webvr_traits::WebVRFutureFrameData;

/// Helper function that creates a WebGL channel (WebGLSender, WebGLReceiver) to be used in WebGLCommands.
pub use crate::webgl_channel::webgl_channel;
Expand Down Expand Up @@ -506,7 +506,12 @@ pub enum WebVRCommand {
/// Start presenting to a VR device.
Create(WebVRDeviceId),
/// Synchronize the pose information to be used in the frame.
SyncPoses(WebVRDeviceId, f64, f64, WebGLSender<Result<ByteBuf, ()>>),
SyncPoses(
WebVRDeviceId,
f64,
f64,
WebGLSender<Result<WebVRFutureFrameData, ()>>,
),
/// Submit the frame to a VR device using the specified texture coordinates.
SubmitFrame(WebVRDeviceId, [f32; 4], [f32; 4]),
/// Stop presenting to a VR device
Expand Down
10 changes: 5 additions & 5 deletions components/script/dom/vrdisplay.rs
Expand Up @@ -42,13 +42,13 @@ use crossbeam_channel::{unbounded, Sender};
use dom_struct::dom_struct;
use ipc_channel::ipc::IpcSender;
use profile_traits::ipc;
use serde_bytes::ByteBuf;
use std::cell::Cell;
use std::mem;
use std::ops::Deref;
use std::rc::Rc;
use std::thread;
use webvr_traits::{WebVRDisplayData, WebVRDisplayEvent, WebVRFrameData, WebVRLayer, WebVRMsg};
use webvr_traits::{WebVRDisplayData, WebVRDisplayEvent, WebVRFrameData, WebVRFutureFrameData};
use webvr_traits::{WebVRLayer, WebVRMsg};

#[dom_struct]
pub struct VRDisplay {
Expand Down Expand Up @@ -77,7 +77,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<ByteBuf, ()>>>>,
frame_data_receiver: DomRefCell<Option<WebGLReceiver<Result<WebVRFutureFrameData, ()>>>>,
running_display_raf: Cell<bool>,
paused: Cell<bool>,
stopped_on_pause: Cell<bool>,
Expand Down Expand Up @@ -664,8 +664,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(bytes) => {
*self.frame_data.borrow_mut() = WebVRFrameData::from_bytes(&bytes[..]);
Ok(mut future_data) => {
*self.frame_data.borrow_mut() = future_data.block();
VRFrameDataStatus::Synced
},
Err(()) => VRFrameDataStatus::Exit,
Expand Down
7 changes: 2 additions & 5 deletions components/webvr/webvr_thread.rs
Expand Up @@ -382,11 +382,8 @@ impl webgl::WebVRRenderHandler for WebVRCompositorHandler {
},
webgl::WebVRCommand::SyncPoses(compositor_id, near, far, sender) => {
if let Some(compositor) = self.compositors.get(&compositor_id) {
let pose = unsafe {
(*compositor.0).sync_poses();
(*compositor.0).synced_frame_data(near, far).to_bytes()
};
let _ = sender.send(Ok(pose.into()));
let pose = unsafe { (*compositor.0).future_frame_data(near, far) };
let _ = sender.send(Ok(pose));
} else {
let _ = sender.send(Err(()));
}
Expand Down
2 changes: 1 addition & 1 deletion components/webvr_traits/Cargo.toml
Expand Up @@ -13,5 +13,5 @@ path = "lib.rs"
[dependencies]
ipc-channel = "0.11"
msg = {path = "../msg"}
rust-webvr-api = {version = "0.10", features = ["serde-serialization"]}
rust-webvr-api = {version = "0.10.2", features = ["ipc"]}
serde = "1.0"
1 change: 1 addition & 0 deletions components/webvr_traits/lib.rs
Expand Up @@ -20,6 +20,7 @@ pub use rust_webvr_api::VREye as WebVREye;
pub use rust_webvr_api::VREyeParameters as WebVREyeParameters;
pub use rust_webvr_api::VRFieldOfView as WebVRFieldOfView;
pub use rust_webvr_api::VRFrameData as WebVRFrameData;
pub use rust_webvr_api::VRFutureFrameData as WebVRFutureFrameData;
pub use rust_webvr_api::VRGamepadButton as WebVRGamepadButton;
pub use rust_webvr_api::VRGamepadData as WebVRGamepadData;
pub use rust_webvr_api::VRGamepadEvent as WebVRGamepadEvent;
Expand Down

0 comments on commit a4b0e97

Please sign in to comment.