mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Auto merge of #22938 - asajeffrey:webvr-future-frame-data, r=paulrouget
Use webvr future_frame_data to avoid blocking the WebGL thread <!-- Please describe your changes on the following line: --> This PR fixes a potential deadlock caused by the WebGL thread being blocked on a VR device. Rather than blocking on the VR device, it forwards a future to the script thread, and then then script thread blocks. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes do not require tests because it's fixing a potential deadlock <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/22938) <!-- Reviewable:end -->
This commit is contained in:
commit
ec7a5f21c8
7 changed files with 23 additions and 17 deletions
|
@ -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"}
|
||||
|
|
|
@ -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;
|
||||
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
@ -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>,
|
||||
|
@ -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(future_data) => {
|
||||
*self.frame_data.borrow_mut() = future_data.block();
|
||||
VRFrameDataStatus::Synced
|
||||
},
|
||||
Err(()) => VRFrameDataStatus::Exit,
|
||||
|
|
|
@ -385,11 +385,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(()));
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue