Skip to content

Commit

Permalink
Format components canvas and canvas_traits #21373
Browse files Browse the repository at this point in the history
  • Loading branch information
kingdido999 committed Aug 30, 2018
1 parent 2a4bee5 commit f472d05
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 47 deletions.
89 changes: 65 additions & 24 deletions components/canvas/webgl_mode/inprocess.rs
Expand Up @@ -22,23 +22,38 @@ pub struct WebGLThreads(WebGLSender<WebGLMsg>);


impl WebGLThreads { impl WebGLThreads {
/// Creates a new WebGLThreads object /// Creates a new WebGLThreads object
pub fn new(gl_factory: GLContextFactory, pub fn new(
webrender_gl: Rc<gl::Gl>, gl_factory: GLContextFactory,
webrender_api_sender: webrender_api::RenderApiSender, webrender_gl: Rc<gl::Gl>,
webvr_compositor: Option<Box<WebVRRenderHandler>>) webrender_api_sender: webrender_api::RenderApiSender,
-> (WebGLThreads, Box<webrender::ExternalImageHandler>, Option<Box<webrender::OutputImageHandler>>) { webvr_compositor: Option<Box<WebVRRenderHandler>>,
) -> (
WebGLThreads,
Box<webrender::ExternalImageHandler>,
Option<Box<webrender::OutputImageHandler>>,
) {
// This implementation creates a single `WebGLThread` for all the pipelines. // This implementation creates a single `WebGLThread` for all the pipelines.
let channel = WebGLThread::start(gl_factory, let channel = WebGLThread::start(
webrender_api_sender, gl_factory,
webvr_compositor.map(|c| WebVRRenderWrapper(c)), webrender_api_sender,
PhantomData); webvr_compositor.map(|c| WebVRRenderWrapper(c)),
PhantomData,
);
let output_handler = if PREFS.is_dom_to_texture_enabled() { let output_handler = if PREFS.is_dom_to_texture_enabled() {
Some(Box::new(OutputHandler::new(webrender_gl.clone(), channel.clone()))) Some(Box::new(OutputHandler::new(
webrender_gl.clone(),
channel.clone(),
)))
} else { } else {
None None
}; };
let external = WebGLExternalImageHandler::new(WebGLExternalImages::new(webrender_gl, channel.clone())); let external =
(WebGLThreads(channel), Box::new(external), output_handler.map(|b| b as Box<_>)) WebGLExternalImageHandler::new(WebGLExternalImages::new(webrender_gl, channel.clone()));
(
WebGLThreads(channel),
Box::new(external),
output_handler.map(|b| b as Box<_>),
)
} }


/// Gets the WebGLThread handle for each script pipeline. /// Gets the WebGLThread handle for each script pipeline.
Expand All @@ -49,7 +64,9 @@ impl WebGLThreads {


/// Sends a exit message to close the WebGLThreads and release all WebGLContexts. /// Sends a exit message to close the WebGLThreads and release all WebGLContexts.
pub fn exit(&self) -> Result<(), &'static str> { pub fn exit(&self) -> Result<(), &'static str> {
self.0.send(WebGLMsg::Exit).map_err(|_| "Failed to send Exit message") self.0
.send(WebGLMsg::Exit)
.map_err(|_| "Failed to send Exit message")
} }
} }


Expand All @@ -58,7 +75,10 @@ struct WebGLExternalImages {
webrender_gl: Rc<gl::Gl>, webrender_gl: Rc<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: (WebGLSender<(u32, Size2D<i32>, usize)>, WebGLReceiver<(u32, Size2D<i32>, usize)>), lock_channel: (
WebGLSender<(u32, Size2D<i32>, usize)>,
WebGLReceiver<(u32, Size2D<i32>, usize)>,
),
} }


impl WebGLExternalImages { impl WebGLExternalImages {
Expand All @@ -75,12 +95,15 @@ impl WebGLExternalImageApi for WebGLExternalImages {
fn lock(&mut self, ctx_id: WebGLContextId) -> (u32, Size2D<i32>) { fn lock(&mut self, ctx_id: WebGLContextId) -> (u32, Size2D<i32>) {
// 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.
self.webgl_channel.send(WebGLMsg::Lock(ctx_id, self.lock_channel.0.clone())).unwrap(); self.webgl_channel
.send(WebGLMsg::Lock(ctx_id, self.lock_channel.0.clone()))
.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 // 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. // 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. // 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); self.webrender_gl
.wait_sync(gl_sync as gl::GLsync, 0, gl::TIMEOUT_IGNORED);
(image_id, size) (image_id, size)
} }


Expand All @@ -92,19 +115,24 @@ impl WebGLExternalImageApi for WebGLExternalImages {
/// Custom observer used in a `WebGLThread`. /// Custom observer used in a `WebGLThread`.
impl WebGLThreadObserver for PhantomData<()> { impl WebGLThreadObserver for PhantomData<()> {
fn on_context_create(&mut self, ctx_id: WebGLContextId, texture_id: u32, size: Size2D<i32>) { fn on_context_create(&mut self, ctx_id: WebGLContextId, texture_id: u32, size: Size2D<i32>) {
debug!("WebGLContext created (ctx_id: {:?} texture_id: {:?} size: {:?}", ctx_id, texture_id, size); debug!(
"WebGLContext created (ctx_id: {:?} texture_id: {:?} size: {:?}",
ctx_id, texture_id, size
);
} }


fn on_context_resize(&mut self, ctx_id: WebGLContextId, texture_id: u32, size: Size2D<i32>) { fn on_context_resize(&mut self, ctx_id: WebGLContextId, texture_id: u32, size: Size2D<i32>) {
debug!("WebGLContext resized (ctx_id: {:?} texture_id: {:?} size: {:?}", ctx_id, texture_id, size); debug!(
"WebGLContext resized (ctx_id: {:?} texture_id: {:?} size: {:?}",
ctx_id, texture_id, size
);
} }


fn on_context_delete(&mut self, ctx_id: WebGLContextId) { fn on_context_delete(&mut self, ctx_id: WebGLContextId) {
debug!("WebGLContext deleted (ctx_id: {:?})", ctx_id); debug!("WebGLContext deleted (ctx_id: {:?})", ctx_id);
} }
} }



/// Wrapper to send WebVR commands used in `WebGLThread`. /// Wrapper to send WebVR commands used in `WebGLThread`.
struct WebVRRenderWrapper(Box<WebVRRenderHandler>); struct WebVRRenderWrapper(Box<WebVRRenderHandler>);


Expand All @@ -120,7 +148,10 @@ struct OutputHandler {
webrender_gl: Rc<gl::Gl>, webrender_gl: Rc<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: (WebGLSender<OutputHandlerData>, WebGLReceiver<OutputHandlerData>), lock_channel: (
WebGLSender<OutputHandlerData>,
WebGLReceiver<OutputHandlerData>,
),
sync_objects: FnvHashMap<webrender_api::PipelineId, gl::GLsync>, sync_objects: FnvHashMap<webrender_api::PipelineId, gl::GLsync>,
} }


Expand All @@ -137,14 +168,24 @@ impl OutputHandler {


/// Bridge between the WR frame outputs and WebGL to implement DOMToTexture synchronization. /// Bridge between the WR frame outputs and WebGL to implement DOMToTexture synchronization.
impl webrender::OutputImageHandler for OutputHandler { impl webrender::OutputImageHandler for OutputHandler {
fn lock(&mut self, id: webrender_api::PipelineId) -> Option<(u32, webrender_api::DeviceIntSize)> { fn lock(
&mut self,
id: webrender_api::PipelineId,
) -> Option<(u32, webrender_api::DeviceIntSize)> {
// Insert a fence in the WR command queue // Insert a fence in the WR command queue
let gl_sync = self.webrender_gl.fence_sync(gl::SYNC_GPU_COMMANDS_COMPLETE, 0); let gl_sync = self
.webrender_gl
.fence_sync(gl::SYNC_GPU_COMMANDS_COMPLETE, 0);
// The lock command adds a WaitSync call on the WebGL command flow. // The lock command adds a WaitSync call on the WebGL command flow.
let command = DOMToTextureCommand::Lock(id, gl_sync as usize, self.lock_channel.0.clone()); let command = DOMToTextureCommand::Lock(id, gl_sync as usize, self.lock_channel.0.clone());
self.webgl_channel.send(WebGLMsg::DOMToTextureCommand(command)).unwrap(); self.webgl_channel
.send(WebGLMsg::DOMToTextureCommand(command))
.unwrap();
self.lock_channel.1.recv().unwrap().map(|(tex_id, size)| { self.lock_channel.1.recv().unwrap().map(|(tex_id, size)| {
(tex_id, webrender_api::DeviceIntSize::new(size.width, size.height)) (
tex_id,
webrender_api::DeviceIntSize::new(size.width, size.height),
)
}) })
} }


Expand Down
4 changes: 2 additions & 2 deletions components/canvas_traits/webgl_channel/ipc.rs
Expand Up @@ -9,7 +9,7 @@ use std::io;
pub type WebGLSender<T> = ipc_channel::ipc::IpcSender<T>; pub type WebGLSender<T> = ipc_channel::ipc::IpcSender<T>;
pub type WebGLReceiver<T> = ipc_channel::ipc::IpcReceiver<T>; pub type WebGLReceiver<T> = ipc_channel::ipc::IpcReceiver<T>;


pub fn webgl_channel<T: Serialize + for<'de> Deserialize<'de>>() pub fn webgl_channel<T: Serialize + for<'de> Deserialize<'de>>(
-> Result<(WebGLSender<T>, WebGLReceiver<T>), io::Error> { ) -> Result<(WebGLSender<T>, WebGLReceiver<T>), io::Error> {
ipc_channel::ipc::channel() ipc_channel::ipc::channel()
} }
39 changes: 19 additions & 20 deletions components/canvas_traits/webgl_channel/mod.rs
Expand Up @@ -13,9 +13,7 @@ use servo_config::opts;
use std::fmt; use std::fmt;


lazy_static! { lazy_static! {
static ref IS_MULTIPROCESS: bool = { static ref IS_MULTIPROCESS: bool = { opts::multiprocess() };
opts::multiprocess()
};
} }


#[derive(Clone, Deserialize, Serialize)] #[derive(Clone, Deserialize, Serialize)]
Expand All @@ -34,41 +32,42 @@ impl<T: Serialize> WebGLSender<T> {
#[inline] #[inline]
pub fn send(&self, msg: T) -> WebGLSendResult { pub fn send(&self, msg: T) -> WebGLSendResult {
match *self { match *self {
WebGLSender::Ipc(ref sender) => { WebGLSender::Ipc(ref sender) => sender.send(msg).map_err(|_| ()),
sender.send(msg).map_err(|_| ()) WebGLSender::Mpsc(ref sender) => sender.send(msg).map_err(|_| ()),
},
WebGLSender::Mpsc(ref sender) => {
sender.send(msg).map_err(|_| ())
}
} }
} }
} }


pub type WebGLSendResult = Result<(), ()>; pub type WebGLSendResult = Result<(), ()>;


pub enum WebGLReceiver<T> where T: for<'de> Deserialize<'de> + Serialize { pub enum WebGLReceiver<T>
where
T: for<'de> Deserialize<'de> + Serialize,
{
Ipc(ipc::WebGLReceiver<T>), Ipc(ipc::WebGLReceiver<T>),
Mpsc(mpsc::WebGLReceiver<T>), Mpsc(mpsc::WebGLReceiver<T>),
} }


impl<T> WebGLReceiver<T> where T: for<'de> Deserialize<'de> + Serialize { impl<T> WebGLReceiver<T>
where
T: for<'de> Deserialize<'de> + Serialize,
{
pub fn recv(&self) -> Result<T, ()> { pub fn recv(&self) -> Result<T, ()> {
match *self { match *self {
WebGLReceiver::Ipc(ref receiver) => { WebGLReceiver::Ipc(ref receiver) => receiver.recv().map_err(|_| ()),
receiver.recv().map_err(|_| ()) WebGLReceiver::Mpsc(ref receiver) => receiver.recv().map_err(|_| ()),
},
WebGLReceiver::Mpsc(ref receiver) => {
receiver.recv().map_err(|_| ())
}
} }
} }
} }


pub fn webgl_channel<T>() -> Result<(WebGLSender<T>, WebGLReceiver<T>), ()> pub fn webgl_channel<T>() -> Result<(WebGLSender<T>, WebGLReceiver<T>), ()>
where T: for<'de> Deserialize<'de> + Serialize { where
T: for<'de> Deserialize<'de> + Serialize,
{
if *IS_MULTIPROCESS { if *IS_MULTIPROCESS {
ipc::webgl_channel().map(|(tx, rx)| (WebGLSender::Ipc(tx), WebGLReceiver::Ipc(rx))) ipc::webgl_channel()
.map_err(|_| ()) .map(|(tx, rx)| (WebGLSender::Ipc(tx), WebGLReceiver::Ipc(rx)))
.map_err(|_| ())
} else { } else {
mpsc::webgl_channel().map(|(tx, rx)| (WebGLSender::Mpsc(tx), WebGLReceiver::Mpsc(rx))) mpsc::webgl_channel().map(|(tx, rx)| (WebGLSender::Mpsc(tx), WebGLReceiver::Mpsc(rx)))
} }
Expand Down
4 changes: 3 additions & 1 deletion components/canvas_traits/webgl_channel/mpsc.rs
Expand Up @@ -17,7 +17,9 @@ macro_rules! unreachable_serializable {


impl<'a, T> Deserialize<'a> for $name<T> { impl<'a, T> Deserialize<'a> for $name<T> {
fn deserialize<D>(_: D) -> Result<$name<T>, D::Error> fn deserialize<D>(_: D) -> Result<$name<T>, D::Error>
where D: Deserializer<'a> { where
D: Deserializer<'a>,
{
unreachable!(); unreachable!();
} }
} }
Expand Down

0 comments on commit f472d05

Please sign in to comment.