aboutsummaryrefslogtreecommitdiffstats
path: root/components/canvas
diff options
context:
space:
mode:
Diffstat (limited to 'components/canvas')
-rw-r--r--components/canvas/Cargo.toml6
-rw-r--r--components/canvas/canvas_paint_task.rs44
-rw-r--r--components/canvas/lib.rs2
-rw-r--r--components/canvas/webgl_paint_task.rs66
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