diff options
-rw-r--r-- | Cargo.lock | 20 | ||||
-rw-r--r-- | components/compositing/Cargo.toml | 1 | ||||
-rw-r--r-- | components/compositing/compositor.rs | 16 | ||||
-rw-r--r-- | components/compositing/compositor_thread.rs | 2 | ||||
-rw-r--r-- | components/compositing/windowing.rs | 8 | ||||
-rw-r--r-- | components/servo/lib.rs | 4 | ||||
-rw-r--r-- | components/webvr/Cargo.toml | 2 | ||||
-rw-r--r-- | components/webvr/lib.rs | 1 | ||||
-rw-r--r-- | components/webvr_traits/lib.rs | 1 | ||||
-rw-r--r-- | ports/libsimpleservo/api/src/lib.rs | 8 | ||||
-rw-r--r-- | ports/servo/Cargo.toml | 1 | ||||
-rw-r--r-- | ports/servo/glutin_app/window.rs | 44 |
12 files changed, 95 insertions, 13 deletions
diff --git a/Cargo.lock b/Cargo.lock index bd65dc2099b..d0fca140e73 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -633,6 +633,7 @@ dependencies = [ "webrender 0.58.0 (git+https://github.com/servo/webrender)", "webrender_api 0.58.0 (git+https://github.com/servo/webrender)", "webvr 0.0.1", + "webvr_traits 0.0.1", ] [[package]] @@ -3328,22 +3329,26 @@ dependencies = [ [[package]] name = "rust-webvr" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bindgen 0.46.0 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.19.4 (registry+https://github.com/rust-lang/crates.io-index)", "gl_generator 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "glutin 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", "gvr-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", "libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "ovr-mobile-sys 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rust-webvr-api 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rust-webvr-api 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winit 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rust-webvr-api" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "android_injected_glue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3667,6 +3672,7 @@ dependencies = [ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "osmesa-src 0.1.0 (git+https://github.com/servo/osmesa-src)", "osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rust-webvr 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "sig 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "tinyfiledialogs 3.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4868,7 +4874,7 @@ dependencies = [ "ipc-channel 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", - "rust-webvr 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rust-webvr 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "script_traits 0.0.1", "servo_config 0.0.1", "webvr_traits 0.0.1", @@ -4880,7 +4886,7 @@ version = "0.0.1" dependencies = [ "ipc-channel 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", - "rust-webvr-api 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rust-webvr-api 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5359,8 +5365,8 @@ dependencies = [ "checksum regex-syntax 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fbc557aac2b708fe84121caf261346cc2eed71978024337e42eb46b8a252ac6e" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum ron 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "da06feaa07f69125ab9ddc769b11de29090122170b402547f64b86fe16ebc399" -"checksum rust-webvr 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4251e156fc27e2ce17a747e3270ee6940c754145cead0cf5da29792328baf473" -"checksum rust-webvr-api 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f8ae20fc34d4b4f59d00be7fa2c06802ad90a0a33195a6f5f73832c6acc5b8fa" +"checksum rust-webvr 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ab7402cf0d85fa4323297ac9d2b329b6d5f730a8cb40c90a8708e6b58d643c60" +"checksum rust-webvr-api 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1b2af5c6c86fb79e70b5a34daa3d488411225707c73dc5467c7da7c83d557daf" "checksum rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3058a43ada2c2d0b92b3ae38007a2d0fa5e9db971be260e0171408a4ff471c95" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum rusttype 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b8eb11f5b0a98c8eca2fb1483f42646d8c340e83e46ab416f8a063a0fd0eeb20" diff --git a/components/compositing/Cargo.toml b/components/compositing/Cargo.toml index 426746838b3..c07e7365ad9 100644 --- a/components/compositing/Cargo.toml +++ b/components/compositing/Cargo.toml @@ -39,6 +39,7 @@ style_traits = {path = "../style_traits"} time = "0.1.17" webrender = {git = "https://github.com/servo/webrender", features = ["capture"]} webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} +webvr_traits = {path = "../webvr_traits"} webvr = {path = "../webvr"} [build-dependencies] diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index 253fc1cb925..9ff74668e0d 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -43,6 +43,7 @@ use style_traits::{CSSPixel, DevicePixel, PinchZoomFactor}; use time::{now, precise_time_ns, precise_time_s}; use webrender_api::{self, DeviceIntPoint, DevicePoint, HitTestFlags, HitTestResult}; use webrender_api::{LayoutVector2D, ScrollLocation}; +use webvr_traits::WebVRMainThreadHeartbeat; #[derive(Debug, PartialEq)] enum UnableToComposite { @@ -176,6 +177,9 @@ pub struct IOCompositor<Window: WindowMethods> { /// The webrender interface, if enabled. webrender_api: webrender_api::RenderApi, + /// Some VR displays want to be sent a heartbeat from the main thread. + webvr_heartbeats: Vec<Box<dyn WebVRMainThreadHeartbeat>>, + /// Map of the pending paint metrics per layout thread. /// The layout thread for each specific pipeline expects the compositor to /// paint frames with specific given IDs (epoch). Once the compositor paints @@ -283,6 +287,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { webrender: state.webrender, webrender_document: state.webrender_document, webrender_api: state.webrender_api, + webvr_heartbeats: state.webvr_heartbeats, pending_paint_metrics: HashMap::new(), } } @@ -919,7 +924,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { pipeline_ids.push(*pipeline_id); } } - let animation_state = if pipeline_ids.is_empty() { + let animation_state = if pipeline_ids.is_empty() && !self.webvr_heartbeats_racing() { windowing::AnimationState::Idle } else { windowing::AnimationState::Animating @@ -930,6 +935,10 @@ impl<Window: WindowMethods> IOCompositor<Window> { } } + fn webvr_heartbeats_racing(&self) -> bool { + self.webvr_heartbeats.iter().any(|hb| hb.heart_racing()) + } + fn tick_animations_for_pipeline(&mut self, pipeline_id: PipelineId) { let animation_callbacks_running = self .pipeline_details(pipeline_id) @@ -1345,6 +1354,11 @@ impl<Window: WindowMethods> IOCompositor<Window> { CompositionRequest::CompositeNow(_) => self.composite(), } + // Send every VR display that wants one a main-thread heartbeat + for webvr_heartbeat in &mut self.webvr_heartbeats { + webvr_heartbeat.heartbeat(); + } + if !self.pending_scroll_zoom_events.is_empty() && !self.waiting_for_results_of_scroll { self.process_pending_scroll_events() } diff --git a/components/compositing/compositor_thread.rs b/components/compositing/compositor_thread.rs index e4dee4f595a..1a7ee9309cb 100644 --- a/components/compositing/compositor_thread.rs +++ b/components/compositing/compositor_thread.rs @@ -18,6 +18,7 @@ use script_traits::{AnimationState, ConstellationMsg, EventResult}; use std::fmt::{Debug, Error, Formatter}; use style_traits::viewport::ViewportConstraints; use webrender_api::{self, DeviceIntPoint, DeviceIntSize}; +use webvr_traits::WebVRMainThreadHeartbeat; /// Sends messages to the compositor. pub struct CompositorProxy { @@ -153,4 +154,5 @@ pub struct InitialCompositorState { pub webrender: webrender::Renderer, pub webrender_document: webrender_api::DocumentId, pub webrender_api: webrender_api::RenderApi, + pub webvr_heartbeats: Vec<Box<WebVRMainThreadHeartbeat>>, } diff --git a/components/compositing/windowing.rs b/components/compositing/windowing.rs index 091eb661a5e..6c4ba4b3cee 100644 --- a/components/compositing/windowing.rs +++ b/components/compositing/windowing.rs @@ -19,6 +19,7 @@ use std::rc::Rc; use style_traits::DevicePixel; use webrender_api::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, DevicePoint, ScrollLocation}; use webvr::VRServiceManager; +use webvr_traits::WebVRMainThreadHeartbeat; #[derive(Clone)] pub enum MouseWindowEvent { @@ -147,7 +148,12 @@ pub trait WindowMethods { /// run the event loop at the vsync interval. fn set_animation_state(&self, _state: AnimationState); /// Register services with a VRServiceManager. - fn register_vr_services(&self, _: &mut VRServiceManager) {} + fn register_vr_services( + &self, + _: &mut VRServiceManager, + _: &mut Vec<Box<WebVRMainThreadHeartbeat>>, + ) { + } } #[derive(Clone, Copy, Debug)] diff --git a/components/servo/lib.rs b/components/servo/lib.rs index 95a02c25afc..cc3a7c849c2 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -258,10 +258,11 @@ where // can't defer it after `create_constellation` has started. script::init(); + let mut webvr_heartbeats = Vec::new(); let webvr_services = if PREFS.is_webvr_enabled() { let mut services = VRServiceManager::new(); services.register_defaults(); - window.register_vr_services(&mut services); + window.register_vr_services(&mut services, &mut webvr_heartbeats); Some(services) } else { None @@ -308,6 +309,7 @@ where webrender, webrender_document, webrender_api, + webvr_heartbeats, }, ); diff --git a/components/webvr/Cargo.toml b/components/webvr/Cargo.toml index e88fbb2682e..faca3eb57a6 100644 --- a/components/webvr/Cargo.toml +++ b/components/webvr/Cargo.toml @@ -22,7 +22,7 @@ gleam = "0.6" ipc-channel = "0.11" log = "0.4" msg = {path = "../msg"} -rust-webvr = {version = "0.10", features = ["openvr", "vrexternal"]} +rust-webvr = {version = "0.10.2", features = ["openvr", "vrexternal"]} script_traits = {path = "../script_traits"} servo_config = {path = "../config"} webvr_traits = {path = "../webvr_traits" } diff --git a/components/webvr/lib.rs b/components/webvr/lib.rs index e1acd062357..cc24381ca57 100644 --- a/components/webvr/lib.rs +++ b/components/webvr/lib.rs @@ -10,4 +10,5 @@ extern crate log; mod webvr_thread; pub use crate::webvr_thread::{WebVRCompositorHandler, WebVRThread}; pub use rust_webvr::api::VRExternalShmemPtr; +pub use rust_webvr::VRMainThreadHeartbeat; pub use rust_webvr::VRServiceManager; diff --git a/components/webvr_traits/lib.rs b/components/webvr_traits/lib.rs index 04dfca47fad..ab31436c136 100644 --- a/components/webvr_traits/lib.rs +++ b/components/webvr_traits/lib.rs @@ -27,5 +27,6 @@ pub use rust_webvr_api::VRGamepadEvent as WebVRGamepadEvent; pub use rust_webvr_api::VRGamepadHand as WebVRGamepadHand; pub use rust_webvr_api::VRGamepadState as WebVRGamepadState; 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; diff --git a/ports/libsimpleservo/api/src/lib.rs b/ports/libsimpleservo/api/src/lib.rs index 4f493fc54e0..8622f832af7 100644 --- a/ports/libsimpleservo/api/src/lib.rs +++ b/ports/libsimpleservo/api/src/lib.rs @@ -21,7 +21,7 @@ use servo::script_traits::{TouchEventType, TouchId}; use servo::servo_config::opts; use servo::servo_config::prefs::{PrefValue, PREFS}; use servo::servo_url::ServoUrl; -use servo::webvr::{VRExternalShmemPtr, VRServiceManager}; +use servo::webvr::{VRExternalShmemPtr, VRMainThreadHeartbeat, VRServiceManager}; use servo::{self, gl, webrender_api, BrowserId, Servo}; use std::cell::{Cell, RefCell}; use std::mem; @@ -576,7 +576,11 @@ impl WindowMethods for ServoCallbacks { } } - fn register_vr_services(&self, services: &mut VRServiceManager) { + fn register_vr_services( + &self, + services: &mut VRServiceManager, + _: &mut Vec<Box<VRMainThreadHeartbeat>>, + ) { if let Some(ptr) = self.vr_pointer { services.register_vrexternal(VRExternalShmemPtr::new(ptr)); } diff --git a/ports/servo/Cargo.toml b/ports/servo/Cargo.toml index 792cab27494..8f798d9cc65 100644 --- a/ports/servo/Cargo.toml +++ b/ports/servo/Cargo.toml @@ -51,6 +51,7 @@ lazy_static = "1" libservo = {path = "../../components/servo"} libc = "0.2" log = "0.4" +rust-webvr = { version = "0.10.2", features = ["glwindow"] } tinyfiledialogs = "3.0" winit = {version = "0.18", features = ["icon_loading"]} diff --git a/ports/servo/glutin_app/window.rs b/ports/servo/glutin_app/window.rs index c9ab4a0ab6f..ab6d35e2f5a 100644 --- a/ports/servo/glutin_app/window.rs +++ b/ports/servo/glutin_app/window.rs @@ -8,14 +8,18 @@ use euclid::{TypedPoint2D, TypedVector2D, TypedScale, TypedSize2D}; use gleam::gl; use glutin::{Api, ContextBuilder, GlContext, GlRequest, GlWindow}; use keyboard_types::{Key, KeyboardEvent, KeyState}; +use rust_webvr::GlWindowVRService; use servo::compositing::windowing::{AnimationState, MouseWindowEvent, WindowEvent}; use servo::compositing::windowing::{EmbedderCoordinates, WindowMethods}; use servo::embedder_traits::{Cursor, EventLoopWaker}; use servo::script_traits::TouchEventType; use servo::servo_config::opts; +use servo::servo_config::prefs::PREFS; use servo::servo_geometry::DeviceIndependentPixel; use servo::style_traits::DevicePixel; use servo::webrender_api::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, ScrollLocation}; +use servo::webvr::VRServiceManager; +use servo::webvr_traits::WebVRMainThreadHeartbeat; use std::cell::{Cell, RefCell}; #[cfg(any(target_os = "linux", target_os = "macos"))] use std::ffi::CString; @@ -440,6 +444,13 @@ impl Window { } fn winit_event_to_servo_event(&self, event: winit::Event) { + if let WindowKind::Window(ref window, _) = self.kind { + if let Event::WindowEvent { window_id, .. } = event { + if window.id() != window_id { + return; + } + } + } match event { Event::WindowEvent { event: winit::WindowEvent::ReceivedCharacter(ch), @@ -775,6 +786,39 @@ impl WindowMethods for Window { }; true } + + fn register_vr_services( + &self, + services: &mut VRServiceManager, + heartbeats: &mut Vec<Box<WebVRMainThreadHeartbeat>> + ) { + if PREFS.get("dom.webvr.test").as_boolean().unwrap_or(false) { + warn!("Creating test VR display"); + // TODO: support dom.webvr.test in headless environments + if let WindowKind::Window(_, ref events_loop) = self.kind { + // This is safe, because register_vr_services is called from the main thread. + let name = String::from("Test VR Display"); + let size = self.inner_size.get().to_f64(); + let size = LogicalSize::new(size.width, size.height); + let mut window_builder = winit::WindowBuilder::new() + .with_title(name.clone()) + .with_dimensions(size) + .with_visibility(false) + .with_multitouch(); + window_builder = builder_with_platform_options(window_builder); + let context_builder = ContextBuilder::new() + .with_gl(Window::gl_version()) + .with_vsync(false); // Assume the browser vsync is the same as the test VR window vsync + let gl_window = GlWindow::new(window_builder, context_builder, &*events_loop.borrow()) + .expect("Failed to create window."); + let gl = self.gl.clone(); + let (service, heartbeat) = GlWindowVRService::new(name, gl_window, gl); + + services.register(Box::new(service)); + heartbeats.push(Box::new(heartbeat)); + } + } + } } fn winit_phase_to_touch_event_type(phase: TouchPhase) -> TouchEventType { |