mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Integrate swapchain surface provider changes into webgl and webxr implementations.
This commit is contained in:
parent
b062f51495
commit
fbcf2bbc3e
17 changed files with 223 additions and 117 deletions
52
Cargo.lock
generated
52
Cargo.lock
generated
|
@ -496,8 +496,8 @@ dependencies = [
|
||||||
"raqote",
|
"raqote",
|
||||||
"servo_config",
|
"servo_config",
|
||||||
"sparkle",
|
"sparkle",
|
||||||
"surfman 0.1.3",
|
"surfman 0.1.4",
|
||||||
"surfman-chains 0.2.1",
|
"surfman-chains 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"surfman-chains-api",
|
"surfman-chains-api",
|
||||||
"time",
|
"time",
|
||||||
"webrender",
|
"webrender",
|
||||||
|
@ -742,6 +742,7 @@ dependencies = [
|
||||||
name = "compositing"
|
name = "compositing"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"canvas",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"embedder_traits",
|
"embedder_traits",
|
||||||
"euclid",
|
"euclid",
|
||||||
|
@ -3184,7 +3185,7 @@ dependencies = [
|
||||||
"sparkle",
|
"sparkle",
|
||||||
"style",
|
"style",
|
||||||
"style_traits",
|
"style_traits",
|
||||||
"surfman 0.1.3",
|
"surfman 0.1.4",
|
||||||
"webdriver_server",
|
"webdriver_server",
|
||||||
"webgpu",
|
"webgpu",
|
||||||
"webrender",
|
"webrender",
|
||||||
|
@ -5046,7 +5047,7 @@ dependencies = [
|
||||||
"servo-media",
|
"servo-media",
|
||||||
"sparkle",
|
"sparkle",
|
||||||
"surfman 0.2.0",
|
"surfman 0.2.0",
|
||||||
"surfman-chains 0.3.0",
|
"surfman-chains 0.3.0 (git+https://github.com/asajeffrey/surfman-chains?branch=multi)",
|
||||||
"surfman-chains-api",
|
"surfman-chains-api",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -5697,9 +5698,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "surfman"
|
name = "surfman"
|
||||||
version = "0.1.3"
|
version = "0.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "10248da202c1c8d8798783bbc4ba08e81ff225c6e2a394d64748d2a62acb198c"
|
checksum = "43bf043642ad98aaa51956091c4f829a400bad5f023b5f0095ecda61f925c63d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cgl 0.3.2",
|
"cgl 0.3.2",
|
||||||
|
@ -5726,7 +5727,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "surfman"
|
name = "surfman"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/pcwalton/surfman?branch=multi#808e5c5906dbcc6707536c8bac8bcc9389b4e1eb"
|
source = "git+https://github.com/pcwalton/surfman?branch=multi#fb782262617e7ca839a4e487b116a5199afaf963"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cgl 0.3.2",
|
"cgl 0.3.2",
|
||||||
|
@ -5750,20 +5751,6 @@ dependencies = [
|
||||||
"x11",
|
"x11",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "surfman-chains"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a2c1b5976b229a807a9e79b3b5248da577948b9882c77f2afce27cf562f80e22"
|
|
||||||
dependencies = [
|
|
||||||
"euclid",
|
|
||||||
"fnv",
|
|
||||||
"log",
|
|
||||||
"sparkle",
|
|
||||||
"surfman 0.1.3",
|
|
||||||
"surfman-chains-api",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "surfman-chains"
|
name = "surfman-chains"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
@ -5777,6 +5764,20 @@ dependencies = [
|
||||||
"surfman-chains-api",
|
"surfman-chains-api",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "surfman-chains"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a2a679f5be9644bbf93662f3b1a704cc6b81c147d4b7d6d5c8d8b6f453176f01"
|
||||||
|
dependencies = [
|
||||||
|
"euclid",
|
||||||
|
"fnv",
|
||||||
|
"log",
|
||||||
|
"sparkle",
|
||||||
|
"surfman 0.1.4",
|
||||||
|
"surfman-chains-api",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "surfman-chains-api"
|
name = "surfman-chains-api"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
@ -6649,9 +6650,10 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webxr"
|
name = "webxr"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
source = "git+https://github.com/servo/webxr#a1afba096c9797c3663727de58f54eae898f3050"
|
source = "git+https://github.com/servo/webxr#3ac3e83f37ff64c74c847a610a8cefba9b907a9c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bindgen",
|
"bindgen",
|
||||||
|
"crossbeam-channel",
|
||||||
"euclid",
|
"euclid",
|
||||||
"gl_generator 0.13.1",
|
"gl_generator 0.13.1",
|
||||||
"gleam 0.9.2",
|
"gleam 0.9.2",
|
||||||
|
@ -6659,8 +6661,8 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"openxr",
|
"openxr",
|
||||||
"serde",
|
"serde",
|
||||||
"surfman 0.1.3",
|
"surfman 0.1.4",
|
||||||
"surfman-chains 0.2.1",
|
"surfman-chains 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"time",
|
"time",
|
||||||
"webxr-api",
|
"webxr-api",
|
||||||
"winapi",
|
"winapi",
|
||||||
|
@ -6670,7 +6672,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webxr-api"
|
name = "webxr-api"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
source = "git+https://github.com/servo/webxr#a1afba096c9797c3663727de58f54eae898f3050"
|
source = "git+https://github.com/servo/webxr#3ac3e83f37ff64c74c847a610a8cefba9b907a9c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"euclid",
|
"euclid",
|
||||||
"ipc-channel",
|
"ipc-channel",
|
||||||
|
|
|
@ -42,5 +42,5 @@ webrender_traits = {path = "../webrender_traits"}
|
||||||
webxr-api = {git = "https://github.com/servo/webxr", features = ["ipc"]}
|
webxr-api = {git = "https://github.com/servo/webxr", features = ["ipc"]}
|
||||||
# NOTE: the sm-angle feature only enables angle on windows, not other platforms!
|
# NOTE: the sm-angle feature only enables angle on windows, not other platforms!
|
||||||
surfman = { version = "0.1", features = ["sm-angle", "sm-osmesa"] }
|
surfman = { version = "0.1", features = ["sm-angle", "sm-osmesa"] }
|
||||||
surfman-chains = "0.2"
|
surfman-chains = "0.3"
|
||||||
surfman-chains-api = "0.2"
|
surfman-chains-api = "0.2"
|
||||||
|
|
|
@ -12,6 +12,9 @@ extern crate log;
|
||||||
mod raqote_backend;
|
mod raqote_backend;
|
||||||
|
|
||||||
pub use webgl_mode::WebGLComm;
|
pub use webgl_mode::WebGLComm;
|
||||||
|
pub use webgl_thread::SurfaceProvider;
|
||||||
|
pub use webgl_thread::SurfaceProviders;
|
||||||
|
pub use webgl_thread::WebGlExecutor;
|
||||||
|
|
||||||
pub mod canvas_data;
|
pub mod canvas_data;
|
||||||
pub mod canvas_paint_thread;
|
pub mod canvas_paint_thread;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* 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::webgl_thread::{WebGLThread, WebGLThreadInit};
|
use crate::webgl_thread::{SurfaceProviders, WebGLThread, WebGLThreadInit, WebGlExecutor};
|
||||||
use canvas_traits::webgl::{webgl_channel, WebVRRenderHandler};
|
use canvas_traits::webgl::{webgl_channel, WebVRRenderHandler};
|
||||||
use canvas_traits::webgl::{WebGLContextId, WebGLMsg, WebGLThreads};
|
use canvas_traits::webgl::{WebGLContextId, WebGLMsg, WebGLThreads};
|
||||||
use euclid::default::Size2D;
|
use euclid::default::Size2D;
|
||||||
|
@ -11,6 +11,7 @@ use gleam;
|
||||||
use servo_config::pref;
|
use servo_config::pref;
|
||||||
use sparkle::gl;
|
use sparkle::gl;
|
||||||
use sparkle::gl::GlType;
|
use sparkle::gl::GlType;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
@ -27,8 +28,10 @@ use webxr_api::SwapChainId as WebXRSwapChainId;
|
||||||
pub struct WebGLComm {
|
pub struct WebGLComm {
|
||||||
pub webgl_threads: WebGLThreads,
|
pub webgl_threads: WebGLThreads,
|
||||||
pub webxr_swap_chains: SwapChains<WebXRSwapChainId>,
|
pub webxr_swap_chains: SwapChains<WebXRSwapChainId>,
|
||||||
|
pub webxr_surface_providers: SurfaceProviders,
|
||||||
pub image_handler: Box<dyn WebrenderExternalImageApi>,
|
pub image_handler: Box<dyn WebrenderExternalImageApi>,
|
||||||
pub output_handler: Option<Box<dyn webrender_api::OutputImageHandler>>,
|
pub output_handler: Option<Box<dyn webrender_api::OutputImageHandler>>,
|
||||||
|
pub webgl_executor: WebGlExecutor,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebGLComm {
|
impl WebGLComm {
|
||||||
|
@ -46,6 +49,8 @@ impl WebGLComm {
|
||||||
let (sender, receiver) = webgl_channel::<WebGLMsg>().unwrap();
|
let (sender, receiver) = webgl_channel::<WebGLMsg>().unwrap();
|
||||||
let webrender_swap_chains = SwapChains::new();
|
let webrender_swap_chains = SwapChains::new();
|
||||||
let webxr_swap_chains = SwapChains::new();
|
let webxr_swap_chains = SwapChains::new();
|
||||||
|
let webxr_surface_providers = Arc::new(Mutex::new(HashMap::new()));
|
||||||
|
let (runnable_sender, runnable_receiver) = crossbeam_channel::unbounded();
|
||||||
|
|
||||||
// This implementation creates a single `WebGLThread` for all the pipelines.
|
// This implementation creates a single `WebGLThread` for all the pipelines.
|
||||||
let init = WebGLThreadInit {
|
let init = WebGLThreadInit {
|
||||||
|
@ -56,9 +61,11 @@ impl WebGLComm {
|
||||||
receiver,
|
receiver,
|
||||||
webrender_swap_chains: webrender_swap_chains.clone(),
|
webrender_swap_chains: webrender_swap_chains.clone(),
|
||||||
webxr_swap_chains: webxr_swap_chains.clone(),
|
webxr_swap_chains: webxr_swap_chains.clone(),
|
||||||
|
webxr_surface_providers: webxr_surface_providers.clone(),
|
||||||
connection: device.connection(),
|
connection: device.connection(),
|
||||||
adapter: device.adapter(),
|
adapter: device.adapter(),
|
||||||
api_type,
|
api_type,
|
||||||
|
runnable_receiver,
|
||||||
};
|
};
|
||||||
|
|
||||||
let output_handler = if pref!(dom.webgl.dom_to_texture.enabled) {
|
let output_handler = if pref!(dom.webgl.dom_to_texture.enabled) {
|
||||||
|
@ -74,8 +81,10 @@ impl WebGLComm {
|
||||||
WebGLComm {
|
WebGLComm {
|
||||||
webgl_threads: WebGLThreads(sender),
|
webgl_threads: WebGLThreads(sender),
|
||||||
webxr_swap_chains,
|
webxr_swap_chains,
|
||||||
|
webxr_surface_providers,
|
||||||
image_handler: Box::new(external),
|
image_handler: Box::new(external),
|
||||||
output_handler: output_handler.map(|b| b as Box<_>),
|
output_handler: output_handler.map(|b| b as Box<_>),
|
||||||
|
webgl_executor: runnable_sender,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ use sparkle::gl::GLint;
|
||||||
use sparkle::gl::GLuint;
|
use sparkle::gl::GLuint;
|
||||||
use sparkle::gl::Gl;
|
use sparkle::gl::Gl;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
@ -70,9 +70,10 @@ use surfman::GLVersion;
|
||||||
use surfman::SurfaceAccess;
|
use surfman::SurfaceAccess;
|
||||||
use surfman::SurfaceInfo;
|
use surfman::SurfaceInfo;
|
||||||
use surfman::SurfaceType;
|
use surfman::SurfaceType;
|
||||||
use surfman_chains::SwapChains;
|
use surfman_chains::{SurfmanProvider, SwapChains};
|
||||||
use surfman_chains_api::SwapChainsAPI;
|
use surfman_chains_api::SwapChainsAPI;
|
||||||
use webrender_traits::{WebrenderExternalImageRegistry, WebrenderImageHandlerType};
|
use webrender_traits::{WebrenderExternalImageRegistry, WebrenderImageHandlerType};
|
||||||
|
use webxr_api::SessionId;
|
||||||
use webxr_api::SwapChainId as WebXRSwapChainId;
|
use webxr_api::SwapChainId as WebXRSwapChainId;
|
||||||
|
|
||||||
#[cfg(feature = "xr-profile")]
|
#[cfg(feature = "xr-profile")]
|
||||||
|
@ -138,25 +139,29 @@ pub(crate) struct WebGLThread {
|
||||||
/// We use it to get an unique ID for new WebGLContexts.
|
/// We use it to get an unique ID for new WebGLContexts.
|
||||||
external_images: Arc<Mutex<WebrenderExternalImageRegistry>>,
|
external_images: Arc<Mutex<WebrenderExternalImageRegistry>>,
|
||||||
/// The receiver that will be used for processing WebGL messages.
|
/// The receiver that will be used for processing WebGL messages.
|
||||||
receiver: WebGLReceiver<WebGLMsg>,
|
receiver: crossbeam_channel::Receiver<WebGLMsg>,
|
||||||
/// The receiver that should be used to send WebGL messages for processing.
|
/// The receiver that should be used to send WebGL messages for processing.
|
||||||
sender: WebGLSender<WebGLMsg>,
|
sender: WebGLSender<WebGLMsg>,
|
||||||
/// The swap chains used by webrender
|
/// The swap chains used by webrender
|
||||||
webrender_swap_chains: SwapChains<WebGLContextId>,
|
webrender_swap_chains: SwapChains<WebGLContextId>,
|
||||||
/// The swap chains used by webxr
|
/// The swap chains used by webxr
|
||||||
webxr_swap_chains: SwapChains<WebXRSwapChainId>,
|
webxr_swap_chains: SwapChains<WebXRSwapChainId>,
|
||||||
|
/// The set of all surface providers corresponding to WebXR sessions.
|
||||||
|
webxr_surface_providers: SurfaceProviders,
|
||||||
|
/// A channel to allow arbitrary threads to execute tasks that run in the WebGL thread.
|
||||||
|
runnable_receiver: crossbeam_channel::Receiver<WebGlRunnable>,
|
||||||
/// Whether this context is a GL or GLES context.
|
/// Whether this context is a GL or GLES context.
|
||||||
api_type: gl::GlType,
|
api_type: gl::GlType,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
pub type WebGlExecutor = crossbeam_channel::Sender<WebGlRunnable>;
|
||||||
enum EventLoop {
|
pub type WebGlRunnable = Box<dyn FnOnce() + Send>;
|
||||||
Blocking,
|
pub type SurfaceProviders = Arc<Mutex<HashMap<SessionId, SurfaceProvider>>>;
|
||||||
Nonblocking,
|
pub type SurfaceProvider = Box<dyn surfman_chains::SurfaceProvider + Send>;
|
||||||
}
|
|
||||||
|
|
||||||
/// The data required to initialize an instance of the WebGLThread type.
|
/// The data required to initialize an instance of the WebGLThread type.
|
||||||
pub(crate) struct WebGLThreadInit {
|
pub(crate) struct WebGLThreadInit {
|
||||||
|
pub webxr_surface_providers: SurfaceProviders,
|
||||||
pub webrender_api_sender: webrender_api::RenderApiSender,
|
pub webrender_api_sender: webrender_api::RenderApiSender,
|
||||||
pub webvr_compositor: Option<Box<dyn WebVRRenderHandler>>,
|
pub webvr_compositor: Option<Box<dyn WebVRRenderHandler>>,
|
||||||
pub external_images: Arc<Mutex<WebrenderExternalImageRegistry>>,
|
pub external_images: Arc<Mutex<WebrenderExternalImageRegistry>>,
|
||||||
|
@ -167,37 +172,7 @@ pub(crate) struct WebGLThreadInit {
|
||||||
pub connection: Connection,
|
pub connection: Connection,
|
||||||
pub adapter: Adapter,
|
pub adapter: Adapter,
|
||||||
pub api_type: gl::GlType,
|
pub api_type: gl::GlType,
|
||||||
}
|
pub runnable_receiver: crossbeam_channel::Receiver<WebGlRunnable>,
|
||||||
|
|
||||||
/// The extra data required to run an instance of WebGLThread when it is
|
|
||||||
/// not running in its own thread.
|
|
||||||
pub struct WebGLMainThread {
|
|
||||||
pub(crate) thread_data: RefCell<WebGLThread>,
|
|
||||||
shut_down: Cell<bool>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WebGLMainThread {
|
|
||||||
/// Synchronously process all outstanding WebGL messages.
|
|
||||||
pub fn process(&self) {
|
|
||||||
if self.shut_down.get() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Any context could be current when we start.
|
|
||||||
self.thread_data.borrow_mut().bound_context_id = None;
|
|
||||||
let result = self
|
|
||||||
.thread_data
|
|
||||||
.borrow_mut()
|
|
||||||
.process(EventLoop::Nonblocking);
|
|
||||||
if !result {
|
|
||||||
self.shut_down.set(true);
|
|
||||||
WEBGL_MAIN_THREAD.with(|thread_data| thread_data.borrow_mut().take());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
thread_local! {
|
|
||||||
static WEBGL_MAIN_THREAD: RefCell<Option<Rc<WebGLMainThread>>> = RefCell::new(None);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// A size at which it should be safe to create GL contexts
|
// A size at which it should be safe to create GL contexts
|
||||||
|
@ -214,9 +189,11 @@ impl WebGLThread {
|
||||||
receiver,
|
receiver,
|
||||||
webrender_swap_chains,
|
webrender_swap_chains,
|
||||||
webxr_swap_chains,
|
webxr_swap_chains,
|
||||||
|
webxr_surface_providers,
|
||||||
connection,
|
connection,
|
||||||
adapter,
|
adapter,
|
||||||
api_type,
|
api_type,
|
||||||
|
runnable_receiver,
|
||||||
}: WebGLThreadInit,
|
}: WebGLThreadInit,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
WebGLThread {
|
WebGLThread {
|
||||||
|
@ -229,9 +206,11 @@ impl WebGLThread {
|
||||||
dom_outputs: Default::default(),
|
dom_outputs: Default::default(),
|
||||||
external_images,
|
external_images,
|
||||||
sender,
|
sender,
|
||||||
receiver,
|
receiver: receiver.into_inner(),
|
||||||
webrender_swap_chains,
|
webrender_swap_chains,
|
||||||
webxr_swap_chains,
|
webxr_swap_chains,
|
||||||
|
webxr_surface_providers,
|
||||||
|
runnable_receiver,
|
||||||
api_type,
|
api_type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,23 +222,35 @@ impl WebGLThread {
|
||||||
.name("WebGL thread".to_owned())
|
.name("WebGL thread".to_owned())
|
||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
let mut data = WebGLThread::new(init);
|
let mut data = WebGLThread::new(init);
|
||||||
data.process(EventLoop::Blocking);
|
data.process();
|
||||||
})
|
})
|
||||||
.expect("Thread spawning failed");
|
.expect("Thread spawning failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process(&mut self, loop_type: EventLoop) -> bool {
|
fn process(&mut self) {
|
||||||
let webgl_chan = WebGLChan(self.sender.clone());
|
let webgl_chan = WebGLChan(self.sender.clone());
|
||||||
while let Ok(msg) = match loop_type {
|
loop {
|
||||||
EventLoop::Blocking => self.receiver.recv(),
|
crossbeam_channel::select! {
|
||||||
EventLoop::Nonblocking => self.receiver.try_recv(),
|
recv(self.receiver) -> msg => {
|
||||||
} {
|
match msg {
|
||||||
|
Ok(msg) => {
|
||||||
let exit = self.handle_msg(msg, &webgl_chan);
|
let exit = self.handle_msg(msg, &webgl_chan);
|
||||||
if exit {
|
if exit {
|
||||||
return false;
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => break,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
recv(self.runnable_receiver) -> msg => {
|
||||||
|
if let Ok(msg) = msg {
|
||||||
|
msg();
|
||||||
|
} else {
|
||||||
|
self.runnable_receiver = crossbeam_channel::never();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles a generic WebGLMsg message
|
/// Handles a generic WebGLMsg message
|
||||||
|
@ -331,8 +322,8 @@ impl WebGLThread {
|
||||||
WebGLMsg::WebVRCommand(ctx_id, command) => {
|
WebGLMsg::WebVRCommand(ctx_id, command) => {
|
||||||
self.handle_webvr_command(ctx_id, command);
|
self.handle_webvr_command(ctx_id, command);
|
||||||
},
|
},
|
||||||
WebGLMsg::CreateWebXRSwapChain(ctx_id, size, sender) => {
|
WebGLMsg::CreateWebXRSwapChain(ctx_id, size, sender, id) => {
|
||||||
let _ = sender.send(self.create_webxr_swap_chain(ctx_id, size));
|
let _ = sender.send(self.create_webxr_swap_chain(ctx_id, size, id));
|
||||||
},
|
},
|
||||||
WebGLMsg::SwapBuffers(swap_ids, sender, sent_time) => {
|
WebGLMsg::SwapBuffers(swap_ids, sender, sent_time) => {
|
||||||
self.handle_swap_buffers(swap_ids, sender, sent_time);
|
self.handle_swap_buffers(swap_ids, sender, sent_time);
|
||||||
|
@ -443,6 +434,7 @@ impl WebGLThread {
|
||||||
size: safe_size.to_i32(),
|
size: safe_size.to_i32(),
|
||||||
};
|
};
|
||||||
let surface_access = self.surface_access();
|
let surface_access = self.surface_access();
|
||||||
|
let surface_provider = Box::new(SurfmanProvider::new(surface_access));
|
||||||
|
|
||||||
let mut ctx = self
|
let mut ctx = self
|
||||||
.device
|
.device
|
||||||
|
@ -469,7 +461,7 @@ impl WebGLThread {
|
||||||
);
|
);
|
||||||
|
|
||||||
self.webrender_swap_chains
|
self.webrender_swap_chains
|
||||||
.create_attached_swap_chain(id, &mut self.device, &mut ctx, surface_access)
|
.create_attached_swap_chain(id, &mut self.device, &mut ctx, surface_provider)
|
||||||
.expect("Failed to create the swap chain");
|
.expect("Failed to create the swap chain");
|
||||||
|
|
||||||
let swap_chain = self
|
let swap_chain = self
|
||||||
|
@ -765,6 +757,7 @@ impl WebGLThread {
|
||||||
&mut self,
|
&mut self,
|
||||||
context_id: WebGLContextId,
|
context_id: WebGLContextId,
|
||||||
size: Size2D<i32>,
|
size: Size2D<i32>,
|
||||||
|
session_id: SessionId,
|
||||||
) -> Option<WebXRSwapChainId> {
|
) -> Option<WebXRSwapChainId> {
|
||||||
debug!("WebGLThread::create_webxr_swap_chain()");
|
debug!("WebGLThread::create_webxr_swap_chain()");
|
||||||
let id = WebXRSwapChainId::new();
|
let id = WebXRSwapChainId::new();
|
||||||
|
@ -775,8 +768,14 @@ impl WebGLThread {
|
||||||
&mut self.contexts,
|
&mut self.contexts,
|
||||||
&mut self.bound_context_id,
|
&mut self.bound_context_id,
|
||||||
)?;
|
)?;
|
||||||
|
let surface_provider = self
|
||||||
|
.webxr_surface_providers
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.remove(&session_id)
|
||||||
|
.unwrap_or_else(|| Box::new(SurfmanProvider::new(surface_access)));
|
||||||
self.webxr_swap_chains
|
self.webxr_swap_chains
|
||||||
.create_detached_swap_chain(id, size, &mut self.device, &mut data.ctx, surface_access)
|
.create_detached_swap_chain(id, size, &mut self.device, &mut data.ctx, surface_provider)
|
||||||
.ok()?;
|
.ok()?;
|
||||||
debug!("Created swap chain {:?}", id);
|
debug!("Created swap chain {:?}", id);
|
||||||
Some(id)
|
Some(id)
|
||||||
|
|
|
@ -14,6 +14,7 @@ use std::num::{NonZeroU32, NonZeroU64};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use webrender_api::{DocumentId, ImageKey, PipelineId};
|
use webrender_api::{DocumentId, ImageKey, PipelineId};
|
||||||
use webvr_traits::WebVRPoseInformation;
|
use webvr_traits::WebVRPoseInformation;
|
||||||
|
use webxr_api::SessionId;
|
||||||
use webxr_api::SwapChainId as WebXRSwapChainId;
|
use webxr_api::SwapChainId as WebXRSwapChainId;
|
||||||
|
|
||||||
/// Helper function that creates a WebGL channel (WebGLSender, WebGLReceiver) to be used in WebGLCommands.
|
/// Helper function that creates a WebGL channel (WebGLSender, WebGLReceiver) to be used in WebGLCommands.
|
||||||
|
@ -80,6 +81,7 @@ pub enum WebGLMsg {
|
||||||
WebGLContextId,
|
WebGLContextId,
|
||||||
Size2D<i32>,
|
Size2D<i32>,
|
||||||
WebGLSender<Option<WebXRSwapChainId>>,
|
WebGLSender<Option<WebXRSwapChainId>>,
|
||||||
|
SessionId,
|
||||||
),
|
),
|
||||||
/// Performs a buffer swap.
|
/// Performs a buffer swap.
|
||||||
///
|
///
|
||||||
|
@ -188,9 +190,14 @@ impl WebGLMsgSender {
|
||||||
&self,
|
&self,
|
||||||
size: Size2D<i32>,
|
size: Size2D<i32>,
|
||||||
sender: WebGLSender<Option<WebXRSwapChainId>>,
|
sender: WebGLSender<Option<WebXRSwapChainId>>,
|
||||||
|
id: SessionId,
|
||||||
) -> WebGLSendResult {
|
) -> WebGLSendResult {
|
||||||
self.sender
|
self.sender.send(WebGLMsg::CreateWebXRSwapChain(
|
||||||
.send(WebGLMsg::CreateWebXRSwapChain(self.ctx_id, size, sender))
|
self.ctx_id,
|
||||||
|
size,
|
||||||
|
sender,
|
||||||
|
id,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -9,6 +9,7 @@ mod mpsc;
|
||||||
|
|
||||||
use crate::webgl::WebGLMsg;
|
use crate::webgl::WebGLMsg;
|
||||||
use ipc_channel::ipc::IpcSender;
|
use ipc_channel::ipc::IpcSender;
|
||||||
|
use ipc_channel::router::ROUTER;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use servo_config::opts;
|
use servo_config::opts;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -78,6 +79,18 @@ where
|
||||||
WebGLReceiver::Mpsc(ref receiver) => receiver.try_recv().map_err(|_| ()),
|
WebGLReceiver::Mpsc(ref receiver) => receiver.try_recv().map_err(|_| ()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn into_inner(self) -> crossbeam_channel::Receiver<T>
|
||||||
|
where
|
||||||
|
T: Send + 'static,
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
WebGLReceiver::Ipc(receiver) => {
|
||||||
|
ROUTER.route_ipc_receiver_to_new_crossbeam_receiver(receiver)
|
||||||
|
},
|
||||||
|
WebGLReceiver::Mpsc(receiver) => receiver.into_inner(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn webgl_channel<T>() -> Result<(WebGLSender<T>, WebGLReceiver<T>), ()>
|
pub fn webgl_channel<T>() -> Result<(WebGLSender<T>, WebGLReceiver<T>), ()>
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde::{Deserializer, Serializer};
|
use serde::{Deserializer, Serializer};
|
||||||
use std::sync::mpsc;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
macro_rules! unreachable_serializable {
|
macro_rules! unreachable_serializable {
|
||||||
|
@ -26,8 +25,8 @@ macro_rules! unreachable_serializable {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WebGLSender<T>(mpsc::Sender<T>);
|
pub struct WebGLSender<T>(crossbeam_channel::Sender<T>);
|
||||||
pub struct WebGLReceiver<T>(mpsc::Receiver<T>);
|
pub struct WebGLReceiver<T>(crossbeam_channel::Receiver<T>);
|
||||||
|
|
||||||
impl<T> Clone for WebGLSender<T> {
|
impl<T> Clone for WebGLSender<T> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
|
@ -37,24 +36,27 @@ impl<T> Clone for WebGLSender<T> {
|
||||||
|
|
||||||
impl<T> WebGLSender<T> {
|
impl<T> WebGLSender<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn send(&self, data: T) -> Result<(), mpsc::SendError<T>> {
|
pub fn send(&self, data: T) -> Result<(), crossbeam_channel::SendError<T>> {
|
||||||
self.0.send(data)
|
self.0.send(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> WebGLReceiver<T> {
|
impl<T> WebGLReceiver<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn recv(&self) -> Result<T, mpsc::RecvError> {
|
pub fn recv(&self) -> Result<T, crossbeam_channel::RecvError> {
|
||||||
self.0.recv()
|
self.0.recv()
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn try_recv(&self) -> Result<T, mpsc::TryRecvError> {
|
pub fn try_recv(&self) -> Result<T, crossbeam_channel::TryRecvError> {
|
||||||
self.0.try_recv()
|
self.0.try_recv()
|
||||||
}
|
}
|
||||||
|
pub fn into_inner(self) -> crossbeam_channel::Receiver<T> {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn webgl_channel<T>() -> Result<(WebGLSender<T>, WebGLReceiver<T>), ()> {
|
pub fn webgl_channel<T>() -> Result<(WebGLSender<T>, WebGLReceiver<T>), ()> {
|
||||||
let (sender, receiver) = mpsc::channel();
|
let (sender, receiver) = crossbeam_channel::unbounded();
|
||||||
Ok((WebGLSender(sender), WebGLReceiver(receiver)))
|
Ok((WebGLSender(sender), WebGLReceiver(receiver)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ default = []
|
||||||
gl = ["gleam", "pixels"]
|
gl = ["gleam", "pixels"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
canvas = { path = "../canvas" }
|
||||||
crossbeam-channel = "0.4"
|
crossbeam-channel = "0.4"
|
||||||
embedder_traits = {path = "../embedder_traits"}
|
embedder_traits = {path = "../embedder_traits"}
|
||||||
euclid = "0.20"
|
euclid = "0.20"
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
//! Abstract windowing methods. The concrete implementations of these can be found in `platform/`.
|
//! Abstract windowing methods. The concrete implementations of these can be found in `platform/`.
|
||||||
|
|
||||||
|
use canvas::{SurfaceProviders, WebGlExecutor};
|
||||||
use embedder_traits::EventLoopWaker;
|
use embedder_traits::EventLoopWaker;
|
||||||
use euclid::Scale;
|
use euclid::Scale;
|
||||||
#[cfg(feature = "gl")]
|
#[cfg(feature = "gl")]
|
||||||
|
@ -184,7 +185,13 @@ pub trait EmbedderMethods {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register services with a WebXR Registry.
|
/// Register services with a WebXR Registry.
|
||||||
fn register_webxr(&mut self, _: &mut webxr::MainThreadRegistry) {}
|
fn register_webxr(
|
||||||
|
&mut self,
|
||||||
|
_: &mut webxr::MainThreadRegistry,
|
||||||
|
_: WebGlExecutor,
|
||||||
|
_: SurfaceProviders,
|
||||||
|
) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
|
|
@ -142,9 +142,11 @@ impl WebGLFramebuffer {
|
||||||
size: Size2D<i32, Viewport>,
|
size: Size2D<i32, Viewport>,
|
||||||
) -> Option<(WebXRSwapChainId, DomRoot<Self>)> {
|
) -> Option<(WebXRSwapChainId, DomRoot<Self>)> {
|
||||||
let (sender, receiver) = webgl_channel().unwrap();
|
let (sender, receiver) = webgl_channel().unwrap();
|
||||||
let _ = context
|
let _ = context.webgl_sender().send_create_webxr_swap_chain(
|
||||||
.webgl_sender()
|
size.to_untyped(),
|
||||||
.send_create_webxr_swap_chain(size.to_untyped(), sender);
|
sender,
|
||||||
|
session.session_id(),
|
||||||
|
);
|
||||||
let swap_chain_id = receiver.recv().unwrap()?;
|
let swap_chain_id = receiver.recv().unwrap()?;
|
||||||
let framebuffer_id =
|
let framebuffer_id =
|
||||||
WebGLFramebufferId::Opaque(WebGLOpaqueFramebufferId::WebXR(swap_chain_id));
|
WebGLFramebufferId::Opaque(WebGLOpaqueFramebufferId::WebXR(swap_chain_id));
|
||||||
|
|
|
@ -81,6 +81,7 @@ use std::cell::Cell;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::ptr::{self, NonNull};
|
use std::ptr::{self, NonNull};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use webxr_api::SessionId;
|
||||||
use webxr_api::SwapChainId as WebXRSwapChainId;
|
use webxr_api::SwapChainId as WebXRSwapChainId;
|
||||||
|
|
||||||
// From the GLES 2.0.25 spec, page 85:
|
// From the GLES 2.0.25 spec, page 85:
|
||||||
|
@ -4576,8 +4577,9 @@ impl WebGLMessageSender {
|
||||||
&self,
|
&self,
|
||||||
size: Size2D<i32>,
|
size: Size2D<i32>,
|
||||||
sender: WebGLSender<Option<WebXRSwapChainId>>,
|
sender: WebGLSender<Option<WebXRSwapChainId>>,
|
||||||
|
id: SessionId,
|
||||||
) -> WebGLSendResult {
|
) -> WebGLSendResult {
|
||||||
self.wake_after_send(|| self.sender.send_create_webxr_swap_chain(size, sender))
|
self.wake_after_send(|| self.sender.send_create_webxr_swap_chain(size, sender, id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_resize(
|
pub fn send_resize(
|
||||||
|
|
|
@ -51,7 +51,7 @@ use std::mem;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use webxr_api::{
|
use webxr_api::{
|
||||||
self, util, Display, EnvironmentBlendMode, Event as XREvent, Frame, SelectEvent, SelectKind,
|
self, util, Display, EnvironmentBlendMode, Event as XREvent, Frame, SelectEvent, SelectKind,
|
||||||
Session, View, Viewer, Visibility,
|
Session, SessionId, View, Viewer, Visibility,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
@ -462,6 +462,10 @@ impl XRSession {
|
||||||
viewport: Rect::from_size(size.to_i32()),
|
viewport: Rect::from_size(size.to_i32()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn session_id(&self) -> SessionId {
|
||||||
|
self.session.borrow().id()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XRSessionMethods for XRSession {
|
impl XRSessionMethods for XRSession {
|
||||||
|
|
|
@ -65,7 +65,7 @@ fn webdriver(_port: u16, _constellation: Sender<ConstellationMsg>) {}
|
||||||
|
|
||||||
use bluetooth::BluetoothThreadFactory;
|
use bluetooth::BluetoothThreadFactory;
|
||||||
use bluetooth_traits::BluetoothRequest;
|
use bluetooth_traits::BluetoothRequest;
|
||||||
use canvas::WebGLComm;
|
use canvas::{SurfaceProviders, WebGLComm, WebGlExecutor};
|
||||||
use canvas_traits::webgl::WebGLThreads;
|
use canvas_traits::webgl::WebGLThreads;
|
||||||
use compositing::compositor_thread::{
|
use compositing::compositor_thread::{
|
||||||
CompositorProxy, CompositorReceiver, InitialCompositorState, Msg,
|
CompositorProxy, CompositorReceiver, InitialCompositorState, Msg,
|
||||||
|
@ -432,14 +432,6 @@ where
|
||||||
panic!("We don't currently support running both WebVR and WebXR");
|
panic!("We don't currently support running both WebVR and WebXR");
|
||||||
}
|
}
|
||||||
|
|
||||||
// For the moment, we enable use both the webxr crate and the rust-webvr crate,
|
|
||||||
// but we are migrating over to just using webxr.
|
|
||||||
let mut webxr_main_thread = webxr::MainThreadRegistry::new(event_loop_waker)
|
|
||||||
.expect("Failed to create WebXR device registry");
|
|
||||||
if pref!(dom.webxr.enabled) {
|
|
||||||
embedder.register_webxr(&mut webxr_main_thread);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut webvr_heartbeats = Vec::new();
|
let mut webvr_heartbeats = Vec::new();
|
||||||
let webvr_services = if pref!(dom.webvr.enabled) {
|
let webvr_services = if pref!(dom.webvr.enabled) {
|
||||||
let mut services = VRServiceManager::new();
|
let mut services = VRServiceManager::new();
|
||||||
|
@ -468,7 +460,12 @@ where
|
||||||
let (external_image_handlers, external_images) = WebrenderExternalImageHandlers::new();
|
let (external_image_handlers, external_images) = WebrenderExternalImageHandlers::new();
|
||||||
let mut external_image_handlers = Box::new(external_image_handlers);
|
let mut external_image_handlers = Box::new(external_image_handlers);
|
||||||
|
|
||||||
let webgl_threads = create_webgl_threads(
|
// For the moment, we enable use both the webxr crate and the rust-webvr crate,
|
||||||
|
// but we are migrating over to just using webxr.
|
||||||
|
let mut webxr_main_thread = webxr::MainThreadRegistry::new(event_loop_waker)
|
||||||
|
.expect("Failed to create WebXR device registry");
|
||||||
|
|
||||||
|
let (webgl_threads, webgl_extras) = create_webgl_threads(
|
||||||
&*window,
|
&*window,
|
||||||
&mut webrender,
|
&mut webrender,
|
||||||
webrender_api_sender.clone(),
|
webrender_api_sender.clone(),
|
||||||
|
@ -478,6 +475,16 @@ where
|
||||||
external_images.clone(),
|
external_images.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if pref!(dom.webxr.enabled) {
|
||||||
|
if let Some((webxr_surface_providers, webgl_executor)) = webgl_extras {
|
||||||
|
embedder.register_webxr(
|
||||||
|
&mut webxr_main_thread,
|
||||||
|
webgl_executor,
|
||||||
|
webxr_surface_providers,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let glplayer_threads = match window.get_gl_context() {
|
let glplayer_threads = match window.get_gl_context() {
|
||||||
GlContext::Unknown => None,
|
GlContext::Unknown => None,
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -1060,7 +1067,10 @@ fn create_webgl_threads<W>(
|
||||||
webxr_main_thread: &mut webxr::MainThreadRegistry,
|
webxr_main_thread: &mut webxr::MainThreadRegistry,
|
||||||
external_image_handlers: &mut WebrenderExternalImageHandlers,
|
external_image_handlers: &mut WebrenderExternalImageHandlers,
|
||||||
external_images: Arc<Mutex<WebrenderExternalImageRegistry>>,
|
external_images: Arc<Mutex<WebrenderExternalImageRegistry>>,
|
||||||
) -> Option<WebGLThreads>
|
) -> (
|
||||||
|
Option<WebGLThreads>,
|
||||||
|
Option<(SurfaceProviders, WebGlExecutor)>,
|
||||||
|
)
|
||||||
where
|
where
|
||||||
W: WindowMethods + 'static + ?Sized,
|
W: WindowMethods + 'static + ?Sized,
|
||||||
{
|
{
|
||||||
|
@ -1074,7 +1084,7 @@ where
|
||||||
Ok(a) => a,
|
Ok(a) => a,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!("Failed to create software graphics context: {:?}", e);
|
warn!("Failed to create software graphics context: {:?}", e);
|
||||||
return None;
|
return (None, None);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
(Device::Software(device), Context::Software(context))
|
(Device::Software(device), Context::Software(context))
|
||||||
|
@ -1083,7 +1093,7 @@ where
|
||||||
Ok(a) => a,
|
Ok(a) => a,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!("Failed to create hardware graphics context: {:?}", e);
|
warn!("Failed to create hardware graphics context: {:?}", e);
|
||||||
return None;
|
return (None, None);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
(Device::Hardware(device), Context::Hardware(context))
|
(Device::Hardware(device), Context::Hardware(context))
|
||||||
|
@ -1094,7 +1104,7 @@ where
|
||||||
Ok(a) => a,
|
Ok(a) => a,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!("Failed to create graphics context: {:?}", e);
|
warn!("Failed to create graphics context: {:?}", e);
|
||||||
return None;
|
return (None, None);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1106,8 +1116,10 @@ where
|
||||||
let WebGLComm {
|
let WebGLComm {
|
||||||
webgl_threads,
|
webgl_threads,
|
||||||
webxr_swap_chains,
|
webxr_swap_chains,
|
||||||
|
webxr_surface_providers,
|
||||||
image_handler,
|
image_handler,
|
||||||
output_handler,
|
output_handler,
|
||||||
|
webgl_executor,
|
||||||
} = WebGLComm::new(
|
} = WebGLComm::new(
|
||||||
device,
|
device,
|
||||||
context,
|
context,
|
||||||
|
@ -1129,5 +1141,8 @@ where
|
||||||
webrender.set_output_image_handler(output_handler);
|
webrender.set_output_image_handler(output_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(webgl_threads)
|
(
|
||||||
|
Some(webgl_threads),
|
||||||
|
Some((webxr_surface_providers, webgl_executor)),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ use glutin;
|
||||||
use glutin::dpi::LogicalSize;
|
use glutin::dpi::LogicalSize;
|
||||||
use glutin::EventsLoopClosed;
|
use glutin::EventsLoopClosed;
|
||||||
use rust_webvr::GlWindowVRService;
|
use rust_webvr::GlWindowVRService;
|
||||||
|
use servo::canvas::{SurfaceProviders, WebGlExecutor};
|
||||||
use servo::compositing::windowing::EmbedderMethods;
|
use servo::compositing::windowing::EmbedderMethods;
|
||||||
use servo::embedder_traits::EventLoopWaker;
|
use servo::embedder_traits::EventLoopWaker;
|
||||||
use servo::servo_config::{opts, pref};
|
use servo::servo_config::{opts, pref};
|
||||||
|
@ -89,7 +90,12 @@ impl EmbedderMethods for EmbedderCallbacks {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_webxr(&mut self, xr: &mut webxr::MainThreadRegistry) {
|
fn register_webxr(
|
||||||
|
&mut self,
|
||||||
|
xr: &mut webxr::MainThreadRegistry,
|
||||||
|
_executor: WebGlExecutor,
|
||||||
|
_surface_provider_registration: SurfaceProviders
|
||||||
|
) {
|
||||||
if pref!(dom.webxr.test) {
|
if pref!(dom.webxr.test) {
|
||||||
xr.register_mock(webxr::headless::HeadlessMockDiscovery::new());
|
xr.register_mock(webxr::headless::HeadlessMockDiscovery::new());
|
||||||
} else if !opts::get().headless && pref!(dom.webxr.glwindow) {
|
} else if !opts::get().headless && pref!(dom.webxr.glwindow) {
|
||||||
|
|
|
@ -13,6 +13,7 @@ pub use servo::embedder_traits::{
|
||||||
pub use servo::script_traits::{MediaSessionActionType, MouseButton};
|
pub use servo::script_traits::{MediaSessionActionType, MouseButton};
|
||||||
|
|
||||||
use getopts::Options;
|
use getopts::Options;
|
||||||
|
use servo::canvas::{SurfaceProviders, WebGlExecutor};
|
||||||
use servo::compositing::windowing::{
|
use servo::compositing::windowing::{
|
||||||
AnimationState, EmbedderCoordinates, EmbedderMethods, MouseWindowEvent, WindowEvent,
|
AnimationState, EmbedderCoordinates, EmbedderMethods, MouseWindowEvent, WindowEvent,
|
||||||
WindowMethods,
|
WindowMethods,
|
||||||
|
@ -723,19 +724,52 @@ impl EmbedderMethods for ServoEmbedderCallbacks {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "uwp")]
|
#[cfg(feature = "uwp")]
|
||||||
fn register_webxr(&mut self, registry: &mut webxr::MainThreadRegistry) {
|
fn register_webxr(
|
||||||
|
&mut self,
|
||||||
|
registry: &mut webxr::MainThreadRegistry,
|
||||||
|
executor: WebGlExecutor,
|
||||||
|
surface_providers: SurfaceProviders,
|
||||||
|
) {
|
||||||
debug!("EmbedderMethods::register_xr");
|
debug!("EmbedderMethods::register_xr");
|
||||||
assert!(
|
assert!(
|
||||||
self.xr_discovery.is_none(),
|
self.xr_discovery.is_none(),
|
||||||
"UWP builds should not be initialized with a WebXR Discovery object"
|
"UWP builds should not be initialized with a WebXR Discovery object"
|
||||||
);
|
);
|
||||||
let gl = self.gl.clone();
|
|
||||||
let discovery = webxr::openxr::OpenXrDiscovery::new(gl);
|
struct ProviderRegistration(SurfaceProviders);
|
||||||
|
impl webxr::openxr::SurfaceProviderRegistration for ProviderRegistration {
|
||||||
|
fn register(&self, id: webxr_api::SessionId, provider: servo::canvas::SurfaceProvider) {
|
||||||
|
self.0.lock().unwrap().insert(id, provider);
|
||||||
|
}
|
||||||
|
fn clone(&self) -> Box<dyn webxr::openxr::SurfaceProviderRegistration> {
|
||||||
|
Box::new(ProviderRegistration(self.0.clone()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GlThread(WebGlExecutor);
|
||||||
|
impl webxr::openxr::GlThread for GlThread {
|
||||||
|
fn execute(&self, runnable: Box<dyn FnOnce() + Send>) {
|
||||||
|
let _ = self.0.send(runnable);
|
||||||
|
}
|
||||||
|
fn clone(&self) -> Box<dyn webxr::openxr::GlThread> {
|
||||||
|
Box::new(GlThread(self.0.clone()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let discovery = webxr::openxr::OpenXrDiscovery::new(
|
||||||
|
Box::new(GlThread(executor)),
|
||||||
|
Box::new(ProviderRegistration(surface_providers)),
|
||||||
|
);
|
||||||
registry.register(discovery);
|
registry.register(discovery);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "uwp"))]
|
#[cfg(not(feature = "uwp"))]
|
||||||
fn register_webxr(&mut self, registry: &mut webxr::MainThreadRegistry) {
|
fn register_webxr(
|
||||||
|
&mut self,
|
||||||
|
registry: &mut webxr::MainThreadRegistry,
|
||||||
|
_executor: WebGlExecutor,
|
||||||
|
_surface_provider_registration: SurfaceProviders,
|
||||||
|
) {
|
||||||
debug!("EmbedderMethods::register_xr");
|
debug!("EmbedderMethods::register_xr");
|
||||||
if let Some(discovery) = self.xr_discovery.take() {
|
if let Some(discovery) = self.xr_discovery.take() {
|
||||||
registry.register(discovery);
|
registry.register(discovery);
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
[incompatible-texture-type-for-sampler.html]
|
[incompatible-texture-type-for-sampler.html]
|
||||||
expected: CRASH
|
expected: TIMEOUT
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue