Skip to content

Commit 1cbf512

Browse files
author
Alan Jeffrey
committed
Replace use of callbacks in webxr by channels
1 parent ad82d67 commit 1cbf512

File tree

10 files changed

+77
-156
lines changed

10 files changed

+77
-156
lines changed

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

components/canvas/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,4 @@ servo_config = {path = "../config"}
3636
webrender = {git = "https://github.com/servo/webrender"}
3737
webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}
3838
webrender_traits = {path = "../webrender_traits"}
39+
webxr-api = {git = "https://github.com/servo/webxr", features = ["ipc"]}

components/canvas/webgl_mode/inprocess.rs

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use servo_config::pref;
1515
use std::rc::Rc;
1616
use std::sync::{Arc, Mutex};
1717
use webrender_traits::{WebrenderExternalImageApi, WebrenderExternalImageRegistry};
18+
use webxr_api::WebGLExternalImageApi;
1819

1920
/// WebGL Threading API entry point that lives in the constellation.
2021
pub struct WebGLThreads(WebGLSender<WebGLMsg>);
@@ -29,6 +30,7 @@ impl WebGLThreads {
2930
external_images: Arc<Mutex<WebrenderExternalImageRegistry>>,
3031
) -> (
3132
WebGLThreads,
33+
Box<dyn webxr_api::WebGLExternalImageApi>,
3234
Box<dyn WebrenderExternalImageApi>,
3335
Option<Box<dyn webrender::OutputImageHandler>>,
3436
) {
@@ -50,6 +52,7 @@ impl WebGLThreads {
5052
let external = WebGLExternalImages::new(webrender_gl, channel.clone());
5153
(
5254
WebGLThreads(channel),
55+
external.sendable.clone_box(),
5356
Box::new(external),
5457
output_handler.map(|b| b as Box<_>),
5558
)
@@ -69,9 +72,8 @@ impl WebGLThreads {
6972
}
7073
}
7174

72-
/// Bridge between the webrender::ExternalImage callbacks and the WebGLThreads.
73-
struct WebGLExternalImages {
74-
webrender_gl: Rc<dyn gl::Gl>,
75+
/// Bridge between the webxr_api::ExternalImage callbacks and the WebGLThreads.
76+
struct SendableWebGLExternalImages {
7577
webgl_channel: WebGLSender<WebGLMsg>,
7678
// Used to avoid creating a new channel on each received WebRender request.
7779
lock_channel: (
@@ -80,39 +82,67 @@ struct WebGLExternalImages {
8082
),
8183
}
8284

83-
impl WebGLExternalImages {
84-
fn new(webrender_gl: Rc<dyn gl::Gl>, channel: WebGLSender<WebGLMsg>) -> Self {
85+
impl SendableWebGLExternalImages {
86+
fn new(channel: WebGLSender<WebGLMsg>) -> Self {
8587
Self {
86-
webrender_gl,
8788
webgl_channel: channel,
8889
lock_channel: webgl_channel().unwrap(),
8990
}
9091
}
9192
}
9293

93-
impl WebrenderExternalImageApi for WebGLExternalImages {
94-
fn lock(&mut self, id: u64) -> (u32, Size2D<i32>) {
94+
impl webxr_api::WebGLExternalImageApi for SendableWebGLExternalImages {
95+
fn lock(&self, id: usize) -> (u32, Size2D<i32>, gl::GLsync) {
9596
// WebGL Thread has it's own GL command queue that we need to synchronize with the WR GL command queue.
9697
// The WebGLMsg::Lock message inserts a fence in the WebGL command queue.
9798
self.webgl_channel
9899
.send(WebGLMsg::Lock(
99-
WebGLContextId(id as usize),
100+
WebGLContextId(id),
100101
self.lock_channel.0.clone(),
101102
))
102103
.unwrap();
103104
let (image_id, size, gl_sync) = self.lock_channel.1.recv().unwrap();
105+
(image_id, size, gl_sync as gl::GLsync)
106+
}
107+
108+
fn unlock(&self, id: usize) {
109+
self.webgl_channel
110+
.send(WebGLMsg::Unlock(WebGLContextId(id as usize)))
111+
.unwrap();
112+
}
113+
114+
fn clone_box(&self) -> Box<dyn webxr_api::WebGLExternalImageApi> {
115+
Box::new(Self::new(self.webgl_channel.clone()))
116+
}
117+
}
118+
119+
/// Bridge between the webrender::ExternalImage callbacks and the WebGLThreads.
120+
struct WebGLExternalImages {
121+
webrender_gl: Rc<dyn gl::Gl>,
122+
sendable: SendableWebGLExternalImages,
123+
}
124+
125+
impl WebGLExternalImages {
126+
fn new(webrender_gl: Rc<dyn gl::Gl>, channel: WebGLSender<WebGLMsg>) -> Self {
127+
Self {
128+
webrender_gl,
129+
sendable: SendableWebGLExternalImages::new(channel),
130+
}
131+
}
132+
}
133+
134+
impl WebrenderExternalImageApi for WebGLExternalImages {
135+
fn lock(&mut self, id: u64) -> (u32, Size2D<i32>) {
136+
let (image_id, size, gl_sync) = self.sendable.lock(id as usize);
104137
// The next glWaitSync call is run on the WR thread and it's used to synchronize the two
105138
// flows of OpenGL commands in order to avoid WR using a semi-ready WebGL texture.
106139
// glWaitSync doesn't block WR thread, it affects only internal OpenGL subsystem.
107-
self.webrender_gl
108-
.wait_sync(gl_sync as gl::GLsync, 0, gl::TIMEOUT_IGNORED);
140+
self.webrender_gl.wait_sync(gl_sync, 0, gl::TIMEOUT_IGNORED);
109141
(image_id, size)
110142
}
111143

112144
fn unlock(&mut self, id: u64) {
113-
self.webgl_channel
114-
.send(WebGLMsg::Unlock(WebGLContextId(id as usize)))
115-
.unwrap();
145+
self.sendable.unlock(id as usize);
116146
}
117147
}
118148

components/canvas/webgl_thread.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use euclid::default::Size2D;
99
use fnv::FnvHashMap;
1010
use gleam::gl;
1111
use half::f16;
12-
use ipc_channel::ipc::IpcSender;
1312
use offscreen_gl_context::{DrawBuffer, GLContext, NativeGLContextMethods};
1413
use pixels::{self, PixelFormat};
1514
use std::borrow::Cow;
@@ -187,9 +186,6 @@ impl<VR: WebVRRenderHandler + 'static> WebGLThread<VR> {
187186
WebGLMsg::Lock(ctx_id, sender) => {
188187
self.handle_lock(ctx_id, sender);
189188
},
190-
WebGLMsg::LockIPC(ctx_id, sender) => {
191-
self.handle_lock_ipc(ctx_id, sender);
192-
},
193189
WebGLMsg::Unlock(ctx_id) => {
194190
self.handle_unlock(ctx_id);
195191
},
@@ -249,15 +245,6 @@ impl<VR: WebVRRenderHandler + 'static> WebGLThread<VR> {
249245
sender.send(self.handle_lock_inner(context_id)).unwrap();
250246
}
251247

252-
/// handle_lock, but unconditionally IPC (used by webxr)
253-
fn handle_lock_ipc(
254-
&mut self,
255-
context_id: WebGLContextId,
256-
sender: IpcSender<(u32, Size2D<i32>, usize)>,
257-
) {
258-
sender.send(self.handle_lock_inner(context_id)).unwrap();
259-
}
260-
261248
/// Shared code between handle_lock and handle_lock_ipc, does the actual syncing/flushing
262249
/// but the caller must send the response back
263250
fn handle_lock_inner(&mut self, context_id: WebGLContextId) -> (u32, Size2D<i32>, usize) {

components/canvas_traits/webgl.rs

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@
44

55
use euclid::default::{Rect, Size2D};
66
use gleam::gl;
7-
use gleam::gl::GLsync;
8-
use gleam::gl::GLuint;
97
use gleam::gl::Gl;
10-
use ipc_channel::ipc::{self, IpcBytesReceiver, IpcBytesSender, IpcSender, IpcSharedMemory};
8+
use ipc_channel::ipc::{IpcBytesReceiver, IpcBytesSender, IpcSharedMemory};
119
use pixels::PixelFormat;
1210
use std::borrow::Cow;
1311
use std::fmt;
@@ -61,8 +59,6 @@ pub enum WebGLMsg {
6159
/// The WR client should not change the shared texture content until the Unlock call.
6260
/// Currently OpenGL Sync Objects are used to implement the synchronization mechanism.
6361
Lock(WebGLContextId, WebGLSender<(u32, Size2D<i32>, usize)>),
64-
/// Lock(), but unconditionally IPC (used by webxr)
65-
LockIPC(WebGLContextId, IpcSender<(u32, Size2D<i32>, usize)>),
6662
/// Unlocks a specific WebGLContext. Unlock messages are used for a correct synchronization
6763
/// with WebRender external image API.
6864
/// The WR unlocks a context when it finished reading the shared texture contents.
@@ -185,39 +181,6 @@ impl WebGLMsgSender {
185181
pub fn send_dom_to_texture(&self, command: DOMToTextureCommand) -> WebGLSendResult {
186182
self.sender.send(WebGLMsg::DOMToTextureCommand(command))
187183
}
188-
189-
pub fn webxr_external_image_api(&self) -> impl webxr_api::WebGLExternalImageApi {
190-
SerializableWebGLMsgSender {
191-
ctx_id: self.ctx_id,
192-
sender: self.sender.to_ipc(),
193-
}
194-
}
195-
}
196-
197-
// WegGLMsgSender isn't actually serializable, despite what it claims.
198-
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
199-
struct SerializableWebGLMsgSender {
200-
ctx_id: WebGLContextId,
201-
#[ignore_malloc_size_of = "channels are hard"]
202-
sender: IpcSender<WebGLMsg>,
203-
}
204-
205-
#[typetag::serde]
206-
impl webxr_api::WebGLExternalImageApi for SerializableWebGLMsgSender {
207-
fn lock(&self) -> Result<(GLuint, Size2D<i32>, GLsync), webxr_api::Error> {
208-
let (sender, receiver) = ipc::channel().or(Err(webxr_api::Error::CommunicationError))?;
209-
self.sender
210-
.send(WebGLMsg::LockIPC(self.ctx_id, sender))
211-
.or(Err(webxr_api::Error::CommunicationError))?;
212-
let (texture, size, sync) = receiver
213-
.recv()
214-
.or(Err(webxr_api::Error::CommunicationError))?;
215-
Ok((texture, size, sync as GLsync))
216-
}
217-
218-
fn unlock(&self) {
219-
let _ = self.sender.send(WebGLMsg::Unlock(self.ctx_id));
220-
}
221184
}
222185

223186
#[derive(Deserialize, Serialize)]

components/script/dom/webglrenderingcontext.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ use canvas_traits::webgl::WebGLError::*;
5555
use canvas_traits::webgl::{
5656
webgl_channel, AlphaTreatment, DOMToTextureCommand, GLContextAttributes, GLLimits, GlType,
5757
Parameter, TexDataType, TexFormat, TexParameter, WebGLCommand, WebGLCommandBacktrace,
58-
WebGLContextShareMode, WebGLError, WebGLFramebufferBindingRequest, WebGLMsg, WebGLMsgSender,
59-
WebGLProgramId, WebGLResult, WebGLSLVersion, WebGLSender, WebGLVersion, WebVRCommand,
60-
YAxisTreatment,
58+
WebGLContextId, WebGLContextShareMode, WebGLError, WebGLFramebufferBindingRequest, WebGLMsg,
59+
WebGLMsgSender, WebGLProgramId, WebGLResult, WebGLSLVersion, WebGLSender, WebGLVersion,
60+
WebVRCommand, YAxisTreatment,
6161
};
6262
use dom_struct::dom_struct;
6363
use euclid::default::{Point2D, Rect, Size2D};
@@ -323,6 +323,10 @@ impl WebGLRenderingContext {
323323
self.webgl_sender.clone()
324324
}
325325

326+
pub fn context_id(&self) -> WebGLContextId {
327+
self.webgl_sender.context_id()
328+
}
329+
326330
#[inline]
327331
pub fn send_command(&self, command: WebGLCommand) {
328332
self.webgl_sender

components/script/dom/xr.rs

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -108,18 +108,6 @@ impl Into<SessionMode> for XRSessionMode {
108108
impl XRMethods for XR {
109109
/// https://immersive-web.github.io/webxr/#dom-xr-supportssessionmode
110110
fn SupportsSession(&self, mode: XRSessionMode) -> Rc<Promise> {
111-
#[derive(serde::Serialize, serde::Deserialize)]
112-
pub struct SupportsSession {
113-
sender: IpcSender<bool>,
114-
}
115-
116-
#[typetag::serde]
117-
impl webxr_api::SessionSupportCallback for SupportsSession {
118-
fn callback(&mut self, result: Result<(), XRError>) {
119-
let _ = self.sender.send(result.is_ok());
120-
}
121-
}
122-
123111
// XXXManishearth this should select an XR device first
124112
let promise = Promise::new(&self.global());
125113
let mut trusted = Some(TrustedPromise::new(promise.clone()));
@@ -139,13 +127,13 @@ impl XRMethods for XR {
139127
error!("supportsSession callback called twice!");
140128
return;
141129
};
142-
let message = if let Ok(message) = message.to() {
130+
let message: Result<(), webxr_api::Error> = if let Ok(message) = message.to() {
143131
message
144132
} else {
145133
error!("supportsSession callback given incorrect payload");
146134
return;
147135
};
148-
if message {
136+
if let Ok(()) = message {
149137
let _ = task_source.queue_with_canceller(trusted.resolve_task(()), &canceller);
150138
} else {
151139
let _ = task_source
@@ -155,7 +143,7 @@ impl XRMethods for XR {
155143
);
156144
window
157145
.webxr_registry()
158-
.supports_session(mode.into(), SupportsSession { sender });
146+
.supports_session(mode.into(), sender);
159147

160148
promise
161149
}
@@ -167,17 +155,6 @@ impl XRMethods for XR {
167155
_: &XRSessionInit,
168156
comp: InCompartment,
169157
) -> Rc<Promise> {
170-
#[derive(serde::Serialize, serde::Deserialize)]
171-
pub struct RequestSession {
172-
sender: IpcSender<Result<Session, XRError>>,
173-
}
174-
175-
#[typetag::serde]
176-
impl webxr_api::SessionRequestCallback for RequestSession {
177-
fn callback(&mut self, result: Result<Session, XRError>) {
178-
let _ = self.sender.send(result);
179-
}
180-
}
181158
let promise = Promise::new_in_current_compartment(&self.global(), comp);
182159
if mode != XRSessionMode::Immersive_vr {
183160
promise.reject_error(Error::NotSupported);
@@ -206,7 +183,7 @@ impl XRMethods for XR {
206183
// router doesn't know this is only called once
207184
let trusted = trusted.take().unwrap();
208185
let this = this.clone();
209-
let message = if let Ok(message) = message.to() {
186+
let message: Result<Session, webxr_api::Error> = if let Ok(message) = message.to() {
210187
message
211188
} else {
212189
error!("requestSession callback given incorrect payload");
@@ -220,9 +197,7 @@ impl XRMethods for XR {
220197
);
221198
}),
222199
);
223-
window
224-
.webxr_registry()
225-
.request_session(mode.into(), RequestSession { sender });
200+
window.webxr_registry().request_session(mode.into(), sender);
226201

227202
promise
228203
}

0 commit comments

Comments
 (0)