diff options
Diffstat (limited to 'components/canvas')
-rw-r--r-- | components/canvas/Cargo.toml | 6 | ||||
-rw-r--r-- | components/canvas/canvas_paint_task.rs | 44 | ||||
-rw-r--r-- | components/canvas/lib.rs | 2 | ||||
-rw-r--r-- | components/canvas/webgl_paint_task.rs | 66 |
4 files changed, 81 insertions, 37 deletions
diff --git a/components/canvas/Cargo.toml b/components/canvas/Cargo.toml index 92081f00c16..d466d425aad 100644 --- a/components/canvas/Cargo.toml +++ b/components/canvas/Cargo.toml @@ -30,9 +30,13 @@ features = ["texture_surface"] [dependencies.ipc-channel] git = "https://github.com/pcwalton/ipc-channel" +[dependencies.cssparser] +version = "0.3" +features = [ "serde-serialization" ] + [dependencies] log = "0.3" -cssparser = "0.3.1" num = "0.1.24" gleam = "0.1" euclid = "0.1" + diff --git a/components/canvas/canvas_paint_task.rs b/components/canvas/canvas_paint_task.rs index af00d817ab6..0b5e96ff921 100644 --- a/components/canvas/canvas_paint_task.rs +++ b/components/canvas/canvas_paint_task.rs @@ -11,6 +11,8 @@ use euclid::matrix2d::Matrix2D; use euclid::point::Point2D; use euclid::rect::Rect; use euclid::size::Size2D; +use ipc_channel::ipc::{self, IpcSender}; +use ipc_channel::router::ROUTER; use layers::platform::surface::NativeSurface; use gfx_traits::color; use ipc_channel::ipc::IpcSharedMemory; @@ -161,13 +163,19 @@ impl<'a> CanvasPaintTask<'a> { } } - pub fn start(size: Size2D<i32>) -> Sender<CanvasMsg> { - let (chan, port) = channel::<CanvasMsg>(); + /// Creates a new `CanvasPaintTask` and returns the out-of-process sender and the in-process + /// sender for it. + pub fn start(size: Size2D<i32>) -> (IpcSender<CanvasMsg>, Sender<CanvasMsg>) { + // TODO(pcwalton): Ask the pipeline to create this for us instead of spawning it directly. + // This will be needed for multiprocess Servo. + 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()); spawn_named("CanvasTask".to_owned(), move || { let mut painter = CanvasPaintTask::new(size); - loop { - match port.recv().unwrap() { + let msg = in_process_port.recv(); + match msg.unwrap() { CanvasMsg::Canvas2d(message) => { match message { Canvas2dMsg::FillRect(ref rect) => painter.fill_rect(rect), @@ -225,17 +233,28 @@ impl<'a> CanvasPaintTask<'a> { match message { CanvasCommonMsg::Close => break, CanvasCommonMsg::Recreate(size) => painter.recreate(size), - CanvasCommonMsg::SendPixelContents(chan) => - painter.send_pixel_contents(chan), - CanvasCommonMsg::SendNativeSurface(chan) => - painter.send_native_surface(chan), } }, + 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::WebGL(_) => panic!("Wrong message sent to Canvas2D task"), } } }); - chan + + (out_of_process_chan, in_process_chan) } fn save_context_state(&mut self) { @@ -516,7 +535,7 @@ impl<'a> CanvasPaintTask<'a> { self.drawtarget = CanvasPaintTask::create(size); } - fn send_pixel_contents(&mut self, chan: Sender<IpcSharedMemory>) { + fn send_pixel_contents(&mut self, chan: IpcSender<IpcSharedMemory>) { self.drawtarget.snapshot().get_data_surface().with_data(|element| { chan.send(IpcSharedMemory::from_bytes(element)).unwrap(); }) @@ -528,7 +547,10 @@ impl<'a> CanvasPaintTask<'a> { unimplemented!() } - fn get_image_data(&self, mut dest_rect: Rect<f64>, canvas_size: Size2D<f64>, chan: Sender<Vec<u8>>) { + fn get_image_data(&self, + mut dest_rect: Rect<f64>, + canvas_size: Size2D<f64>, + chan: IpcSender<Vec<u8>>) { if dest_rect.size.width < 0.0 { dest_rect.size.width = -dest_rect.size.width; dest_rect.origin.x -= dest_rect.size.width; diff --git a/components/canvas/lib.rs b/components/canvas/lib.rs index b78f552f9bb..443c9b901f8 100644 --- a/components/canvas/lib.rs +++ b/components/canvas/lib.rs @@ -13,12 +13,12 @@ extern crate azure; extern crate cssparser; extern crate euclid; extern crate gfx_traits; +extern crate ipc_channel; extern crate util; extern crate gleam; extern crate num; extern crate layers; extern crate offscreen_gl_context; -extern crate ipc_channel; #[macro_use] extern crate log; 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 |