diff options
author | Patrick Walton <pcwalton@mimiga.net> | 2015-07-13 17:02:35 -0700 |
---|---|---|
committer | Patrick Walton <pcwalton@mimiga.net> | 2015-07-25 00:50:12 -0700 |
commit | bb99b2f3c8813919c476930c709b73d3cfbc8c83 (patch) | |
tree | 15641e7ed77b46ab61bab772fa3c63b7e8e8d619 /components/canvas/webgl_paint_task.rs | |
parent | 886c08c393f51499490702eaf97fc770273a2600 (diff) | |
download | servo-bb99b2f3c8813919c476930c709b73d3cfbc8c83.tar.gz servo-bb99b2f3c8813919c476930c709b73d3cfbc8c83.zip |
script: Make most of 2D canvas and WebGL run over IPC.
To actually make the multiprocess communication work, we'll need to
reroute the task creation to the pipeline or the compositor. But this
works as a first step.
Diffstat (limited to 'components/canvas/webgl_paint_task.rs')
-rw-r--r-- | components/canvas/webgl_paint_task.rs | 66 |
1 files changed, 42 insertions, 24 deletions
diff --git a/components/canvas/webgl_paint_task.rs b/components/canvas/webgl_paint_task.rs index 8af5e547c3a..fdf75e05cb5 100644 --- a/components/canvas/webgl_paint_task.rs +++ b/components/canvas/webgl_paint_task.rs @@ -2,7 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use canvas_traits::{CanvasMsg, CanvasWebGLMsg, CanvasCommonMsg, WebGLShaderParameter, WebGLFramebufferBindingRequest}; +use canvas_traits::{CanvasMsg, CanvasWebGLMsg, CanvasCommonMsg, FromLayoutMsg, FromPaintMsg}; +use canvas_traits::{WebGLShaderParameter, WebGLFramebufferBindingRequest}; use euclid::size::Size2D; use core::nonzero::NonZero; use gleam::gl; @@ -16,7 +17,8 @@ use std::sync::mpsc::{channel, Sender}; use util::vec::byte_swap; use layers::platform::surface::NativeSurface; use offscreen_gl_context::{GLContext, GLContextAttributes, ColorAttachmentType}; -use ipc_channel::ipc::IpcSharedMemory; +use ipc_channel::ipc::{self, IpcSender, IpcSharedMemory}; +use ipc_channel::router::ROUTER; pub struct WebGLPaintTask { size: Size2D<i32>, @@ -135,45 +137,58 @@ impl WebGLPaintTask { } } - pub fn start(size: Size2D<i32>, attrs: GLContextAttributes) -> Result<Sender<CanvasMsg>, &'static str> { - let (chan, port) = channel::<CanvasMsg>(); + /// Creates a new `WebGLPaintTask` and returns the out-of-process sender and the in-process + /// sender for it. + pub fn start(size: Size2D<i32>, attrs: GLContextAttributes) + -> Result<(IpcSender<CanvasMsg>, Sender<CanvasMsg>), &'static str> { + let (out_of_process_chan, out_of_process_port) = ipc::channel::<CanvasMsg>().unwrap(); + let (in_process_chan, in_process_port) = channel(); + ROUTER.route_ipc_receiver_to_mpsc_sender(out_of_process_port, in_process_chan.clone()); let mut painter = try!(WebGLPaintTask::new(size, attrs)); spawn_named("WebGLTask".to_owned(), move || { painter.init(); loop { - match port.recv().unwrap() { + match in_process_port.recv().unwrap() { CanvasMsg::WebGL(message) => painter.handle_webgl_message(message), CanvasMsg::Common(message) => { match message { CanvasCommonMsg::Close => break, - CanvasCommonMsg::SendPixelContents(chan) => - painter.send_pixel_contents(chan), - CanvasCommonMsg::SendNativeSurface(chan) => - painter.send_native_surface(chan), // TODO(ecoal95): handle error nicely CanvasCommonMsg::Recreate(size) => painter.recreate(size).unwrap(), } }, + CanvasMsg::FromLayout(message) => { + match message { + FromLayoutMsg::SendPixelContents(chan) => + painter.send_pixel_contents(chan), + } + } + CanvasMsg::FromPaint(message) => { + match message { + FromPaintMsg::SendNativeSurface(chan) => + painter.send_native_surface(chan), + } + } CanvasMsg::Canvas2d(_) => panic!("Wrong message sent to WebGLTask"), } } }); - Ok(chan) + Ok((out_of_process_chan, in_process_chan)) } #[inline] - fn get_context_attributes(&self, sender: Sender<GLContextAttributes>) { + fn get_context_attributes(&self, sender: IpcSender<GLContextAttributes>) { sender.send(*self.gl_context.borrow_attributes()).unwrap() } #[inline] - fn send_drawing_buffer_width(&self, sender: Sender<i32>) { + fn send_drawing_buffer_width(&self, sender: IpcSender<i32>) { sender.send(self.size.width).unwrap() } #[inline] - fn send_drawing_buffer_height(&self, sender: Sender<i32>) { + fn send_drawing_buffer_height(&self, sender: IpcSender<i32>) { sender.send(self.size.height).unwrap() } @@ -234,7 +249,7 @@ impl WebGLPaintTask { gl::clear_color(r, g, b, a); } - fn create_buffer(&self, chan: Sender<Option<NonZero<u32>>>) { + fn create_buffer(&self, chan: IpcSender<Option<NonZero<u32>>>) { let buffer = gl::gen_buffers(1)[0]; let buffer = if buffer == 0 { None @@ -244,7 +259,7 @@ impl WebGLPaintTask { chan.send(buffer).unwrap(); } - fn create_framebuffer(&self, chan: Sender<Option<NonZero<u32>>>) { + fn create_framebuffer(&self, chan: IpcSender<Option<NonZero<u32>>>) { let framebuffer = gl::gen_framebuffers(1)[0]; let framebuffer = if framebuffer == 0 { None @@ -254,7 +269,7 @@ impl WebGLPaintTask { chan.send(framebuffer).unwrap(); } - fn create_renderbuffer(&self, chan: Sender<Option<NonZero<u32>>>) { + fn create_renderbuffer(&self, chan: IpcSender<Option<NonZero<u32>>>) { let renderbuffer = gl::gen_renderbuffers(1)[0]; let renderbuffer = if renderbuffer == 0 { None @@ -264,7 +279,7 @@ impl WebGLPaintTask { chan.send(renderbuffer).unwrap(); } - fn create_texture(&self, chan: Sender<Option<NonZero<u32>>>) { + fn create_texture(&self, chan: IpcSender<Option<NonZero<u32>>>) { let texture = gl::gen_framebuffers(1)[0]; let texture = if texture == 0 { None @@ -274,7 +289,7 @@ impl WebGLPaintTask { chan.send(texture).unwrap(); } - fn create_program(&self, chan: Sender<Option<NonZero<u32>>>) { + fn create_program(&self, chan: IpcSender<Option<NonZero<u32>>>) { let program = gl::create_program(); let program = if program == 0 { None @@ -284,7 +299,7 @@ impl WebGLPaintTask { chan.send(program).unwrap(); } - fn create_shader(&self, shader_type: u32, chan: Sender<Option<NonZero<u32>>>) { + fn create_shader(&self, shader_type: u32, chan: IpcSender<Option<NonZero<u32>>>) { let shader = gl::create_shader(shader_type); let shader = if shader == 0 { None @@ -368,7 +383,7 @@ impl WebGLPaintTask { gl::enable_vertex_attrib_array(attrib_id); } - fn get_attrib_location(&self, program_id: u32, name: String, chan: Sender<Option<i32>> ) { + fn get_attrib_location(&self, program_id: u32, name: String, chan: IpcSender<Option<i32>> ) { let attrib_location = gl::get_attrib_location(program_id, &name); let attrib_location = if attrib_location == -1 { @@ -380,14 +395,17 @@ impl WebGLPaintTask { chan.send(attrib_location).unwrap(); } - fn get_shader_info_log(&self, shader_id: u32, chan: Sender<Option<String>>) { + fn get_shader_info_log(&self, shader_id: u32, chan: IpcSender<Option<String>>) { // TODO(ecoal95): Right now we always return a value, we should // check for gl errors and return None there let info = gl::get_shader_info_log(shader_id); chan.send(Some(info)).unwrap(); } - fn get_shader_parameter(&self, shader_id: u32, param_id: u32, chan: Sender<WebGLShaderParameter>) { + fn get_shader_parameter(&self, + shader_id: u32, + param_id: u32, + chan: IpcSender<WebGLShaderParameter>) { let result = match param_id { gl::SHADER_TYPE => WebGLShaderParameter::Int(gl::get_shader_iv(shader_id, param_id)), @@ -399,7 +417,7 @@ impl WebGLPaintTask { chan.send(result).unwrap(); } - fn get_uniform_location(&self, program_id: u32, name: String, chan: Sender<Option<i32>>) { + fn get_uniform_location(&self, program_id: u32, name: String, chan: IpcSender<Option<i32>>) { let location = gl::get_uniform_location(program_id, &name); let location = if location == -1 { None @@ -441,7 +459,7 @@ impl WebGLPaintTask { gl::viewport(x, y, width, height); } - fn send_pixel_contents(&mut self, chan: Sender<IpcSharedMemory>) { + fn send_pixel_contents(&mut self, chan: IpcSender<IpcSharedMemory>) { // FIXME(#5652, dmarcos) Instead of a readback strategy we have // to layerize the canvas. // TODO(pcwalton): We'd save a copy if we had an `IpcSharedMemoryBuilder` abstraction that |