aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock36
-rw-r--r--components/canvas/Cargo.toml2
-rw-r--r--components/canvas/lib.rs3
-rw-r--r--components/canvas/webgl_mode/inprocess.rs11
-rw-r--r--components/canvas/webgl_thread.rs107
-rw-r--r--components/canvas_traits/webgl.rs11
-rw-r--r--components/canvas_traits/webgl_channel/mod.rs13
-rw-r--r--components/canvas_traits/webgl_channel/mpsc.rs16
-rw-r--r--components/compositing/Cargo.toml1
-rw-r--r--components/compositing/windowing.rs9
-rw-r--r--components/script/dom/webglframebuffer.rs8
-rw-r--r--components/script/dom/webglrenderingcontext.rs4
-rw-r--r--components/script/dom/xrsession.rs6
-rw-r--r--components/servo/lib.rs45
-rw-r--r--ports/glutin/embedder.rs8
-rw-r--r--ports/libsimpleservo/api/src/lib.rs42
-rw-r--r--tests/wpt/webgl/meta/conformance2/uniforms/incompatible-texture-type-for-sampler.html.ini2
17 files changed, 215 insertions, 109 deletions
diff --git a/Cargo.lock b/Cargo.lock
index a7ad0c22733..fd23f6edda5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -496,8 +496,8 @@ dependencies = [
"raqote",
"servo_config",
"sparkle",
- "surfman 0.1.3",
- "surfman-chains 0.2.1",
+ "surfman 0.1.4",
+ "surfman-chains 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"surfman-chains-api",
"time",
"webrender",
@@ -742,6 +742,7 @@ dependencies = [
name = "compositing"
version = "0.0.1"
dependencies = [
+ "canvas",
"crossbeam-channel",
"embedder_traits",
"euclid",
@@ -3184,7 +3185,7 @@ dependencies = [
"sparkle",
"style",
"style_traits",
- "surfman 0.1.3",
+ "surfman 0.1.4",
"webdriver_server",
"webgpu",
"webrender",
@@ -5046,7 +5047,7 @@ dependencies = [
"servo-media",
"sparkle",
"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",
]
@@ -5697,9 +5698,9 @@ dependencies = [
[[package]]
name = "surfman"
-version = "0.1.3"
+version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10248da202c1c8d8798783bbc4ba08e81ff225c6e2a394d64748d2a62acb198c"
+checksum = "43bf043642ad98aaa51956091c4f829a400bad5f023b5f0095ecda61f925c63d"
dependencies = [
"bitflags",
"cgl 0.3.2",
@@ -5726,7 +5727,7 @@ dependencies = [
[[package]]
name = "surfman"
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 = [
"bitflags",
"cgl 0.3.2",
@@ -5752,28 +5753,28 @@ dependencies = [
[[package]]
name = "surfman-chains"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2c1b5976b229a807a9e79b3b5248da577948b9882c77f2afce27cf562f80e22"
+version = "0.3.0"
+source = "git+https://github.com/asajeffrey/surfman-chains?branch=multi#80a71b1a2df71ae70c3c194d0af40b8ebf72968a"
dependencies = [
"euclid",
"fnv",
"log",
"sparkle",
- "surfman 0.1.3",
+ "surfman 0.2.0",
"surfman-chains-api",
]
[[package]]
name = "surfman-chains"
version = "0.3.0"
-source = "git+https://github.com/asajeffrey/surfman-chains?branch=multi#80a71b1a2df71ae70c3c194d0af40b8ebf72968a"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2a679f5be9644bbf93662f3b1a704cc6b81c147d4b7d6d5c8d8b6f453176f01"
dependencies = [
"euclid",
"fnv",
"log",
"sparkle",
- "surfman 0.2.0",
+ "surfman 0.1.4",
"surfman-chains-api",
]
@@ -6649,9 +6650,10 @@ dependencies = [
[[package]]
name = "webxr"
version = "0.0.1"
-source = "git+https://github.com/servo/webxr#a1afba096c9797c3663727de58f54eae898f3050"
+source = "git+https://github.com/servo/webxr#3ac3e83f37ff64c74c847a610a8cefba9b907a9c"
dependencies = [
"bindgen",
+ "crossbeam-channel",
"euclid",
"gl_generator 0.13.1",
"gleam 0.9.2",
@@ -6659,8 +6661,8 @@ dependencies = [
"log",
"openxr",
"serde",
- "surfman 0.1.3",
- "surfman-chains 0.2.1",
+ "surfman 0.1.4",
+ "surfman-chains 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"time",
"webxr-api",
"winapi",
@@ -6670,7 +6672,7 @@ dependencies = [
[[package]]
name = "webxr-api"
version = "0.0.1"
-source = "git+https://github.com/servo/webxr#a1afba096c9797c3663727de58f54eae898f3050"
+source = "git+https://github.com/servo/webxr#3ac3e83f37ff64c74c847a610a8cefba9b907a9c"
dependencies = [
"euclid",
"ipc-channel",
diff --git a/components/canvas/Cargo.toml b/components/canvas/Cargo.toml
index ffb12a7a4ce..86cd3c4e440 100644
--- a/components/canvas/Cargo.toml
+++ b/components/canvas/Cargo.toml
@@ -42,5 +42,5 @@ webrender_traits = {path = "../webrender_traits"}
webxr-api = {git = "https://github.com/servo/webxr", features = ["ipc"]}
# NOTE: the sm-angle feature only enables angle on windows, not other platforms!
surfman = { version = "0.1", features = ["sm-angle", "sm-osmesa"] }
-surfman-chains = "0.2"
+surfman-chains = "0.3"
surfman-chains-api = "0.2"
diff --git a/components/canvas/lib.rs b/components/canvas/lib.rs
index 1e5872420bc..074a4a00bcb 100644
--- a/components/canvas/lib.rs
+++ b/components/canvas/lib.rs
@@ -12,6 +12,9 @@ extern crate log;
mod raqote_backend;
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_paint_thread;
diff --git a/components/canvas/webgl_mode/inprocess.rs b/components/canvas/webgl_mode/inprocess.rs
index d84b27684d5..b46b1608101 100644
--- a/components/canvas/webgl_mode/inprocess.rs
+++ b/components/canvas/webgl_mode/inprocess.rs
@@ -2,7 +2,7 @@
* 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/. */
-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::{WebGLContextId, WebGLMsg, WebGLThreads};
use euclid::default::Size2D;
@@ -11,6 +11,7 @@ use gleam;
use servo_config::pref;
use sparkle::gl;
use sparkle::gl::GlType;
+use std::collections::HashMap;
use std::default::Default;
use std::rc::Rc;
use std::sync::{Arc, Mutex};
@@ -27,8 +28,10 @@ use webxr_api::SwapChainId as WebXRSwapChainId;
pub struct WebGLComm {
pub webgl_threads: WebGLThreads,
pub webxr_swap_chains: SwapChains<WebXRSwapChainId>,
+ pub webxr_surface_providers: SurfaceProviders,
pub image_handler: Box<dyn WebrenderExternalImageApi>,
pub output_handler: Option<Box<dyn webrender_api::OutputImageHandler>>,
+ pub webgl_executor: WebGlExecutor,
}
impl WebGLComm {
@@ -46,6 +49,8 @@ impl WebGLComm {
let (sender, receiver) = webgl_channel::<WebGLMsg>().unwrap();
let webrender_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.
let init = WebGLThreadInit {
@@ -56,9 +61,11 @@ impl WebGLComm {
receiver,
webrender_swap_chains: webrender_swap_chains.clone(),
webxr_swap_chains: webxr_swap_chains.clone(),
+ webxr_surface_providers: webxr_surface_providers.clone(),
connection: device.connection(),
adapter: device.adapter(),
api_type,
+ runnable_receiver,
};
let output_handler = if pref!(dom.webgl.dom_to_texture.enabled) {
@@ -74,8 +81,10 @@ impl WebGLComm {
WebGLComm {
webgl_threads: WebGLThreads(sender),
webxr_swap_chains,
+ webxr_surface_providers,
image_handler: Box::new(external),
output_handler: output_handler.map(|b| b as Box<_>),
+ webgl_executor: runnable_sender,
}
}
}
diff --git a/components/canvas/webgl_thread.rs b/components/canvas/webgl_thread.rs
index 1658ebf94a5..f72e2c79bc1 100644
--- a/components/canvas/webgl_thread.rs
+++ b/components/canvas/webgl_thread.rs
@@ -54,7 +54,7 @@ use sparkle::gl::GLint;
use sparkle::gl::GLuint;
use sparkle::gl::Gl;
use std::borrow::Cow;
-use std::cell::{Cell, RefCell};
+use std::collections::HashMap;
use std::rc::Rc;
use std::slice;
use std::sync::{Arc, Mutex};
@@ -70,9 +70,10 @@ use surfman::GLVersion;
use surfman::SurfaceAccess;
use surfman::SurfaceInfo;
use surfman::SurfaceType;
-use surfman_chains::SwapChains;
+use surfman_chains::{SurfmanProvider, SwapChains};
use surfman_chains_api::SwapChainsAPI;
use webrender_traits::{WebrenderExternalImageRegistry, WebrenderImageHandlerType};
+use webxr_api::SessionId;
use webxr_api::SwapChainId as WebXRSwapChainId;
#[cfg(feature = "xr-profile")]
@@ -138,25 +139,29 @@ pub(crate) struct WebGLThread {
/// We use it to get an unique ID for new WebGLContexts.
external_images: Arc<Mutex<WebrenderExternalImageRegistry>>,
/// 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.
sender: WebGLSender<WebGLMsg>,
/// The swap chains used by webrender
webrender_swap_chains: SwapChains<WebGLContextId>,
/// The swap chains used by webxr
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.
api_type: gl::GlType,
}
-#[derive(PartialEq)]
-enum EventLoop {
- Blocking,
- Nonblocking,
-}
+pub type WebGlExecutor = crossbeam_channel::Sender<WebGlRunnable>;
+pub type WebGlRunnable = Box<dyn FnOnce() + Send>;
+pub type SurfaceProviders = Arc<Mutex<HashMap<SessionId, SurfaceProvider>>>;
+pub type SurfaceProvider = Box<dyn surfman_chains::SurfaceProvider + Send>;
/// The data required to initialize an instance of the WebGLThread type.
pub(crate) struct WebGLThreadInit {
+ pub webxr_surface_providers: SurfaceProviders,
pub webrender_api_sender: webrender_api::RenderApiSender,
pub webvr_compositor: Option<Box<dyn WebVRRenderHandler>>,
pub external_images: Arc<Mutex<WebrenderExternalImageRegistry>>,
@@ -167,37 +172,7 @@ pub(crate) struct WebGLThreadInit {
pub connection: Connection,
pub adapter: Adapter,
pub api_type: gl::GlType,
-}
-
-/// 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);
+ pub runnable_receiver: crossbeam_channel::Receiver<WebGlRunnable>,
}
// A size at which it should be safe to create GL contexts
@@ -214,9 +189,11 @@ impl WebGLThread {
receiver,
webrender_swap_chains,
webxr_swap_chains,
+ webxr_surface_providers,
connection,
adapter,
api_type,
+ runnable_receiver,
}: WebGLThreadInit,
) -> Self {
WebGLThread {
@@ -229,9 +206,11 @@ impl WebGLThread {
dom_outputs: Default::default(),
external_images,
sender,
- receiver,
+ receiver: receiver.into_inner(),
webrender_swap_chains,
webxr_swap_chains,
+ webxr_surface_providers,
+ runnable_receiver,
api_type,
}
}
@@ -243,23 +222,35 @@ impl WebGLThread {
.name("WebGL thread".to_owned())
.spawn(move || {
let mut data = WebGLThread::new(init);
- data.process(EventLoop::Blocking);
+ data.process();
})
.expect("Thread spawning failed");
}
- fn process(&mut self, loop_type: EventLoop) -> bool {
+ fn process(&mut self) {
let webgl_chan = WebGLChan(self.sender.clone());
- while let Ok(msg) = match loop_type {
- EventLoop::Blocking => self.receiver.recv(),
- EventLoop::Nonblocking => self.receiver.try_recv(),
- } {
- let exit = self.handle_msg(msg, &webgl_chan);
- if exit {
- return false;
+ loop {
+ crossbeam_channel::select! {
+ recv(self.receiver) -> msg => {
+ match msg {
+ Ok(msg) => {
+ let exit = self.handle_msg(msg, &webgl_chan);
+ if exit {
+ 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
@@ -331,8 +322,8 @@ impl WebGLThread {
WebGLMsg::WebVRCommand(ctx_id, command) => {
self.handle_webvr_command(ctx_id, command);
},
- WebGLMsg::CreateWebXRSwapChain(ctx_id, size, sender) => {
- let _ = sender.send(self.create_webxr_swap_chain(ctx_id, size));
+ WebGLMsg::CreateWebXRSwapChain(ctx_id, size, sender, id) => {
+ let _ = sender.send(self.create_webxr_swap_chain(ctx_id, size, id));
},
WebGLMsg::SwapBuffers(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(),
};
let surface_access = self.surface_access();
+ let surface_provider = Box::new(SurfmanProvider::new(surface_access));
let mut ctx = self
.device
@@ -469,7 +461,7 @@ impl WebGLThread {
);
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");
let swap_chain = self
@@ -765,6 +757,7 @@ impl WebGLThread {
&mut self,
context_id: WebGLContextId,
size: Size2D<i32>,
+ session_id: SessionId,
) -> Option<WebXRSwapChainId> {
debug!("WebGLThread::create_webxr_swap_chain()");
let id = WebXRSwapChainId::new();
@@ -775,8 +768,14 @@ impl WebGLThread {
&mut self.contexts,
&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
- .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()?;
debug!("Created swap chain {:?}", id);
Some(id)
diff --git a/components/canvas_traits/webgl.rs b/components/canvas_traits/webgl.rs
index 22e47ad9bb4..ce109f4e034 100644
--- a/components/canvas_traits/webgl.rs
+++ b/components/canvas_traits/webgl.rs
@@ -14,6 +14,7 @@ use std::num::{NonZeroU32, NonZeroU64};
use std::ops::Deref;
use webrender_api::{DocumentId, ImageKey, PipelineId};
use webvr_traits::WebVRPoseInformation;
+use webxr_api::SessionId;
use webxr_api::SwapChainId as WebXRSwapChainId;
/// Helper function that creates a WebGL channel (WebGLSender, WebGLReceiver) to be used in WebGLCommands.
@@ -80,6 +81,7 @@ pub enum WebGLMsg {
WebGLContextId,
Size2D<i32>,
WebGLSender<Option<WebXRSwapChainId>>,
+ SessionId,
),
/// Performs a buffer swap.
///
@@ -188,9 +190,14 @@ impl WebGLMsgSender {
&self,
size: Size2D<i32>,
sender: WebGLSender<Option<WebXRSwapChainId>>,
+ id: SessionId,
) -> WebGLSendResult {
- self.sender
- .send(WebGLMsg::CreateWebXRSwapChain(self.ctx_id, size, sender))
+ self.sender.send(WebGLMsg::CreateWebXRSwapChain(
+ self.ctx_id,
+ size,
+ sender,
+ id,
+ ))
}
#[inline]
diff --git a/components/canvas_traits/webgl_channel/mod.rs b/components/canvas_traits/webgl_channel/mod.rs
index 45c76d54605..86a6cd23bf4 100644
--- a/components/canvas_traits/webgl_channel/mod.rs
+++ b/components/canvas_traits/webgl_channel/mod.rs
@@ -9,6 +9,7 @@ mod mpsc;
use crate::webgl::WebGLMsg;
use ipc_channel::ipc::IpcSender;
+use ipc_channel::router::ROUTER;
use serde::{Deserialize, Serialize};
use servo_config::opts;
use std::fmt;
@@ -78,6 +79,18 @@ where
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>), ()>
diff --git a/components/canvas_traits/webgl_channel/mpsc.rs b/components/canvas_traits/webgl_channel/mpsc.rs
index 0dd063967ea..40acb050861 100644
--- a/components/canvas_traits/webgl_channel/mpsc.rs
+++ b/components/canvas_traits/webgl_channel/mpsc.rs
@@ -4,7 +4,6 @@
use serde::{Deserialize, Serialize};
use serde::{Deserializer, Serializer};
-use std::sync::mpsc;
#[macro_use]
macro_rules! unreachable_serializable {
@@ -26,8 +25,8 @@ macro_rules! unreachable_serializable {
};
}
-pub struct WebGLSender<T>(mpsc::Sender<T>);
-pub struct WebGLReceiver<T>(mpsc::Receiver<T>);
+pub struct WebGLSender<T>(crossbeam_channel::Sender<T>);
+pub struct WebGLReceiver<T>(crossbeam_channel::Receiver<T>);
impl<T> Clone for WebGLSender<T> {
fn clone(&self) -> Self {
@@ -37,24 +36,27 @@ impl<T> Clone for WebGLSender<T> {
impl<T> WebGLSender<T> {
#[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)
}
}
impl<T> WebGLReceiver<T> {
#[inline]
- pub fn recv(&self) -> Result<T, mpsc::RecvError> {
+ pub fn recv(&self) -> Result<T, crossbeam_channel::RecvError> {
self.0.recv()
}
#[inline]
- pub fn try_recv(&self) -> Result<T, mpsc::TryRecvError> {
+ pub fn try_recv(&self) -> Result<T, crossbeam_channel::TryRecvError> {
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>), ()> {
- let (sender, receiver) = mpsc::channel();
+ let (sender, receiver) = crossbeam_channel::unbounded();
Ok((WebGLSender(sender), WebGLReceiver(receiver)))
}
diff --git a/components/compositing/Cargo.toml b/components/compositing/Cargo.toml
index e8ec781bcfd..589c45a9c73 100644
--- a/components/compositing/Cargo.toml
+++ b/components/compositing/Cargo.toml
@@ -16,6 +16,7 @@ default = []
gl = ["gleam", "pixels"]
[dependencies]
+canvas = { path = "../canvas" }
crossbeam-channel = "0.4"
embedder_traits = {path = "../embedder_traits"}
euclid = "0.20"
diff --git a/components/compositing/windowing.rs b/components/compositing/windowing.rs
index 4dfa27a9d02..a27473ca0f1 100644
--- a/components/compositing/windowing.rs
+++ b/components/compositing/windowing.rs
@@ -4,6 +4,7 @@
//! Abstract windowing methods. The concrete implementations of these can be found in `platform/`.
+use canvas::{SurfaceProviders, WebGlExecutor};
use embedder_traits::EventLoopWaker;
use euclid::Scale;
#[cfg(feature = "gl")]
@@ -184,7 +185,13 @@ pub trait EmbedderMethods {
}
/// 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)]
diff --git a/components/script/dom/webglframebuffer.rs b/components/script/dom/webglframebuffer.rs
index c285145d994..2d6fcf9122d 100644
--- a/components/script/dom/webglframebuffer.rs
+++ b/components/script/dom/webglframebuffer.rs
@@ -142,9 +142,11 @@ impl WebGLFramebuffer {
size: Size2D<i32, Viewport>,
) -> Option<(WebXRSwapChainId, DomRoot<Self>)> {
let (sender, receiver) = webgl_channel().unwrap();
- let _ = context
- .webgl_sender()
- .send_create_webxr_swap_chain(size.to_untyped(), sender);
+ let _ = context.webgl_sender().send_create_webxr_swap_chain(
+ size.to_untyped(),
+ sender,
+ session.session_id(),
+ );
let swap_chain_id = receiver.recv().unwrap()?;
let framebuffer_id =
WebGLFramebufferId::Opaque(WebGLOpaqueFramebufferId::WebXR(swap_chain_id));
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index ca5c08b25e3..65134a631e1 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -81,6 +81,7 @@ use std::cell::Cell;
use std::cmp;
use std::ptr::{self, NonNull};
use std::rc::Rc;
+use webxr_api::SessionId;
use webxr_api::SwapChainId as WebXRSwapChainId;
// From the GLES 2.0.25 spec, page 85:
@@ -4576,8 +4577,9 @@ impl WebGLMessageSender {
&self,
size: Size2D<i32>,
sender: WebGLSender<Option<WebXRSwapChainId>>,
+ id: SessionId,
) -> 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(
diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs
index ec51c910a17..ecb78615897 100644
--- a/components/script/dom/xrsession.rs
+++ b/components/script/dom/xrsession.rs
@@ -51,7 +51,7 @@ use std::mem;
use std::rc::Rc;
use webxr_api::{
self, util, Display, EnvironmentBlendMode, Event as XREvent, Frame, SelectEvent, SelectKind,
- Session, View, Viewer, Visibility,
+ Session, SessionId, View, Viewer, Visibility,
};
#[dom_struct]
@@ -462,6 +462,10 @@ impl XRSession {
viewport: Rect::from_size(size.to_i32()),
}
}
+
+ pub fn session_id(&self) -> SessionId {
+ self.session.borrow().id()
+ }
}
impl XRSessionMethods for XRSession {
diff --git a/components/servo/lib.rs b/components/servo/lib.rs
index bb408eaa2b5..a71a1e708ba 100644
--- a/components/servo/lib.rs
+++ b/components/servo/lib.rs
@@ -65,7 +65,7 @@ fn webdriver(_port: u16, _constellation: Sender<ConstellationMsg>) {}
use bluetooth::BluetoothThreadFactory;
use bluetooth_traits::BluetoothRequest;
-use canvas::WebGLComm;
+use canvas::{SurfaceProviders, WebGLComm, WebGlExecutor};
use canvas_traits::webgl::WebGLThreads;
use compositing::compositor_thread::{
CompositorProxy, CompositorReceiver, InitialCompositorState, Msg,
@@ -432,14 +432,6 @@ where
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 webvr_services = if pref!(dom.webvr.enabled) {
let mut services = VRServiceManager::new();
@@ -468,7 +460,12 @@ where
let (external_image_handlers, external_images) = WebrenderExternalImageHandlers::new();
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,
&mut webrender,
webrender_api_sender.clone(),
@@ -478,6 +475,16 @@ where
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() {
GlContext::Unknown => None,
_ => {
@@ -1060,7 +1067,10 @@ fn create_webgl_threads<W>(
webxr_main_thread: &mut webxr::MainThreadRegistry,
external_image_handlers: &mut WebrenderExternalImageHandlers,
external_images: Arc<Mutex<WebrenderExternalImageRegistry>>,
-) -> Option<WebGLThreads>
+) -> (
+ Option<WebGLThreads>,
+ Option<(SurfaceProviders, WebGlExecutor)>,
+)
where
W: WindowMethods + 'static + ?Sized,
{
@@ -1074,7 +1084,7 @@ where
Ok(a) => a,
Err(e) => {
warn!("Failed to create software graphics context: {:?}", e);
- return None;
+ return (None, None);
},
};
(Device::Software(device), Context::Software(context))
@@ -1083,7 +1093,7 @@ where
Ok(a) => a,
Err(e) => {
warn!("Failed to create hardware graphics context: {:?}", e);
- return None;
+ return (None, None);
},
};
(Device::Hardware(device), Context::Hardware(context))
@@ -1094,7 +1104,7 @@ where
Ok(a) => a,
Err(e) => {
warn!("Failed to create graphics context: {:?}", e);
- return None;
+ return (None, None);
},
};
@@ -1106,8 +1116,10 @@ where
let WebGLComm {
webgl_threads,
webxr_swap_chains,
+ webxr_surface_providers,
image_handler,
output_handler,
+ webgl_executor,
} = WebGLComm::new(
device,
context,
@@ -1129,5 +1141,8 @@ where
webrender.set_output_image_handler(output_handler);
}
- Some(webgl_threads)
+ (
+ Some(webgl_threads),
+ Some((webxr_surface_providers, webgl_executor)),
+ )
}
diff --git a/ports/glutin/embedder.rs b/ports/glutin/embedder.rs
index 44c925af3e4..af65d4c34a1 100644
--- a/ports/glutin/embedder.rs
+++ b/ports/glutin/embedder.rs
@@ -12,6 +12,7 @@ use glutin;
use glutin::dpi::LogicalSize;
use glutin::EventsLoopClosed;
use rust_webvr::GlWindowVRService;
+use servo::canvas::{SurfaceProviders, WebGlExecutor};
use servo::compositing::windowing::EmbedderMethods;
use servo::embedder_traits::EventLoopWaker;
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) {
xr.register_mock(webxr::headless::HeadlessMockDiscovery::new());
} else if !opts::get().headless && pref!(dom.webxr.glwindow) {
diff --git a/ports/libsimpleservo/api/src/lib.rs b/ports/libsimpleservo/api/src/lib.rs
index fcbcf89cc6d..64eddcb40e2 100644
--- a/ports/libsimpleservo/api/src/lib.rs
+++ b/ports/libsimpleservo/api/src/lib.rs
@@ -13,6 +13,7 @@ pub use servo::embedder_traits::{
pub use servo::script_traits::{MediaSessionActionType, MouseButton};
use getopts::Options;
+use servo::canvas::{SurfaceProviders, WebGlExecutor};
use servo::compositing::windowing::{
AnimationState, EmbedderCoordinates, EmbedderMethods, MouseWindowEvent, WindowEvent,
WindowMethods,
@@ -723,19 +724,52 @@ impl EmbedderMethods for ServoEmbedderCallbacks {
}
#[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");
assert!(
self.xr_discovery.is_none(),
"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);
}
#[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");
if let Some(discovery) = self.xr_discovery.take() {
registry.register(discovery);
diff --git a/tests/wpt/webgl/meta/conformance2/uniforms/incompatible-texture-type-for-sampler.html.ini b/tests/wpt/webgl/meta/conformance2/uniforms/incompatible-texture-type-for-sampler.html.ini
index 087ab66dcda..32055007d4e 100644
--- a/tests/wpt/webgl/meta/conformance2/uniforms/incompatible-texture-type-for-sampler.html.ini
+++ b/tests/wpt/webgl/meta/conformance2/uniforms/incompatible-texture-type-for-sampler.html.ini
@@ -1,2 +1,2 @@
[incompatible-texture-type-for-sampler.html]
- expected: CRASH
+ expected: TIMEOUT