Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

script: Make most of 2D canvas and WebGL run over IPC. #6616

Merged
merged 1 commit into from Jul 25, 2015
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -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"

@@ -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;
@@ -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;
@@ -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
@@ -22,6 +22,15 @@ git = "https://github.com/ecoal95/rust-offscreen-rendering-context"
[dependencies.ipc-channel]
git = "https://github.com/pcwalton/ipc-channel"

[dependencies.serde]
version = "0.4"
features = [ "nightly" ]

[dependencies.cssparser]
version = "0.3"
features = [ "serde-serialization" ]

[dependencies]
cssparser = "0.3.1"
euclid = "0.1"
serde_macros = "0.4"

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.