aboutsummaryrefslogtreecommitdiffstats
path: root/components/canvas/webgl_paint_task.rs
diff options
context:
space:
mode:
authorbors-servo <metajack+bors@gmail.com>2015-07-25 01:50:31 -0600
committerbors-servo <metajack+bors@gmail.com>2015-07-25 01:50:31 -0600
commit1764267379a00b96a1df89f3917299a0c6fd325c (patch)
tree15641e7ed77b46ab61bab772fa3c63b7e8e8d619 /components/canvas/webgl_paint_task.rs
parent886c08c393f51499490702eaf97fc770273a2600 (diff)
parentbb99b2f3c8813919c476930c709b73d3cfbc8c83 (diff)
downloadservo-1764267379a00b96a1df89f3917299a0c6fd325c.tar.gz
servo-1764267379a00b96a1df89f3917299a0c6fd325c.zip
Auto merge of #6616 - pcwalton:canvas-webgl-ipc, r=jdm
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. r? @jdm <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/6616) <!-- Reviewable:end -->
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