aboutsummaryrefslogtreecommitdiffstats
path: root/components/canvas/webgl_paint_task.rs
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2015-07-13 17:02:35 -0700
committerPatrick Walton <pcwalton@mimiga.net>2015-07-25 00:50:12 -0700
commitbb99b2f3c8813919c476930c709b73d3cfbc8c83 (patch)
tree15641e7ed77b46ab61bab772fa3c63b7e8e8d619 /components/canvas/webgl_paint_task.rs
parent886c08c393f51499490702eaf97fc770273a2600 (diff)
downloadservo-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.rs66
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