Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebVR API Implementation #14618

Merged
merged 1 commit into from Jan 9, 2017
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

WebVR API Implementation, r=larsbergstrom

  • Loading branch information
MortimerGoro committed Jan 9, 2017
commit c5705bff5003675d6d266c698653834027a78227

Some generated files are not rendered by default. Learn more.

@@ -211,7 +211,8 @@ impl<'a> CanvasPaintThread<'a> {
}
}
}
CanvasMsg::WebGL(_) => panic!("Wrong message sent to Canvas2D thread"),
CanvasMsg::WebGL(_) => panic!("Wrong WebGL message sent to Canvas2D thread"),
CanvasMsg::WebVR(_) => panic!("Wrong WebVR message sent to Canvas2D thread"),
}
}
}).expect("Thread spawning failed");
@@ -144,6 +144,18 @@ impl WebGLPaintThread {
}
}

fn handle_webvr_message(&self, message: webrender_traits::VRCompositorCommand) {
match self.data {
WebGLPaintTaskData::WebRender(ref api, id) => {
api.send_vr_compositor_command(id, message);
}
WebGLPaintTaskData::Readback(..) => {
error!("Webrender is required for WebVR implementation");
}
}
}


/// Creates a new `WebGLPaintThread` and returns an `IpcSender` to
/// communicate with it.
pub fn start(size: Size2D<i32>,
@@ -190,6 +202,7 @@ impl WebGLPaintThread {
}
}
CanvasMsg::Canvas2d(_) => panic!("Wrong message sent to WebGLThread"),
CanvasMsg::WebVR(message) => painter.handle_webvr_message(message)
}
}
}).expect("Thread spawning failed");
@@ -27,7 +27,7 @@ use euclid::size::Size2D;
use ipc_channel::ipc::IpcSender;
use std::default::Default;
use std::str::FromStr;
use webrender_traits::{WebGLCommand, WebGLContextId};
use webrender_traits::{WebGLCommand, WebGLContextId, VRCompositorCommand};

#[derive(Clone, Deserialize, Serialize)]
pub enum FillRule {
@@ -42,6 +42,7 @@ pub enum CanvasMsg {
FromLayout(FromLayoutMsg),
FromScript(FromScriptMsg),
WebGL(WebGLCommand),
WebVR(VRCompositorCommand)
}

#[derive(Clone, Deserialize, Serialize)]
@@ -259,4 +259,8 @@ impl Preferences {
pub fn extend(&self, extension: HashMap<String, Pref>) {
self.0.write().unwrap().extend(extension);
}

pub fn is_webvr_enabled(&self) -> bool {
self.get("dom.webvr.enabled").as_boolean().unwrap_or(false)
}
}
@@ -36,6 +36,7 @@ servo_config = {path = "../config", features = ["servo"]}
servo_rand = {path = "../rand"}
servo_remutex = {path = "../remutex"}
servo_url = {path = "../url", features = ["servo"]}
webvr_traits = {path = "../webvr_traits"}

[dependencies.webrender_traits]
git = "https://github.com/servo/webrender"
@@ -101,6 +101,7 @@ use script_traits::{LayoutMsg as FromLayoutMsg, ScriptMsg as FromScriptMsg, Scri
use script_traits::{LogEntry, ServiceWorkerMsg, webdriver_msg};
use script_traits::{MozBrowserErrorType, MozBrowserEvent, WebDriverCommandMsg, WindowSizeData};
use script_traits::{SWManagerMsg, ScopeThings, WindowSizeType};
use script_traits::WebVREventMsg;
use servo_config::opts;
use servo_config::prefs::PREFS;
use servo_rand::{Rng, SeedableRng, ServoRng, random};
@@ -122,6 +123,7 @@ use style_traits::cursor::Cursor;
use style_traits::viewport::ViewportConstraints;
use timer_scheduler::TimerScheduler;
use webrender_traits;
use webvr_traits::WebVRMsg;

/// The `Constellation` itself. In the servo browser, there is one
/// constellation, which maintains all of the browser global data.
@@ -280,6 +282,9 @@ pub struct Constellation<Message, LTF, STF> {

/// Phantom data that keeps the Rust type system happy.
phantom: PhantomData<(Message, LTF, STF)>,

/// A channel through which messages can be sent to the webvr thread.
webvr_thread: Option<IpcSender<WebVRMsg>>,
}

/// State needed to construct a constellation.
@@ -535,6 +540,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
info!("Using seed {} for random pipeline closure.", seed);
(rng, prob)
}),
webvr_thread: None
};

constellation.run();
@@ -645,6 +651,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
prev_visibility: prev_visibility,
webrender_api_sender: self.webrender_api_sender.clone(),
is_private: is_private,
webvr_thread: self.webvr_thread.clone()
});

let pipeline = match result {
@@ -879,6 +886,14 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
FromCompositorMsg::LogEntry(top_level_frame_id, thread_name, entry) => {
self.handle_log_entry(top_level_frame_id, thread_name, entry);
}
FromCompositorMsg::SetWebVRThread(webvr_thread) => {
assert!(self.webvr_thread.is_none());
self.webvr_thread = Some(webvr_thread)
}
FromCompositorMsg::WebVREvent(pipeline_ids, event) => {
debug!("constellation got WebVR event");
self.handle_webvr_event(pipeline_ids, event);
}
}
}

@@ -1186,6 +1201,13 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
}

if let Some(chan) = self.webvr_thread.as_ref() {
debug!("Exiting WebVR thread.");

This comment has been minimized.

Copy link
@cvan

cvan Dec 19, 2016

should this be logged outside the if check (à la above)?

This comment has been minimized.

Copy link
@MortimerGoro

MortimerGoro Dec 19, 2016

Author Contributor

I included it inside the if because WebVR can be disabled and it didn't make sense to show that message in that case. I checked and the same pattern is used in ""Exiting devtools" too ;)

if let Err(e) = chan.send(WebVRMsg::Exit) {
warn!("Exit WebVR thread failed ({})", e);
}
}

debug!("Exiting font cache thread.");
self.font_cache_thread.exit();

@@ -1274,6 +1296,18 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
}

fn handle_webvr_event(&mut self, ids: Vec<PipelineId>, event: WebVREventMsg) {
for id in ids {
match self.pipelines.get_mut(&id) {
Some(ref pipeline) => {
// Notify script thread
let _ = pipeline.event_loop.send(ConstellationControlMsg::WebVREvent(id, event.clone()));
},
None => warn!("constellation got webvr event for dead pipeline")
}
}
}

fn handle_init_load(&mut self, url: ServoUrl) {
let window_size = self.window_size.visible_viewport;
let root_pipeline_id = PipelineId::new();
@@ -41,6 +41,7 @@ extern crate servo_remutex;
extern crate servo_url;
extern crate style_traits;
extern crate webrender_traits;
extern crate webvr_traits;

mod constellation;
mod event_loop;
@@ -36,6 +36,7 @@ use std::rc::Rc;
use std::sync::mpsc::Sender;
use style_traits::{PagePx, ViewportPx};
use webrender_traits;
use webvr_traits::WebVRMsg;

/// A `Pipeline` is the constellation's view of a `Document`. Each pipeline has an
/// event loop (executed by a script thread) and a layout thread. A script thread
@@ -169,6 +170,8 @@ pub struct InitialPipelineState {

/// Whether this pipeline is considered private.
pub is_private: bool,
/// A channel to the webvr thread.
pub webvr_thread: Option<IpcSender<WebVRMsg>>,
}

impl Pipeline {
@@ -268,6 +271,7 @@ impl Pipeline {
script_content_process_shutdown_chan: script_content_process_shutdown_chan,
script_content_process_shutdown_port: script_content_process_shutdown_port,
webrender_api_sender: state.webrender_api_sender,
webvr_thread: state.webvr_thread,
};

// Spawn the child process.
@@ -470,6 +474,7 @@ pub struct UnprivilegedPipelineContent {
script_content_process_shutdown_chan: IpcSender<()>,
script_content_process_shutdown_port: IpcReceiver<()>,
webrender_api_sender: webrender_traits::RenderApiSender,
webvr_thread: Option<IpcSender<WebVRMsg>>,
}

impl UnprivilegedPipelineContent {
@@ -496,6 +501,7 @@ impl UnprivilegedPipelineContent {
window_size: self.window_size,
pipeline_namespace_id: self.pipeline_namespace_id,
content_process_shutdown_chan: self.script_content_process_shutdown_chan,
webvr_thread: self.webvr_thread
}, self.load_data.clone());

LTF::create(self.id,
@@ -151,6 +151,7 @@ impl Formattable for ProfilerCategory {
ProfilerCategory::ScriptServiceWorkerEvent => "Script Service Worker Event",
ProfilerCategory::ScriptEnterFullscreen => "Script Enter Fullscreen",
ProfilerCategory::ScriptExitFullscreen => "Script Exit Fullscreen",
ProfilerCategory::ScriptWebVREvent => "Script WebVR Event",
ProfilerCategory::ApplicationHeartbeat => "Application Heartbeat",
};
format!("{}{}", padding, name)
@@ -88,6 +88,7 @@ pub enum ProfilerCategory {
ScriptParseXML = 0x76,
ScriptEnterFullscreen = 0x77,
ScriptExitFullscreen = 0x78,
ScriptWebVREvent = 0x79,
ApplicationHeartbeat = 0x90,
}

@@ -82,6 +82,8 @@ url = {version = "1.2", features = ["heap_size", "query_encoding"]}
uuid = {version = "0.3.1", features = ["v4"]}
websocket = "0.17"
xml5ever = {version = "0.3.1", features = ["unstable"]}
webvr = {path = "../webvr"}
webvr_traits = {path = "../webvr_traits"}

[dependencies.webrender_traits]
git = "https://github.com/servo/webrender"
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.