Improve WebGL architecture.

This commit is contained in:
Imanol Fernandez 2017-08-15 16:05:22 +02:00
parent e9cbbc58cc
commit 703962fe61
54 changed files with 3154 additions and 1426 deletions

View file

@ -10,10 +10,11 @@ name = "webvr"
path = "lib.rs"
[dependencies]
canvas_traits = {path = "../canvas_traits"}
euclid = "0.15"
ipc-channel = "0.8"
log = "0.3"
msg = {path = "../msg"}
script_traits = {path = "../script_traits"}
servo_config = {path = "../config"}
webvr_traits = {path = "../webvr_traits" }
webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}

View file

@ -4,13 +4,14 @@
#![deny(unsafe_code)]
extern crate canvas_traits;
extern crate euclid;
extern crate ipc_channel;
#[macro_use]
extern crate log;
extern crate msg;
extern crate script_traits;
extern crate servo_config;
extern crate webrender_api;
extern crate webvr_traits;
mod webvr_thread;

View file

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use canvas_traits::webgl;
use euclid::Size2D;
use ipc_channel::ipc;
use ipc_channel::ipc::{IpcReceiver, IpcSender};
use msg::constellation_msg::PipelineId;
@ -11,8 +13,6 @@ use std::{thread, time};
use std::collections::{HashMap, HashSet};
use std::sync::mpsc;
use std::sync::mpsc::{Receiver, Sender};
use webrender_api;
use webrender_api::DeviceIntSize;
use webvr_traits::{WebVRMsg, WebVRResult};
use webvr_traits::webvr::*;
@ -34,7 +34,7 @@ use webvr_traits::webvr::*;
/// ids using the WebVR APIs. These ids are used to implement privacy guidelines defined in the WebVR Spec.
/// * When a JavaScript thread gains access to present to a headset, WebVRThread is not used as a intermediary in
/// the VRDisplay.requestAnimationFrame loop in order to minimize latency. A direct communication with WebRender
/// is used instead. See WebVRCompositorHandler and the VRCompositorCommanda for more details.
/// is used instead. See WebVRCompositorHandler and the WebVRCommands for more details.
pub struct WebVRThread {
receiver: IpcReceiver<WebVRMsg>,
sender: IpcSender<WebVRMsg>,
@ -66,15 +66,17 @@ impl WebVRThread {
}
}
pub fn spawn(constellation_chan: Sender<ConstellationMsg>,
vr_compositor_chan: WebVRCompositorSender)
-> IpcSender<WebVRMsg> {
pub fn spawn(vr_compositor_chan: WebVRCompositorSender)
-> (IpcSender<WebVRMsg>, Sender<Sender<ConstellationMsg>>) {
let (sender, receiver) = ipc::channel().unwrap();
let (constellation_sender, constellation_receiver) = mpsc::channel();
let sender_clone = sender.clone();
thread::Builder::new().name("WebVRThread".into()).spawn(move || {
let constellation_chan = constellation_receiver.recv().unwrap();
WebVRThread::new(receiver, sender_clone, constellation_chan, vr_compositor_chan).start();
}).expect("Thread spawning failed");
sender
(sender, constellation_sender)
}
fn start(&mut self) {
@ -305,7 +307,7 @@ impl WebVRThread {
pub struct WebVRCompositor(*mut VRDisplay);
pub struct WebVRCompositorHandler {
compositors: HashMap<webrender_api::VRCompositorId, WebVRCompositor>,
compositors: HashMap<webgl::WebVRDeviceId, WebVRCompositor>,
webvr_thread_receiver: Receiver<Option<WebVRCompositor>>,
webvr_thread_sender: Option<IpcSender<WebVRMsg>>
}
@ -328,14 +330,14 @@ impl WebVRCompositorHandler {
}
}
impl webrender_api::VRCompositorHandler for WebVRCompositorHandler {
impl webgl::WebVRRenderHandler for WebVRCompositorHandler {
#[allow(unsafe_code)]
fn handle(&mut self, cmd: webrender_api::VRCompositorCommand, texture: Option<(u32, DeviceIntSize)>) {
fn handle(&mut self, cmd: webgl::WebVRCommand, texture: Option<(u32, Size2D<i32>)>) {
match cmd {
webrender_api::VRCompositorCommand::Create(compositor_id) => {
webgl::WebVRCommand::Create(compositor_id) => {
self.create_compositor(compositor_id);
}
webrender_api::VRCompositorCommand::SyncPoses(compositor_id, near, far, sender) => {
webgl::WebVRCommand::SyncPoses(compositor_id, near, far, sender) => {
if let Some(compositor) = self.compositors.get(&compositor_id) {
let pose = unsafe {
(*compositor.0).sync_poses();
@ -346,7 +348,7 @@ impl webrender_api::VRCompositorHandler for WebVRCompositorHandler {
let _ = sender.send(Err(()));
}
}
webrender_api::VRCompositorCommand::SubmitFrame(compositor_id, left_bounds, right_bounds) => {
webgl::WebVRCommand::SubmitFrame(compositor_id, left_bounds, right_bounds) => {
if let Some(compositor) = self.compositors.get(&compositor_id) {
if let Some((texture_id, size)) = texture {
let layer = VRLayer {
@ -361,7 +363,7 @@ impl webrender_api::VRCompositorHandler for WebVRCompositorHandler {
}
}
}
webrender_api::VRCompositorCommand::Release(compositor_id) => {
webgl::WebVRCommand::Release(compositor_id) => {
self.compositors.remove(&compositor_id);
}
}
@ -370,7 +372,7 @@ impl webrender_api::VRCompositorHandler for WebVRCompositorHandler {
impl WebVRCompositorHandler {
#[allow(unsafe_code)]
fn create_compositor(&mut self, display_id: webrender_api::VRCompositorId) {
fn create_compositor(&mut self, display_id: webgl::WebVRDeviceId) {
let sender = match self.webvr_thread_sender {
Some(ref s) => s,
None => return,