mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Replace use of callbacks in webxr by channels
This commit is contained in:
parent
5c8fee4e0b
commit
133a17e15c
11 changed files with 109 additions and 190 deletions
30
Cargo.lock
generated
30
Cargo.lock
generated
|
@ -411,6 +411,7 @@ dependencies = [
|
||||||
"webrender 0.60.0 (git+https://github.com/servo/webrender)",
|
"webrender 0.60.0 (git+https://github.com/servo/webrender)",
|
||||||
"webrender_api 0.60.0 (git+https://github.com/servo/webrender)",
|
"webrender_api 0.60.0 (git+https://github.com/servo/webrender)",
|
||||||
"webrender_traits 0.0.1",
|
"webrender_traits 0.0.1",
|
||||||
|
"webxr-api 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -431,7 +432,7 @@ dependencies = [
|
||||||
"typetag 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"typetag 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"webrender_api 0.60.0 (git+https://github.com/servo/webrender)",
|
"webrender_api 0.60.0 (git+https://github.com/servo/webrender)",
|
||||||
"webvr_traits 0.0.1",
|
"webvr_traits 0.0.1",
|
||||||
"webxr-api 0.0.1 (git+https://github.com/servo/webxr)",
|
"webxr-api 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -621,7 +622,7 @@ dependencies = [
|
||||||
"webrender_api 0.60.0 (git+https://github.com/servo/webrender)",
|
"webrender_api 0.60.0 (git+https://github.com/servo/webrender)",
|
||||||
"webvr 0.0.1",
|
"webvr 0.0.1",
|
||||||
"webvr_traits 0.0.1",
|
"webvr_traits 0.0.1",
|
||||||
"webxr-api 0.0.1 (git+https://github.com/servo/webxr)",
|
"webxr-api 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -664,7 +665,7 @@ dependencies = [
|
||||||
"style_traits 0.0.1",
|
"style_traits 0.0.1",
|
||||||
"webrender_api 0.60.0 (git+https://github.com/servo/webrender)",
|
"webrender_api 0.60.0 (git+https://github.com/servo/webrender)",
|
||||||
"webvr_traits 0.0.1",
|
"webvr_traits 0.0.1",
|
||||||
"webxr-api 0.0.1 (git+https://github.com/servo/webxr)",
|
"webxr-api 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1087,7 +1088,7 @@ dependencies = [
|
||||||
"servo_url 0.0.1",
|
"servo_url 0.0.1",
|
||||||
"style_traits 0.0.1",
|
"style_traits 0.0.1",
|
||||||
"webrender_api 0.60.0 (git+https://github.com/servo/webrender)",
|
"webrender_api 0.60.0 (git+https://github.com/servo/webrender)",
|
||||||
"webxr-api 0.0.1 (git+https://github.com/servo/webxr)",
|
"webxr-api 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2537,7 +2538,7 @@ dependencies = [
|
||||||
"webrender_traits 0.0.1",
|
"webrender_traits 0.0.1",
|
||||||
"webvr 0.0.1",
|
"webvr 0.0.1",
|
||||||
"webvr_traits 0.0.1",
|
"webvr_traits 0.0.1",
|
||||||
"webxr-api 0.0.1 (git+https://github.com/servo/webxr)",
|
"webxr-api 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3912,7 +3913,7 @@ dependencies = [
|
||||||
"uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"webrender_api 0.60.0 (git+https://github.com/servo/webrender)",
|
"webrender_api 0.60.0 (git+https://github.com/servo/webrender)",
|
||||||
"webvr_traits 0.0.1",
|
"webvr_traits 0.0.1",
|
||||||
"webxr-api 0.0.1 (git+https://github.com/servo/webxr)",
|
"webxr-api 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)",
|
||||||
"xml5ever 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"xml5ever 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -4004,7 +4005,7 @@ dependencies = [
|
||||||
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"webrender_api 0.60.0 (git+https://github.com/servo/webrender)",
|
"webrender_api 0.60.0 (git+https://github.com/servo/webrender)",
|
||||||
"webvr_traits 0.0.1",
|
"webvr_traits 0.0.1",
|
||||||
"webxr-api 0.0.1 (git+https://github.com/servo/webxr)",
|
"webxr-api 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -4101,8 +4102,8 @@ dependencies = [
|
||||||
"servo-media 0.1.0 (git+https://github.com/servo/media)",
|
"servo-media 0.1.0 (git+https://github.com/servo/media)",
|
||||||
"sig 1.0.0 (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)",
|
"tinyfiledialogs 3.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"webxr 0.0.1 (git+https://github.com/servo/webxr)",
|
"webxr 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)",
|
||||||
"webxr-api 0.0.1 (git+https://github.com/servo/webxr)",
|
"webxr-api 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winres 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winres 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"x11 2.17.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"x11 2.17.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -5495,25 +5496,24 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webxr"
|
name = "webxr"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
source = "git+https://github.com/servo/webxr#0418277175dbccf83e575c99d6b9c778bfdbe70b"
|
source = "git+https://github.com/asajeffrey/webxr?branch=optional-glsync#da820a3ab266fce07c9a8abee3e6e9231cb93ec5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gleam 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gleam 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glutin 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glutin 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"webxr-api 0.0.1 (git+https://github.com/servo/webxr)",
|
"webxr-api 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webxr-api"
|
name = "webxr-api"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
source = "git+https://github.com/servo/webxr#0418277175dbccf83e575c99d6b9c778bfdbe70b"
|
source = "git+https://github.com/asajeffrey/webxr?branch=optional-glsync#da820a3ab266fce07c9a8abee3e6e9231cb93ec5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gleam 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gleam 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ipc-channel 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ipc-channel 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"typetag 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -6142,8 +6142,8 @@ dependencies = [
|
||||||
"checksum webrender 0.60.0 (git+https://github.com/servo/webrender)" = "<none>"
|
"checksum webrender 0.60.0 (git+https://github.com/servo/webrender)" = "<none>"
|
||||||
"checksum webrender_api 0.60.0 (git+https://github.com/servo/webrender)" = "<none>"
|
"checksum webrender_api 0.60.0 (git+https://github.com/servo/webrender)" = "<none>"
|
||||||
"checksum webrender_build 0.0.1 (git+https://github.com/servo/webrender)" = "<none>"
|
"checksum webrender_build 0.0.1 (git+https://github.com/servo/webrender)" = "<none>"
|
||||||
"checksum webxr 0.0.1 (git+https://github.com/servo/webxr)" = "<none>"
|
"checksum webxr 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)" = "<none>"
|
||||||
"checksum webxr-api 0.0.1 (git+https://github.com/servo/webxr)" = "<none>"
|
"checksum webxr-api 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)" = "<none>"
|
||||||
"checksum weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164"
|
"checksum weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164"
|
||||||
"checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164"
|
"checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164"
|
||||||
"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770"
|
"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770"
|
||||||
|
|
|
@ -29,3 +29,7 @@ opt-level = 3
|
||||||
mio = { git = "https://github.com/servo/mio.git", branch = "servo" }
|
mio = { git = "https://github.com/servo/mio.git", branch = "servo" }
|
||||||
iovec = { git = "https://github.com/servo/iovec.git", branch = "servo" }
|
iovec = { git = "https://github.com/servo/iovec.git", branch = "servo" }
|
||||||
cmake = { git = "https://github.com/alexcrichton/cmake-rs" }
|
cmake = { git = "https://github.com/alexcrichton/cmake-rs" }
|
||||||
|
|
||||||
|
[patch."https://github.com/servo/webxr"]
|
||||||
|
webxr = { git = "https://github.com/asajeffrey/webxr", branch = "optional-glsync" }
|
||||||
|
webxr-api = { git = "https://github.com/asajeffrey/webxr", branch = "optional-glsync" }
|
||||||
|
|
|
@ -37,3 +37,4 @@ servo_config = {path = "../config"}
|
||||||
webrender = {git = "https://github.com/servo/webrender"}
|
webrender = {git = "https://github.com/servo/webrender"}
|
||||||
webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}
|
webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}
|
||||||
webrender_traits = {path = "../webrender_traits"}
|
webrender_traits = {path = "../webrender_traits"}
|
||||||
|
webxr-api = {git = "https://github.com/servo/webxr", features = ["ipc"]}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use crate::gl_context::GLContextFactory;
|
use crate::gl_context::GLContextFactory;
|
||||||
use crate::webgl_thread::{WebGLMainThread, WebGLThread, WebGLThreadInit};
|
use crate::webgl_thread::{WebGLMainThread, WebGLThread, WebGLThreadInit};
|
||||||
use canvas_traits::webgl::webgl_channel;
|
use canvas_traits::webgl::webgl_channel;
|
||||||
|
@ -17,6 +16,7 @@ use std::default::Default;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use webrender_traits::{WebrenderExternalImageApi, WebrenderExternalImageRegistry};
|
use webrender_traits::{WebrenderExternalImageApi, WebrenderExternalImageRegistry};
|
||||||
|
use webxr_api::WebGLExternalImageApi;
|
||||||
|
|
||||||
/// WebGL Threading API entry point that lives in the constellation.
|
/// WebGL Threading API entry point that lives in the constellation.
|
||||||
pub struct WebGLThreads(WebGLSender<WebGLMsg>);
|
pub struct WebGLThreads(WebGLSender<WebGLMsg>);
|
||||||
|
@ -38,6 +38,7 @@ impl WebGLThreads {
|
||||||
) -> (
|
) -> (
|
||||||
WebGLThreads,
|
WebGLThreads,
|
||||||
Option<Rc<WebGLMainThread>>,
|
Option<Rc<WebGLMainThread>>,
|
||||||
|
Box<dyn webxr_api::WebGLExternalImageApi>,
|
||||||
Box<dyn WebrenderExternalImageApi>,
|
Box<dyn WebrenderExternalImageApi>,
|
||||||
Option<Box<dyn webrender::OutputImageHandler>>,
|
Option<Box<dyn webrender::OutputImageHandler>>,
|
||||||
) {
|
) {
|
||||||
|
@ -77,6 +78,7 @@ impl WebGLThreads {
|
||||||
(
|
(
|
||||||
WebGLThreads(sender),
|
WebGLThreads(sender),
|
||||||
webgl_thread,
|
webgl_thread,
|
||||||
|
external.sendable.clone_box(),
|
||||||
Box::new(external),
|
Box::new(external),
|
||||||
output_handler.map(|b| b as Box<_>),
|
output_handler.map(|b| b as Box<_>),
|
||||||
)
|
)
|
||||||
|
@ -96,9 +98,8 @@ impl WebGLThreads {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Bridge between the webrender::ExternalImage callbacks and the WebGLThreads.
|
/// Bridge between the webxr_api::ExternalImage callbacks and the WebGLThreads.
|
||||||
struct WebGLExternalImages {
|
struct SendableWebGLExternalImages {
|
||||||
webrender_gl: Rc<dyn gl::Gl>,
|
|
||||||
webgl_channel: WebGLSender<WebGLMsg>,
|
webgl_channel: WebGLSender<WebGLMsg>,
|
||||||
// Used to avoid creating a new channel on each received WebRender request.
|
// Used to avoid creating a new channel on each received WebRender request.
|
||||||
lock_channel: (
|
lock_channel: (
|
||||||
|
@ -107,24 +108,26 @@ struct WebGLExternalImages {
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebGLExternalImages {
|
impl SendableWebGLExternalImages {
|
||||||
fn new(webrender_gl: Rc<dyn gl::Gl>, channel: WebGLSender<WebGLMsg>) -> Self {
|
fn new(channel: WebGLSender<WebGLMsg>) -> Self {
|
||||||
WebGLExternalImages {
|
Self {
|
||||||
webrender_gl,
|
|
||||||
webgl_channel: channel,
|
webgl_channel: channel,
|
||||||
lock_channel: webgl_channel().unwrap(),
|
lock_channel: webgl_channel().unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebrenderExternalImageApi for WebGLExternalImages {
|
impl webxr_api::WebGLExternalImageApi for SendableWebGLExternalImages {
|
||||||
fn lock(&mut self, id: u64) -> (u32, Size2D<i32>) {
|
fn lock(&self, id: usize) -> (u32, Size2D<i32>, Option<gl::GLsync>) {
|
||||||
if let Some(main_thread) = WebGLMainThread::on_current_thread() {
|
if let Some(main_thread) = WebGLMainThread::on_current_thread() {
|
||||||
// If we're on the same thread as WebGL, we can get the data directly
|
// If we're on the same thread as WebGL, we can get the data directly
|
||||||
main_thread
|
let (image_id, size) = main_thread
|
||||||
.thread_data
|
.thread_data
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.handle_lock_unsync(WebGLContextId(id as usize))
|
.handle_lock_unsync(WebGLContextId(id as usize));
|
||||||
|
// We don't need a GLsync object if we're running on the main thread
|
||||||
|
// Might be better to return an option?
|
||||||
|
(image_id, size, None)
|
||||||
} else {
|
} else {
|
||||||
// WebGL Thread has it's own GL command queue that we need to synchronize with the WR GL command queue.
|
// WebGL Thread has it's own GL command queue that we need to synchronize with the WR GL command queue.
|
||||||
// The WebGLMsg::Lock message inserts a fence in the WebGL command queue.
|
// The WebGLMsg::Lock message inserts a fence in the WebGL command queue.
|
||||||
|
@ -135,16 +138,11 @@ impl WebrenderExternalImageApi for WebGLExternalImages {
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let (image_id, size, gl_sync) = self.lock_channel.1.recv().unwrap();
|
let (image_id, size, gl_sync) = self.lock_channel.1.recv().unwrap();
|
||||||
// The next glWaitSync call is run on the WR thread and it's used to synchronize the two
|
(image_id, size, Some(gl_sync as gl::GLsync))
|
||||||
// flows of OpenGL commands in order to avoid WR using a semi-ready WebGL texture.
|
|
||||||
// glWaitSync doesn't block WR thread, it affects only internal OpenGL subsystem.
|
|
||||||
self.webrender_gl
|
|
||||||
.wait_sync(gl_sync as gl::GLsync, 0, gl::TIMEOUT_IGNORED);
|
|
||||||
(image_id, size)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unlock(&mut self, id: u64) {
|
fn unlock(&self, id: usize) {
|
||||||
if let Some(main_thread) = WebGLMainThread::on_current_thread() {
|
if let Some(main_thread) = WebGLMainThread::on_current_thread() {
|
||||||
// If we're on the same thread as WebGL, we can unlock directly
|
// If we're on the same thread as WebGL, we can unlock directly
|
||||||
main_thread
|
main_thread
|
||||||
|
@ -157,6 +155,42 @@ impl WebrenderExternalImageApi for WebGLExternalImages {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clone_box(&self) -> Box<dyn webxr_api::WebGLExternalImageApi> {
|
||||||
|
Box::new(Self::new(self.webgl_channel.clone()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Bridge between the webrender::ExternalImage callbacks and the WebGLThreads.
|
||||||
|
struct WebGLExternalImages {
|
||||||
|
webrender_gl: Rc<dyn gl::Gl>,
|
||||||
|
sendable: SendableWebGLExternalImages,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebGLExternalImages {
|
||||||
|
fn new(webrender_gl: Rc<dyn gl::Gl>, channel: WebGLSender<WebGLMsg>) -> Self {
|
||||||
|
Self {
|
||||||
|
webrender_gl,
|
||||||
|
sendable: SendableWebGLExternalImages::new(channel),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebrenderExternalImageApi for WebGLExternalImages {
|
||||||
|
fn lock(&mut self, id: u64) -> (u32, Size2D<i32>) {
|
||||||
|
let (image_id, size, gl_sync) = self.sendable.lock(id as usize);
|
||||||
|
// The next glWaitSync call is run on the WR thread and it's used to synchronize the two
|
||||||
|
// flows of OpenGL commands in order to avoid WR using a semi-ready WebGL texture.
|
||||||
|
// glWaitSync doesn't block WR thread, it affects only internal OpenGL subsystem.
|
||||||
|
if let Some(gl_sync) = gl_sync {
|
||||||
|
self.webrender_gl.wait_sync(gl_sync, 0, gl::TIMEOUT_IGNORED);
|
||||||
|
}
|
||||||
|
(image_id, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unlock(&mut self, id: u64) {
|
||||||
|
self.sendable.unlock(id as usize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// struct used to implement DOMToTexture feature and webrender::OutputImageHandler trait.
|
/// struct used to implement DOMToTexture feature and webrender::OutputImageHandler trait.
|
||||||
|
|
|
@ -10,7 +10,7 @@ use euclid::default::Size2D;
|
||||||
use fnv::FnvHashMap;
|
use fnv::FnvHashMap;
|
||||||
use gleam::gl;
|
use gleam::gl;
|
||||||
use half::f16;
|
use half::f16;
|
||||||
use ipc_channel::ipc::{self, IpcSender, OpaqueIpcMessage};
|
use ipc_channel::ipc::{self, OpaqueIpcMessage};
|
||||||
use ipc_channel::router::ROUTER;
|
use ipc_channel::router::ROUTER;
|
||||||
use offscreen_gl_context::{DrawBuffer, GLContext, NativeGLContextMethods};
|
use offscreen_gl_context::{DrawBuffer, GLContext, NativeGLContextMethods};
|
||||||
use pixels::{self, PixelFormat};
|
use pixels::{self, PixelFormat};
|
||||||
|
@ -284,9 +284,6 @@ impl WebGLThread {
|
||||||
WebGLMsg::Lock(ctx_id, sender) => {
|
WebGLMsg::Lock(ctx_id, sender) => {
|
||||||
self.handle_lock(ctx_id, sender);
|
self.handle_lock(ctx_id, sender);
|
||||||
},
|
},
|
||||||
WebGLMsg::LockIPC(ctx_id, sender) => {
|
|
||||||
self.handle_lock_ipc(ctx_id, sender);
|
|
||||||
},
|
|
||||||
WebGLMsg::Unlock(ctx_id) => {
|
WebGLMsg::Unlock(ctx_id) => {
|
||||||
self.handle_unlock(ctx_id);
|
self.handle_unlock(ctx_id);
|
||||||
},
|
},
|
||||||
|
@ -343,21 +340,6 @@ impl WebGLThread {
|
||||||
context_id: WebGLContextId,
|
context_id: WebGLContextId,
|
||||||
sender: WebGLSender<(u32, Size2D<i32>, usize)>,
|
sender: WebGLSender<(u32, Size2D<i32>, usize)>,
|
||||||
) {
|
) {
|
||||||
sender.send(self.handle_lock_sync(context_id)).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// handle_lock, but unconditionally IPC (used by webxr)
|
|
||||||
fn handle_lock_ipc(
|
|
||||||
&mut self,
|
|
||||||
context_id: WebGLContextId,
|
|
||||||
sender: IpcSender<(u32, Size2D<i32>, usize)>,
|
|
||||||
) {
|
|
||||||
sender.send(self.handle_lock_sync(context_id)).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Shared code between handle_lock and handle_lock_ipc, does the actual syncing/flushing
|
|
||||||
/// but the caller must send the response back
|
|
||||||
fn handle_lock_sync(&mut self, context_id: WebGLContextId) -> (u32, Size2D<i32>, usize) {
|
|
||||||
let data =
|
let data =
|
||||||
Self::make_current_if_needed(context_id, &self.contexts, &mut self.bound_context_id)
|
Self::make_current_if_needed(context_id, &self.contexts, &mut self.bound_context_id)
|
||||||
.expect("WebGLContext not found in a WebGLMsg::Lock message");
|
.expect("WebGLContext not found in a WebGLMsg::Lock message");
|
||||||
|
@ -374,7 +356,7 @@ impl WebGLThread {
|
||||||
data.ctx.gl().flush();
|
data.ctx.gl().flush();
|
||||||
debug_assert!(data.ctx.gl().get_error() == gl::NO_ERROR);
|
debug_assert!(data.ctx.gl().get_error() == gl::NO_ERROR);
|
||||||
|
|
||||||
(info.texture_id, info.size, gl_sync as usize)
|
let _ = sender.send((info.texture_id, info.size, gl_sync as usize));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A version of locking that doesn't return a GLsync object,
|
/// A version of locking that doesn't return a GLsync object,
|
||||||
|
|
|
@ -4,10 +4,8 @@
|
||||||
|
|
||||||
use euclid::default::{Rect, Size2D};
|
use euclid::default::{Rect, Size2D};
|
||||||
use gleam::gl;
|
use gleam::gl;
|
||||||
use gleam::gl::GLsync;
|
|
||||||
use gleam::gl::GLuint;
|
|
||||||
use gleam::gl::Gl;
|
use gleam::gl::Gl;
|
||||||
use ipc_channel::ipc::{self, IpcBytesReceiver, IpcBytesSender, IpcSender, IpcSharedMemory};
|
use ipc_channel::ipc::{IpcBytesReceiver, IpcBytesSender, IpcSharedMemory};
|
||||||
use pixels::PixelFormat;
|
use pixels::PixelFormat;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -61,8 +59,6 @@ pub enum WebGLMsg {
|
||||||
/// The WR client should not change the shared texture content until the Unlock call.
|
/// The WR client should not change the shared texture content until the Unlock call.
|
||||||
/// Currently OpenGL Sync Objects are used to implement the synchronization mechanism.
|
/// Currently OpenGL Sync Objects are used to implement the synchronization mechanism.
|
||||||
Lock(WebGLContextId, WebGLSender<(u32, Size2D<i32>, usize)>),
|
Lock(WebGLContextId, WebGLSender<(u32, Size2D<i32>, usize)>),
|
||||||
/// Lock(), but unconditionally IPC (used by webxr)
|
|
||||||
LockIPC(WebGLContextId, IpcSender<(u32, Size2D<i32>, usize)>),
|
|
||||||
/// Unlocks a specific WebGLContext. Unlock messages are used for a correct synchronization
|
/// Unlocks a specific WebGLContext. Unlock messages are used for a correct synchronization
|
||||||
/// with WebRender external image API.
|
/// with WebRender external image API.
|
||||||
/// The WR unlocks a context when it finished reading the shared texture contents.
|
/// The WR unlocks a context when it finished reading the shared texture contents.
|
||||||
|
@ -185,39 +181,6 @@ impl WebGLMsgSender {
|
||||||
pub fn send_dom_to_texture(&self, command: DOMToTextureCommand) -> WebGLSendResult {
|
pub fn send_dom_to_texture(&self, command: DOMToTextureCommand) -> WebGLSendResult {
|
||||||
self.sender.send(WebGLMsg::DOMToTextureCommand(command))
|
self.sender.send(WebGLMsg::DOMToTextureCommand(command))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn webxr_external_image_api(&self) -> impl webxr_api::WebGLExternalImageApi {
|
|
||||||
SerializableWebGLMsgSender {
|
|
||||||
ctx_id: self.ctx_id,
|
|
||||||
sender: self.sender.to_ipc(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WegGLMsgSender isn't actually serializable, despite what it claims.
|
|
||||||
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
|
|
||||||
struct SerializableWebGLMsgSender {
|
|
||||||
ctx_id: WebGLContextId,
|
|
||||||
#[ignore_malloc_size_of = "channels are hard"]
|
|
||||||
sender: IpcSender<WebGLMsg>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[typetag::serde]
|
|
||||||
impl webxr_api::WebGLExternalImageApi for SerializableWebGLMsgSender {
|
|
||||||
fn lock(&self) -> Result<(GLuint, Size2D<i32>, GLsync), webxr_api::Error> {
|
|
||||||
let (sender, receiver) = ipc::channel().or(Err(webxr_api::Error::CommunicationError))?;
|
|
||||||
self.sender
|
|
||||||
.send(WebGLMsg::LockIPC(self.ctx_id, sender))
|
|
||||||
.or(Err(webxr_api::Error::CommunicationError))?;
|
|
||||||
let (texture, size, sync) = receiver
|
|
||||||
.recv()
|
|
||||||
.or(Err(webxr_api::Error::CommunicationError))?;
|
|
||||||
Ok((texture, size, sync as GLsync))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unlock(&self) {
|
|
||||||
let _ = self.sender.send(WebGLMsg::Unlock(self.ctx_id));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
|
|
|
@ -328,6 +328,10 @@ impl WebGLRenderingContext {
|
||||||
self.webgl_sender.clone()
|
self.webgl_sender.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn context_id(&self) -> WebGLContextId {
|
||||||
|
self.webgl_sender.context_id()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn send_command(&self, command: WebGLCommand) {
|
pub fn send_command(&self, command: WebGLCommand) {
|
||||||
self.webgl_sender
|
self.webgl_sender
|
||||||
|
@ -4377,8 +4381,4 @@ impl WebGLMessageSender {
|
||||||
pub fn send_dom_to_texture(&self, command: DOMToTextureCommand) -> WebGLSendResult {
|
pub fn send_dom_to_texture(&self, command: DOMToTextureCommand) -> WebGLSendResult {
|
||||||
self.wake_after_send(|| self.sender.send_dom_to_texture(command))
|
self.wake_after_send(|| self.sender.send_dom_to_texture(command))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn webxr_external_image_api(&self) -> impl webxr_api::WebGLExternalImageApi {
|
|
||||||
self.sender.webxr_external_image_api()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,18 +108,6 @@ impl Into<SessionMode> for XRSessionMode {
|
||||||
impl XRMethods for XR {
|
impl XRMethods for XR {
|
||||||
/// https://immersive-web.github.io/webxr/#dom-xr-supportssessionmode
|
/// https://immersive-web.github.io/webxr/#dom-xr-supportssessionmode
|
||||||
fn SupportsSession(&self, mode: XRSessionMode) -> Rc<Promise> {
|
fn SupportsSession(&self, mode: XRSessionMode) -> Rc<Promise> {
|
||||||
#[derive(serde::Serialize, serde::Deserialize)]
|
|
||||||
pub struct SupportsSession {
|
|
||||||
sender: IpcSender<bool>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[typetag::serde]
|
|
||||||
impl webxr_api::SessionSupportCallback for SupportsSession {
|
|
||||||
fn callback(&mut self, result: Result<(), XRError>) {
|
|
||||||
let _ = self.sender.send(result.is_ok());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXXManishearth this should select an XR device first
|
// XXXManishearth this should select an XR device first
|
||||||
let promise = Promise::new(&self.global());
|
let promise = Promise::new(&self.global());
|
||||||
let mut trusted = Some(TrustedPromise::new(promise.clone()));
|
let mut trusted = Some(TrustedPromise::new(promise.clone()));
|
||||||
|
@ -139,13 +127,13 @@ impl XRMethods for XR {
|
||||||
error!("supportsSession callback called twice!");
|
error!("supportsSession callback called twice!");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let message = if let Ok(message) = message.to() {
|
let message: Result<(), webxr_api::Error> = if let Ok(message) = message.to() {
|
||||||
message
|
message
|
||||||
} else {
|
} else {
|
||||||
error!("supportsSession callback given incorrect payload");
|
error!("supportsSession callback given incorrect payload");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if message {
|
if let Ok(()) = message {
|
||||||
let _ = task_source.queue_with_canceller(trusted.resolve_task(()), &canceller);
|
let _ = task_source.queue_with_canceller(trusted.resolve_task(()), &canceller);
|
||||||
} else {
|
} else {
|
||||||
let _ = task_source
|
let _ = task_source
|
||||||
|
@ -155,7 +143,7 @@ impl XRMethods for XR {
|
||||||
);
|
);
|
||||||
window
|
window
|
||||||
.webxr_registry()
|
.webxr_registry()
|
||||||
.supports_session(mode.into(), SupportsSession { sender });
|
.supports_session(mode.into(), sender);
|
||||||
|
|
||||||
promise
|
promise
|
||||||
}
|
}
|
||||||
|
@ -167,17 +155,6 @@ impl XRMethods for XR {
|
||||||
_: &XRSessionInit,
|
_: &XRSessionInit,
|
||||||
comp: InCompartment,
|
comp: InCompartment,
|
||||||
) -> Rc<Promise> {
|
) -> Rc<Promise> {
|
||||||
#[derive(serde::Serialize, serde::Deserialize)]
|
|
||||||
pub struct RequestSession {
|
|
||||||
sender: IpcSender<Result<Session, XRError>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[typetag::serde]
|
|
||||||
impl webxr_api::SessionRequestCallback for RequestSession {
|
|
||||||
fn callback(&mut self, result: Result<Session, XRError>) {
|
|
||||||
let _ = self.sender.send(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let promise = Promise::new_in_current_compartment(&self.global(), comp);
|
let promise = Promise::new_in_current_compartment(&self.global(), comp);
|
||||||
if mode != XRSessionMode::Immersive_vr {
|
if mode != XRSessionMode::Immersive_vr {
|
||||||
promise.reject_error(Error::NotSupported);
|
promise.reject_error(Error::NotSupported);
|
||||||
|
@ -206,7 +183,7 @@ impl XRMethods for XR {
|
||||||
// router doesn't know this is only called once
|
// router doesn't know this is only called once
|
||||||
let trusted = trusted.take().unwrap();
|
let trusted = trusted.take().unwrap();
|
||||||
let this = this.clone();
|
let this = this.clone();
|
||||||
let message = if let Ok(message) = message.to() {
|
let message: Result<Session, webxr_api::Error> = if let Ok(message) = message.to() {
|
||||||
message
|
message
|
||||||
} else {
|
} else {
|
||||||
error!("requestSession callback given incorrect payload");
|
error!("requestSession callback given incorrect payload");
|
||||||
|
@ -220,9 +197,7 @@ impl XRMethods for XR {
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
window
|
window.webxr_registry().request_session(mode.into(), sender);
|
||||||
.webxr_registry()
|
|
||||||
.request_session(mode.into(), RequestSession { sender });
|
|
||||||
|
|
||||||
promise
|
promise
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,18 +124,6 @@ impl XRSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn attach_event_handler(&self) {
|
fn attach_event_handler(&self) {
|
||||||
#[derive(serde::Serialize, serde::Deserialize)]
|
|
||||||
pub struct EventCallback {
|
|
||||||
sender: IpcSender<XREvent>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[typetag::serde]
|
|
||||||
impl webxr_api::EventCallback for EventCallback {
|
|
||||||
fn callback(&mut self, event: XREvent) {
|
|
||||||
let _ = self.sender.send(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let this = Trusted::new(self);
|
let this = Trusted::new(self);
|
||||||
let global = self.global();
|
let global = self.global();
|
||||||
let window = global.as_window();
|
let window = global.as_window();
|
||||||
|
@ -143,6 +131,7 @@ impl XRSession {
|
||||||
.task_manager()
|
.task_manager()
|
||||||
.dom_manipulation_task_source_with_canceller();
|
.dom_manipulation_task_source_with_canceller();
|
||||||
let (sender, receiver) = ipc::channel(global.time_profiler_chan().clone()).unwrap();
|
let (sender, receiver) = ipc::channel(global.time_profiler_chan().clone()).unwrap();
|
||||||
|
|
||||||
ROUTER.add_route(
|
ROUTER.add_route(
|
||||||
receiver.to_opaque(),
|
receiver.to_opaque(),
|
||||||
Box::new(move |message| {
|
Box::new(move |message| {
|
||||||
|
@ -157,9 +146,7 @@ impl XRSession {
|
||||||
);
|
);
|
||||||
|
|
||||||
// request animation frame
|
// request animation frame
|
||||||
self.session
|
self.session.borrow_mut().set_event_dest(sender);
|
||||||
.borrow_mut()
|
|
||||||
.set_event_callback(EventCallback { sender });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn event_callback(&self, event: XREvent) {
|
fn event_callback(&self, event: XREvent) {
|
||||||
|
@ -195,13 +182,10 @@ impl XRSession {
|
||||||
// Step 6-7: XXXManishearth handle inlineVerticalFieldOfView
|
// Step 6-7: XXXManishearth handle inlineVerticalFieldOfView
|
||||||
|
|
||||||
// XXXManishearth handle inline sessions and composition disabled flag
|
// XXXManishearth handle inline sessions and composition disabled flag
|
||||||
let layer = pending.GetBaseLayer();
|
let context = pending
|
||||||
if let Some(layer) = layer {
|
.GetBaseLayer()
|
||||||
let mut session = self.session.borrow_mut();
|
.map(|layer| layer.Context().context_id().0);
|
||||||
session.update_webgl_external_image_api(
|
self.session.borrow_mut().set_webgl_context(context);
|
||||||
layer.Context().webgl_sender().webxr_external_image_api(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2
|
// Step 2
|
||||||
|
@ -289,18 +273,6 @@ impl XRSessionMethods for XRSession {
|
||||||
|
|
||||||
/// https://immersive-web.github.io/webxr/#dom-xrsession-requestanimationframe
|
/// https://immersive-web.github.io/webxr/#dom-xrsession-requestanimationframe
|
||||||
fn RequestAnimationFrame(&self, callback: Rc<XRFrameRequestCallback>) -> i32 {
|
fn RequestAnimationFrame(&self, callback: Rc<XRFrameRequestCallback>) -> i32 {
|
||||||
#[derive(serde::Serialize, serde::Deserialize)]
|
|
||||||
pub struct FrameCallback {
|
|
||||||
sender: IpcSender<(f64, Frame)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[typetag::serde]
|
|
||||||
impl webxr_api::FrameRequestCallback for FrameCallback {
|
|
||||||
fn callback(&mut self, time: f64, frame: Frame) {
|
|
||||||
let _ = self.sender.send((time, frame));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// queue up RAF callback, obtain ID
|
// queue up RAF callback, obtain ID
|
||||||
let raf_id = self.next_raf_id.get();
|
let raf_id = self.next_raf_id.get();
|
||||||
self.next_raf_id.set(raf_id + 1);
|
self.next_raf_id.set(raf_id + 1);
|
||||||
|
@ -334,9 +306,7 @@ impl XRSessionMethods for XRSession {
|
||||||
let sender = self.raf_sender.borrow().clone().unwrap();
|
let sender = self.raf_sender.borrow().clone().unwrap();
|
||||||
|
|
||||||
// request animation frame
|
// request animation frame
|
||||||
self.session
|
self.session.borrow_mut().request_animation_frame(sender);
|
||||||
.borrow_mut()
|
|
||||||
.request_animation_frame(FrameCallback { sender });
|
|
||||||
|
|
||||||
raf_id
|
raf_id
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,20 +73,6 @@ impl XRTest {
|
||||||
impl XRTestMethods for XRTest {
|
impl XRTestMethods for XRTest {
|
||||||
/// https://github.com/immersive-web/webxr-test-api/blob/master/explainer.md
|
/// https://github.com/immersive-web/webxr-test-api/blob/master/explainer.md
|
||||||
fn SimulateDeviceConnection(&self, init: &FakeXRDeviceInit) -> Rc<Promise> {
|
fn SimulateDeviceConnection(&self, init: &FakeXRDeviceInit) -> Rc<Promise> {
|
||||||
#[derive(serde::Serialize, serde::Deserialize)]
|
|
||||||
pub struct MockDevice {
|
|
||||||
sender: IpcSender<Result<IpcSender<MockDeviceMsg>, XRError>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[typetag::serde]
|
|
||||||
impl webxr_api::MockDeviceCallback for MockDevice {
|
|
||||||
fn callback(&mut self, result: Result<IpcSender<MockDeviceMsg>, XRError>) {
|
|
||||||
self.sender
|
|
||||||
.send(result)
|
|
||||||
.expect("mock device callback failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let p = Promise::new(&self.global());
|
let p = Promise::new(&self.global());
|
||||||
|
|
||||||
if !init.supportsImmersive || self.session_started.get() {
|
if !init.supportsImmersive || self.session_started.get() {
|
||||||
|
@ -166,7 +152,7 @@ impl XRTestMethods for XRTest {
|
||||||
);
|
);
|
||||||
window
|
window
|
||||||
.webxr_registry()
|
.webxr_registry()
|
||||||
.simulate_device_connection(init, MockDevice { sender });
|
.simulate_device_connection(init, sender);
|
||||||
|
|
||||||
p
|
p
|
||||||
}
|
}
|
||||||
|
|
|
@ -418,7 +418,8 @@ where
|
||||||
|
|
||||||
// Initialize WebGL Thread entry point.
|
// Initialize WebGL Thread entry point.
|
||||||
let webgl_result = gl_factory.map(|factory| {
|
let webgl_result = gl_factory.map(|factory| {
|
||||||
let (webgl_threads, thread_data, image_handler, output_handler) = WebGLThreads::new(
|
let (webgl_threads, thread_data, webxr_handler, image_handler, output_handler) =
|
||||||
|
WebGLThreads::new(
|
||||||
factory,
|
factory,
|
||||||
window.gl(),
|
window.gl(),
|
||||||
webrender_api_sender.clone(),
|
webrender_api_sender.clone(),
|
||||||
|
@ -434,6 +435,9 @@ where
|
||||||
// Set webrender external image handler for WebGL textures
|
// Set webrender external image handler for WebGL textures
|
||||||
external_image_handlers.set_handler(image_handler, WebrenderImageHandlerType::WebGL);
|
external_image_handlers.set_handler(image_handler, WebrenderImageHandlerType::WebGL);
|
||||||
|
|
||||||
|
// Set webxr external image handler for WebGL textures
|
||||||
|
webxr_main_thread.set_webgl(webxr_handler);
|
||||||
|
|
||||||
// Set DOM to texture handler, if enabled.
|
// Set DOM to texture handler, if enabled.
|
||||||
if let Some(output_handler) = output_handler {
|
if let Some(output_handler) = output_handler {
|
||||||
webrender.set_output_image_handler(output_handler);
|
webrender.set_output_image_handler(output_handler);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue