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.
This commit is contained in:
Patrick Walton 2015-07-13 17:02:35 -07:00
parent 886c08c393
commit bb99b2f3c8
39 changed files with 694 additions and 365 deletions

View file

@ -17,7 +17,7 @@ use dom::window::{self, WindowHelpers};
use devtools_traits::DevtoolsControlChan;
use script_task::{ScriptChan, ScriptPort, ScriptMsg, ScriptTask};
use msg::constellation_msg::{PipelineId, WorkerId};
use msg::constellation_msg::{ConstellationChan, PipelineId, WorkerId};
use net_traits::ResourceTask;
use profile_traits::mem;
@ -91,6 +91,14 @@ impl<'a> GlobalRef<'a> {
}
}
/// Get a `ConstellationChan` to send messages to the constellation channel when available.
pub fn constellation_chan(&self) -> ConstellationChan {
match *self {
GlobalRef::Window(window) => window.constellation_chan(),
GlobalRef::Worker(worker) => worker.constellation_chan(),
}
}
/// Get a `DevtoolsControlChan` to send messages to Devtools
/// task when available.
pub fn devtools_chan(&self) -> Option<DevtoolsControlChan> {

View file

@ -62,8 +62,8 @@ use msg::compositor_msg::ScriptListener;
use msg::constellation_msg::ConstellationChan;
use net_traits::image::base::Image;
use profile_traits::mem::ProfilerChan;
use serde::Serialize;
use util::str::{LengthOrPercentageOrAuto};
use serde::{Deserialize, Serialize};
use std::cell::{Cell, UnsafeCell, RefCell};
use std::collections::{HashMap, HashSet};
use std::collections::hash_state::HashState;
@ -332,6 +332,13 @@ impl<A,B> JSTraceable for fn(A) -> B {
}
}
impl<T> JSTraceable for IpcSender<T> where T: Deserialize + Serialize {
#[inline]
fn trace(&self, _: *mut JSTracer) {
// Do nothing
}
}
impl JSTraceable for ScriptListener {
#[inline]
fn trace(&self, _: *mut JSTracer) {
@ -346,13 +353,6 @@ impl JSTraceable for Box<LayoutRPC+'static> {
}
}
impl<T> JSTraceable for IpcSender<T> where T: Serialize {
#[inline]
fn trace(&self, _: *mut JSTracer) {
// Do nothing
}
}
impl JSTraceable for () {
#[inline]
fn trace(&self, _trc: *mut JSTracer) {

View file

@ -28,20 +28,22 @@ use euclid::matrix2d::Matrix2D;
use euclid::point::Point2D;
use euclid::rect::Rect;
use euclid::size::Size2D;
use ipc_channel::ipc;
use canvas_traits::{CanvasMsg, Canvas2dMsg, CanvasCommonMsg};
use canvas_traits::{FillOrStrokeStyle, LinearGradientStyle, RadialGradientStyle, RepetitionStyle};
use canvas_traits::{LineCapStyle, LineJoinStyle, CompositionOrBlending};
use canvas::canvas_paint_task::CanvasPaintTask;
use msg::constellation_msg::Msg as ConstellationMsg;
use net_traits::image_cache_task::{ImageCacheChan, ImageResponse};
use net_traits::image::base::PixelFormat;
use ipc_channel::ipc::IpcSender;
use num::{Float, ToPrimitive};
use std::borrow::ToOwned;
use std::cell::RefCell;
use std::fmt;
use std::sync::mpsc::{channel, Sender};
use std::sync::mpsc::channel;
use util::str::DOMString;
use url::Url;
@ -60,7 +62,8 @@ pub enum CanvasFillOrStrokeStyle {
pub struct CanvasRenderingContext2D {
reflector_: Reflector,
global: GlobalField,
renderer: Sender<CanvasMsg>,
renderer_id: usize,
ipc_renderer: IpcSender<CanvasMsg>,
canvas: JS<HTMLCanvasElement>,
state: RefCell<CanvasContextState>,
saved_states: RefCell<Vec<CanvasContextState>>,
@ -115,10 +118,15 @@ impl CanvasContextState {
impl CanvasRenderingContext2D {
fn new_inherited(global: GlobalRef, canvas: &HTMLCanvasElement, size: Size2D<i32>)
-> CanvasRenderingContext2D {
let (sender, receiver) = ipc::channel().unwrap();
let constellation_chan = global.constellation_chan();
constellation_chan.0.send(ConstellationMsg::CreateCanvasPaintTask(size, sender)).unwrap();
let (ipc_renderer, renderer_id) = receiver.recv().unwrap();
CanvasRenderingContext2D {
reflector_: Reflector::new(),
global: GlobalField::from_rooted(&global),
renderer: CanvasPaintTask::start(size),
renderer_id: renderer_id,
ipc_renderer: ipc_renderer,
canvas: JS::from_ref(canvas),
state: RefCell::new(CanvasContextState::new()),
saved_states: RefCell::new(Vec::new()),
@ -132,7 +140,9 @@ impl CanvasRenderingContext2D {
}
pub fn recreate(&self, size: Size2D<i32>) {
self.renderer.send(CanvasMsg::Common(CanvasCommonMsg::Recreate(size))).unwrap();
self.ipc_renderer
.send(CanvasMsg::Common(CanvasCommonMsg::Recreate(size)))
.unwrap();
}
fn mark_as_dirty(&self) {
@ -142,7 +152,9 @@ impl CanvasRenderingContext2D {
}
fn update_transform(&self) {
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetTransform(self.state.borrow().transform))).unwrap()
self.ipc_renderer
.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetTransform(self.state.borrow().transform)))
.unwrap()
}
// It is used by DrawImage to calculate the size of the source and destination rectangles based
@ -237,17 +249,19 @@ impl CanvasRenderingContext2D {
None => return Err(InvalidState),
};
let renderer = context.r().get_renderer();
let (sender, receiver) = channel::<Vec<u8>>();
let renderer = context.r().get_ipc_renderer();
let (sender, receiver) = ipc::channel::<Vec<u8>>().unwrap();
// Reads pixels from source image
renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::GetImageData(source_rect, image_size, sender))).unwrap();
renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::GetImageData(source_rect,
image_size,
sender))).unwrap();
let imagedata = receiver.recv().unwrap();
// Writes pixels to destination canvas
CanvasMsg::Canvas2d(
Canvas2dMsg::DrawImage(imagedata, source_rect.size, dest_rect, source_rect, smoothing_enabled))
};
self.renderer.send(msg).unwrap();
self.ipc_renderer.send(msg).unwrap();
self.mark_as_dirty();
Ok(())
}
@ -265,9 +279,13 @@ impl CanvasRenderingContext2D {
}
let smoothing_enabled = self.state.borrow().image_smoothing_enabled;
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::DrawImage(
image_data, image_size, dest_rect,
source_rect, smoothing_enabled))).unwrap();
self.ipc_renderer
.send(CanvasMsg::Canvas2d(Canvas2dMsg::DrawImage(image_data,
image_size,
dest_rect,
source_rect,
smoothing_enabled)))
.unwrap();
self.mark_as_dirty();
Ok(())
}
@ -282,7 +300,9 @@ impl CanvasRenderingContext2D {
let img = match self.request_image_from_cache(url) {
ImageResponse::Loaded(img) => img,
ImageResponse::PlaceholderLoaded(_) | ImageResponse::None => return None,
ImageResponse::PlaceholderLoaded(_) | ImageResponse::None => {
return None
}
};
let image_size = Size2D::new(img.width as f64, img.height as f64);
@ -308,8 +328,8 @@ impl CanvasRenderingContext2D {
let canvas_size = canvas_element.get_size();
let image_size = Size2D::new(canvas_size.width as f64, canvas_size.height as f64);
let renderer = context.r().get_renderer();
let (sender, receiver) = channel::<Vec<u8>>();
let renderer = context.r().get_ipc_renderer();
let (sender, receiver) = ipc::channel::<Vec<u8>>().unwrap();
// Reads pixels from source canvas
renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::GetImageData(source_rect, image_size, sender))).unwrap();
@ -341,24 +361,34 @@ impl CanvasRenderingContext2D {
}
pub trait CanvasRenderingContext2DHelpers {
fn get_renderer(self) -> Sender<CanvasMsg>;
fn get_renderer_id(self) -> usize;
fn get_ipc_renderer(self) -> IpcSender<CanvasMsg>;
}
impl<'a> CanvasRenderingContext2DHelpers for &'a CanvasRenderingContext2D {
fn get_renderer(self) -> Sender<CanvasMsg> {
self.renderer.clone()
fn get_renderer_id(self) -> usize {
self.renderer_id
}
fn get_ipc_renderer(self) -> IpcSender<CanvasMsg> {
self.ipc_renderer.clone()
}
}
pub trait LayoutCanvasRenderingContext2DHelpers {
#[allow(unsafe_code)]
unsafe fn get_renderer(&self) -> Sender<CanvasMsg>;
unsafe fn get_renderer_id(&self) -> usize;
#[allow(unsafe_code)]
unsafe fn get_ipc_renderer(&self) -> IpcSender<CanvasMsg>;
}
impl LayoutCanvasRenderingContext2DHelpers for LayoutJS<CanvasRenderingContext2D> {
#[allow(unsafe_code)]
unsafe fn get_renderer(&self) -> Sender<CanvasMsg> {
(*self.unsafe_get()).renderer.clone()
unsafe fn get_renderer_id(&self) -> usize {
(*self.unsafe_get()).renderer_id
}
#[allow(unsafe_code)]
unsafe fn get_ipc_renderer(&self) -> IpcSender<CanvasMsg> {
(*self.unsafe_get()).ipc_renderer.clone()
}
}
@ -380,7 +410,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
// https://html.spec.whatwg.org/multipage/#dom-context-2d-save
fn Save(self) {
self.saved_states.borrow_mut().push(self.state.borrow().clone());
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SaveContext)).unwrap();
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SaveContext)).unwrap();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-restore
@ -388,7 +418,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
let mut saved_states = self.saved_states.borrow_mut();
if let Some(state) = saved_states.pop() {
self.state.borrow_mut().clone_from(&state);
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::RestoreContext)).unwrap();
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::RestoreContext)).unwrap();
}
}
@ -480,7 +510,9 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
self.state.borrow_mut().global_alpha = alpha;
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetGlobalAlpha(alpha as f32))).unwrap()
self.ipc_renderer
.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetGlobalAlpha(alpha as f32)))
.unwrap()
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-globalcompositeoperation
@ -496,14 +528,16 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
fn SetGlobalCompositeOperation(self, op_str: DOMString) {
if let Some(op) = CompositionOrBlending::from_str(&op_str) {
self.state.borrow_mut().global_composition = op;
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetGlobalComposition(op))).unwrap()
self.ipc_renderer
.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetGlobalComposition(op)))
.unwrap()
}
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-fillrect
fn FillRect(self, x: f64, y: f64, width: f64, height: f64) {
if let Some(rect) = self.create_drawable_rect(x, y, width, height) {
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::FillRect(rect))).unwrap();
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::FillRect(rect))).unwrap();
self.mark_as_dirty();
}
}
@ -511,7 +545,9 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
// https://html.spec.whatwg.org/multipage/#dom-context-2d-clearrect
fn ClearRect(self, x: f64, y: f64, width: f64, height: f64) {
if let Some(rect) = self.create_drawable_rect(x, y, width, height) {
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::ClearRect(rect))).unwrap();
self.ipc_renderer
.send(CanvasMsg::Canvas2d(Canvas2dMsg::ClearRect(rect)))
.unwrap();
self.mark_as_dirty();
}
}
@ -519,38 +555,40 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokerect
fn StrokeRect(self, x: f64, y: f64, width: f64, height: f64) {
if let Some(rect) = self.create_drawable_rect(x, y, width, height) {
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::StrokeRect(rect))).unwrap();
self.ipc_renderer
.send(CanvasMsg::Canvas2d(Canvas2dMsg::StrokeRect(rect)))
.unwrap();
self.mark_as_dirty();
}
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-beginpath
fn BeginPath(self) {
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::BeginPath)).unwrap();
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::BeginPath)).unwrap();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-closepath
fn ClosePath(self) {
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::ClosePath)).unwrap();
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::ClosePath)).unwrap();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-fill
fn Fill(self, _: CanvasWindingRule) {
// TODO: Process winding rule
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::Fill)).unwrap();
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::Fill)).unwrap();
self.mark_as_dirty();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-stroke
fn Stroke(self) {
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::Stroke)).unwrap();
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::Stroke)).unwrap();
self.mark_as_dirty();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-clip
fn Clip(self, _: CanvasWindingRule) {
// TODO: Process winding rule
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::Clip)).unwrap();
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::Clip)).unwrap();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-drawimage
@ -728,7 +766,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
let msg = CanvasMsg::Canvas2d(
Canvas2dMsg::MoveTo(
Point2D::new(x as f32, y as f32)));
self.renderer.send(msg).unwrap();
self.ipc_renderer.send(msg).unwrap();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-lineto
@ -740,7 +778,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
let msg = CanvasMsg::Canvas2d(
Canvas2dMsg::LineTo(
Point2D::new(x as f32, y as f32)));
self.renderer.send(msg).unwrap();
self.ipc_renderer.send(msg).unwrap();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-rect
@ -749,7 +787,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
let rect = Rect::new(Point2D::new(x as f32, y as f32),
Size2D::new(width as f32, height as f32));
let msg = CanvasMsg::Canvas2d(Canvas2dMsg::Rect(rect));
self.renderer.send(msg).unwrap();
self.ipc_renderer.send(msg).unwrap();
}
}
@ -764,7 +802,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
Canvas2dMsg::QuadraticCurveTo(
Point2D::new(cpx as f32, cpy as f32),
Point2D::new(x as f32, y as f32)));
self.renderer.send(msg).unwrap();
self.ipc_renderer.send(msg).unwrap();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-beziercurveto
@ -779,7 +817,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
Point2D::new(cp1x as f32, cp1y as f32),
Point2D::new(cp2x as f32, cp2y as f32),
Point2D::new(x as f32, y as f32)));
self.renderer.send(msg).unwrap();
self.ipc_renderer.send(msg).unwrap();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-arc
@ -800,7 +838,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
Point2D::new(x as f32, y as f32), r as f32,
start as f32, end as f32, ccw));
self.renderer.send(msg).unwrap();
self.ipc_renderer.send(msg).unwrap();
Ok(())
}
@ -818,7 +856,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
Point2D::new(cp1x as f32, cp1y as f32),
Point2D::new(cp2x as f32, cp2y as f32),
r as f32));
self.renderer.send(msg).unwrap();
self.ipc_renderer.send(msg).unwrap();
Ok(())
}
@ -854,8 +892,9 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
match parse_color(&string) {
Ok(rgba) => {
self.state.borrow_mut().stroke_style = CanvasFillOrStrokeStyle::Color(rgba);
self.renderer
.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetStrokeStyle(FillOrStrokeStyle::Color(rgba))))
self.ipc_renderer
.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetStrokeStyle(
FillOrStrokeStyle::Color(rgba))))
.unwrap();
}
_ => {}
@ -866,7 +905,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
JS::from_ref(gradient.r()));
let msg = CanvasMsg::Canvas2d(
Canvas2dMsg::SetStrokeStyle(gradient.r().to_fill_or_stroke_style()));
self.renderer.send(msg).unwrap();
self.ipc_renderer.send(msg).unwrap();
},
_ => {}
}
@ -893,8 +932,9 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
match parse_color(&string) {
Ok(rgba) => {
self.state.borrow_mut().fill_style = CanvasFillOrStrokeStyle::Color(rgba);
self.renderer
.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetFillStyle(FillOrStrokeStyle::Color(rgba))))
self.ipc_renderer
.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetFillStyle(
FillOrStrokeStyle::Color(rgba))))
.unwrap()
}
_ => {}
@ -905,10 +945,10 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
JS::from_rooted(&gradient));
let msg = CanvasMsg::Canvas2d(
Canvas2dMsg::SetFillStyle(gradient.r().to_fill_or_stroke_style()));
self.renderer.send(msg).unwrap();
self.ipc_renderer.send(msg).unwrap();
}
StringOrCanvasGradientOrCanvasPattern::eCanvasPattern(pattern) => {
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetFillStyle(
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetFillStyle(
pattern.r().to_fill_or_stroke_style()))).unwrap();
}
}
@ -947,12 +987,14 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
return Err(IndexSize)
}
let (sender, receiver) = channel::<Vec<u8>>();
let (sender, receiver) = ipc::channel::<Vec<u8>>().unwrap();
let dest_rect = Rect::new(Point2D::new(sx as f64, sy as f64),
Size2D::new(sw as f64, sh as f64));
let canvas_size = self.canvas.root().r().get_size();
let canvas_size = Size2D::new(canvas_size.width as f64, canvas_size.height as f64);
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::GetImageData(dest_rect, canvas_size, sender))).unwrap();
self.ipc_renderer
.send(CanvasMsg::Canvas2d(Canvas2dMsg::GetImageData(dest_rect, canvas_size, sender)))
.unwrap();
let data = receiver.recv().unwrap();
Ok(ImageData::new(self.global.root().r(), sw.abs().to_u32().unwrap(), sh.abs().to_u32().unwrap(), Some(data)))
}
@ -975,7 +1017,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
let image_data_rect = Rect::new(Point2D::new(dx, dy), image_data_size);
let dirty_rect = None;
let msg = CanvasMsg::Canvas2d(Canvas2dMsg::PutImageData(data, image_data_rect, dirty_rect));
self.renderer.send(msg).unwrap();
self.ipc_renderer.send(msg).unwrap();
self.mark_as_dirty();
}
@ -1003,7 +1045,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
let dirty_rect = Some(Rect::new(Point2D::new(dirtyX, dirtyY),
Size2D::new(dirtyWidth, dirtyHeight)));
let msg = CanvasMsg::Canvas2d(Canvas2dMsg::PutImageData(data, image_data_rect, dirty_rect));
self.renderer.send(msg).unwrap();
self.ipc_renderer.send(msg).unwrap();
self.mark_as_dirty();
}
@ -1106,7 +1148,9 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
self.state.borrow_mut().line_width = width;
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetLineWidth(width as f32))).unwrap()
self.ipc_renderer
.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetLineWidth(width as f32)))
.unwrap()
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-linecap
@ -1123,7 +1167,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
fn SetLineCap(self, cap_str: DOMString) {
if let Some(cap) = LineCapStyle::from_str(&cap_str) {
self.state.borrow_mut().line_cap = cap;
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetLineCap(cap))).unwrap()
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetLineCap(cap))).unwrap()
}
}
@ -1141,7 +1185,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
fn SetLineJoin(self, join_str: DOMString) {
if let Some(join) = LineJoinStyle::from_str(&join_str) {
self.state.borrow_mut().line_join = join;
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetLineJoin(join))).unwrap()
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetLineJoin(join))).unwrap()
}
}
@ -1158,7 +1202,9 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
self.state.borrow_mut().miter_limit = limit;
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetMiterLimit(limit as f32))).unwrap()
self.ipc_renderer
.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetMiterLimit(limit as f32)))
.unwrap()
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowoffsetx
@ -1172,7 +1218,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
return;
}
self.state.borrow_mut().shadow_offset_x = value;
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetShadowOffsetX(value))).unwrap()
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetShadowOffsetX(value))).unwrap()
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowoffsety
@ -1186,7 +1232,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
return;
}
self.state.borrow_mut().shadow_offset_y = value;
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetShadowOffsetY(value))).unwrap()
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetShadowOffsetY(value))).unwrap()
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowblur
@ -1200,7 +1246,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
return;
}
self.state.borrow_mut().shadow_blur = value;
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetShadowBlur(value))).unwrap()
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetShadowBlur(value))).unwrap()
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor
@ -1214,14 +1260,16 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
fn SetShadowColor(self, value: DOMString) {
if let Ok(color) = parse_color(&value) {
self.state.borrow_mut().shadow_color = color;
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetShadowColor(color))).unwrap()
self.ipc_renderer
.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetShadowColor(color)))
.unwrap()
}
}
}
impl Drop for CanvasRenderingContext2D {
fn drop(&mut self) {
self.renderer.send(CanvasMsg::Common(CanvasCommonMsg::Close)).unwrap();
self.ipc_renderer.send(CanvasMsg::Common(CanvasCommonMsg::Close)).unwrap();
}
}

View file

@ -24,7 +24,7 @@ use dom::workerglobalscope::WorkerGlobalScopeTypeId;
use script_task::{ScriptTask, ScriptChan, ScriptMsg, TimerSource, ScriptPort};
use script_task::StackRootTLS;
use msg::constellation_msg::PipelineId;
use msg::constellation_msg::{ConstellationChan, PipelineId};
use devtools_traits::DevtoolsControlChan;
@ -113,6 +113,7 @@ impl DedicatedWorkerGlobalScope {
devtools_chan: Option<DevtoolsControlChan>,
runtime: Rc<Runtime>,
resource_task: ResourceTask,
constellation_chan: ConstellationChan,
parent_sender: Box<ScriptChan+Send>,
own_sender: Sender<(TrustedWorkerAddress, ScriptMsg)>,
receiver: Receiver<(TrustedWorkerAddress, ScriptMsg)>)
@ -120,7 +121,7 @@ impl DedicatedWorkerGlobalScope {
DedicatedWorkerGlobalScope {
workerglobalscope: WorkerGlobalScope::new_inherited(
WorkerGlobalScopeTypeId::DedicatedGlobalScope, worker_url,
runtime, resource_task, mem_profiler_chan, devtools_chan),
runtime, resource_task, mem_profiler_chan, devtools_chan, constellation_chan),
id: id,
receiver: receiver,
own_sender: own_sender,
@ -135,13 +136,14 @@ impl DedicatedWorkerGlobalScope {
devtools_chan: Option<DevtoolsControlChan>,
runtime: Rc<Runtime>,
resource_task: ResourceTask,
constellation_chan: ConstellationChan,
parent_sender: Box<ScriptChan+Send>,
own_sender: Sender<(TrustedWorkerAddress, ScriptMsg)>,
receiver: Receiver<(TrustedWorkerAddress, ScriptMsg)>)
-> Root<DedicatedWorkerGlobalScope> {
let scope = box DedicatedWorkerGlobalScope::new_inherited(
worker_url, id, mem_profiler_chan, devtools_chan, runtime.clone(), resource_task,
parent_sender, own_sender, receiver);
constellation_chan, parent_sender, own_sender, receiver);
DedicatedWorkerGlobalScopeBinding::Wrap(runtime.cx(), scope)
}
}
@ -153,6 +155,7 @@ impl DedicatedWorkerGlobalScope {
devtools_chan: Option<DevtoolsControlChan>,
worker: TrustedWorkerAddress,
resource_task: ResourceTask,
constellation_chan: ConstellationChan,
parent_sender: Box<ScriptChan+Send>,
own_sender: Sender<(TrustedWorkerAddress, ScriptMsg)>,
receiver: Receiver<(TrustedWorkerAddress, ScriptMsg)>) {
@ -180,7 +183,7 @@ impl DedicatedWorkerGlobalScope {
let parent_sender_for_reporter = parent_sender.clone();
let global = DedicatedWorkerGlobalScope::new(
url, id, mem_profiler_chan.clone(), devtools_chan, runtime.clone(), resource_task,
parent_sender, own_sender, receiver);
constellation_chan, parent_sender, own_sender, receiver);
// FIXME(njn): workers currently don't have a unique ID suitable for using in reporter
// registration (#6631), so we instead use a random number and cross our fingers.
let reporter_name = format!("worker-reporter-{}", random::<u64>());

View file

@ -2,7 +2,6 @@
* 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;
use dom::attr::Attr;
use dom::attr::AttrHelpers;
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding;
@ -27,12 +26,13 @@ use dom::webglrenderingcontext::{WebGLRenderingContext, LayoutCanvasWebGLRenderi
use util::str::{DOMString, parse_unsigned_integer};
use js::jsapi::{JSContext, HandleValue};
use offscreen_gl_context::GLContextAttributes;
use canvas_traits::CanvasMsg;
use ipc_channel::ipc::IpcSender;
use euclid::size::Size2D;
use std::cell::Cell;
use std::default::Default;
use std::sync::mpsc::Sender;
const DEFAULT_WIDTH: u32 = 300;
const DEFAULT_HEIGHT: u32 = 150;
@ -106,7 +106,9 @@ impl HTMLCanvasElement {
pub trait LayoutHTMLCanvasElementHelpers {
#[allow(unsafe_code)]
unsafe fn get_renderer(&self) -> Option<Sender<CanvasMsg>>;
unsafe fn get_renderer_id(&self) -> Option<usize>;
#[allow(unsafe_code)]
unsafe fn get_ipc_renderer(&self) -> Option<IpcSender<CanvasMsg>>;
#[allow(unsafe_code)]
unsafe fn get_canvas_width(&self) -> u32;
#[allow(unsafe_code)]
@ -115,14 +117,25 @@ pub trait LayoutHTMLCanvasElementHelpers {
impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
#[allow(unsafe_code)]
unsafe fn get_renderer(&self) -> Option<Sender<CanvasMsg>> {
unsafe fn get_renderer_id(&self) -> Option<usize> {
let ref canvas = *self.unsafe_get();
if let Some(context) = canvas.context.get() {
match context {
CanvasContext::Context2d(context)
=> Some(context.to_layout().get_renderer()),
CanvasContext::WebGL(context)
=> Some(context.to_layout().get_renderer()),
CanvasContext::Context2d(context) => Some(context.to_layout().get_renderer_id()),
CanvasContext::WebGL(context) => Some(context.to_layout().get_renderer_id()),
}
} else {
None
}
}
#[allow(unsafe_code)]
unsafe fn get_ipc_renderer(&self) -> Option<IpcSender<CanvasMsg>> {
let ref canvas = *self.unsafe_get();
if let Some(context) = canvas.context.get() {
match context {
CanvasContext::Context2d(context) => Some(context.to_layout().get_ipc_renderer()),
CanvasContext::WebGL(context) => Some(context.to_layout().get_ipc_renderer()),
}
} else {
None

View file

@ -10,7 +10,7 @@ use dom::bindings::utils::reflect_dom_object;
use dom::webglobject::WebGLObject;
use canvas_traits::{CanvasMsg, CanvasWebGLMsg};
use std::sync::mpsc::{channel, Sender};
use ipc_channel::ipc::{self, IpcSender};
use std::cell::Cell;
#[dom_struct]
@ -18,11 +18,11 @@ pub struct WebGLBuffer {
webgl_object: WebGLObject,
id: u32,
is_deleted: Cell<bool>,
renderer: Sender<CanvasMsg>,
renderer: IpcSender<CanvasMsg>,
}
impl WebGLBuffer {
fn new_inherited(renderer: Sender<CanvasMsg>, id: u32) -> WebGLBuffer {
fn new_inherited(renderer: IpcSender<CanvasMsg>, id: u32) -> WebGLBuffer {
WebGLBuffer {
webgl_object: WebGLObject::new_inherited(),
id: id,
@ -31,15 +31,16 @@ impl WebGLBuffer {
}
}
pub fn maybe_new(global: GlobalRef, renderer: Sender<CanvasMsg>) -> Option<Root<WebGLBuffer>> {
let (sender, receiver) = channel();
pub fn maybe_new(global: GlobalRef, renderer: IpcSender<CanvasMsg>)
-> Option<Root<WebGLBuffer>> {
let (sender, receiver) = ipc::channel().unwrap();
renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateBuffer(sender))).unwrap();
let result = receiver.recv().unwrap();
result.map(|buffer_id| WebGLBuffer::new(global, renderer, *buffer_id))
}
pub fn new(global: GlobalRef, renderer: Sender<CanvasMsg>, id: u32) -> Root<WebGLBuffer> {
pub fn new(global: GlobalRef, renderer: IpcSender<CanvasMsg>, id: u32) -> Root<WebGLBuffer> {
reflect_dom_object(box WebGLBuffer::new_inherited(renderer, id), global, WebGLBufferBinding::Wrap)
}
}

View file

@ -10,7 +10,7 @@ use dom::bindings::utils::reflect_dom_object;
use dom::webglobject::WebGLObject;
use canvas_traits::{CanvasMsg, CanvasWebGLMsg, WebGLFramebufferBindingRequest};
use std::sync::mpsc::{channel, Sender};
use ipc_channel::ipc::{self, IpcSender};
use std::cell::Cell;
#[dom_struct]
@ -18,11 +18,11 @@ pub struct WebGLFramebuffer {
webgl_object: WebGLObject,
id: u32,
is_deleted: Cell<bool>,
renderer: Sender<CanvasMsg>,
renderer: IpcSender<CanvasMsg>,
}
impl WebGLFramebuffer {
fn new_inherited(renderer: Sender<CanvasMsg>, id: u32) -> WebGLFramebuffer {
fn new_inherited(renderer: IpcSender<CanvasMsg>, id: u32) -> WebGLFramebuffer {
WebGLFramebuffer {
webgl_object: WebGLObject::new_inherited(),
id: id,
@ -31,15 +31,17 @@ impl WebGLFramebuffer {
}
}
pub fn maybe_new(global: GlobalRef, renderer: Sender<CanvasMsg>) -> Option<Root<WebGLFramebuffer>> {
let (sender, receiver) = channel();
pub fn maybe_new(global: GlobalRef, renderer: IpcSender<CanvasMsg>)
-> Option<Root<WebGLFramebuffer>> {
let (sender, receiver) = ipc::channel().unwrap();
renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateFramebuffer(sender))).unwrap();
let result = receiver.recv().unwrap();
result.map(|fb_id| WebGLFramebuffer::new(global, renderer, *fb_id))
}
pub fn new(global: GlobalRef, renderer: Sender<CanvasMsg>, id: u32) -> Root<WebGLFramebuffer> {
pub fn new(global: GlobalRef, renderer: IpcSender<CanvasMsg>, id: u32)
-> Root<WebGLFramebuffer> {
reflect_dom_object(box WebGLFramebuffer::new_inherited(renderer, id), global, WebGLFramebufferBinding::Wrap)
}
}

View file

@ -14,7 +14,7 @@ use dom::webglrenderingcontext::MAX_UNIFORM_AND_ATTRIBUTE_LEN;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
use canvas_traits::{CanvasMsg, CanvasWebGLMsg, WebGLResult, WebGLError};
use std::sync::mpsc::{channel, Sender};
use ipc_channel::ipc::{self, IpcSender};
use std::cell::Cell;
#[dom_struct]
@ -24,11 +24,11 @@ pub struct WebGLProgram {
is_deleted: Cell<bool>,
fragment_shader: MutNullableHeap<JS<WebGLShader>>,
vertex_shader: MutNullableHeap<JS<WebGLShader>>,
renderer: Sender<CanvasMsg>,
renderer: IpcSender<CanvasMsg>,
}
impl WebGLProgram {
fn new_inherited(renderer: Sender<CanvasMsg>, id: u32) -> WebGLProgram {
fn new_inherited(renderer: IpcSender<CanvasMsg>, id: u32) -> WebGLProgram {
WebGLProgram {
webgl_object: WebGLObject::new_inherited(),
id: id,
@ -39,15 +39,16 @@ impl WebGLProgram {
}
}
pub fn maybe_new(global: GlobalRef, renderer: Sender<CanvasMsg>) -> Option<Root<WebGLProgram>> {
let (sender, receiver) = channel();
pub fn maybe_new(global: GlobalRef, renderer: IpcSender<CanvasMsg>)
-> Option<Root<WebGLProgram>> {
let (sender, receiver) = ipc::channel().unwrap();
renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateProgram(sender))).unwrap();
let result = receiver.recv().unwrap();
result.map(|program_id| WebGLProgram::new(global, renderer, *program_id))
}
pub fn new(global: GlobalRef, renderer: Sender<CanvasMsg>, id: u32) -> Root<WebGLProgram> {
pub fn new(global: GlobalRef, renderer: IpcSender<CanvasMsg>, id: u32) -> Root<WebGLProgram> {
reflect_dom_object(box WebGLProgram::new_inherited(renderer, id), global, WebGLProgramBinding::Wrap)
}
}
@ -112,7 +113,7 @@ impl<'a> WebGLProgramHelpers for &'a WebGLProgram {
return Ok(None);
}
let (sender, receiver) = channel();
let (sender, receiver) = ipc::channel().unwrap();
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::GetAttribLocation(self.id, name, sender))).unwrap();
Ok(receiver.recv().unwrap())
}
@ -128,7 +129,7 @@ impl<'a> WebGLProgramHelpers for &'a WebGLProgram {
return Ok(None);
}
let (sender, receiver) = channel();
let (sender, receiver) = ipc::channel().unwrap();
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::GetUniformLocation(self.id, name, sender))).unwrap();
Ok(receiver.recv().unwrap())
}

View file

@ -10,7 +10,7 @@ use dom::bindings::utils::reflect_dom_object;
use dom::webglobject::WebGLObject;
use canvas_traits::{CanvasMsg, CanvasWebGLMsg};
use std::sync::mpsc::{channel, Sender};
use ipc_channel::ipc::{self, IpcSender};
use std::cell::Cell;
#[dom_struct]
@ -18,11 +18,11 @@ pub struct WebGLRenderbuffer {
webgl_object: WebGLObject,
id: u32,
is_deleted: Cell<bool>,
renderer: Sender<CanvasMsg>,
renderer: IpcSender<CanvasMsg>,
}
impl WebGLRenderbuffer {
fn new_inherited(renderer: Sender<CanvasMsg>, id: u32) -> WebGLRenderbuffer {
fn new_inherited(renderer: IpcSender<CanvasMsg>, id: u32) -> WebGLRenderbuffer {
WebGLRenderbuffer {
webgl_object: WebGLObject::new_inherited(),
id: id,
@ -31,15 +31,17 @@ impl WebGLRenderbuffer {
}
}
pub fn maybe_new(global: GlobalRef, renderer: Sender<CanvasMsg>) -> Option<Root<WebGLRenderbuffer>> {
let (sender, receiver) = channel();
pub fn maybe_new(global: GlobalRef, renderer: IpcSender<CanvasMsg>)
-> Option<Root<WebGLRenderbuffer>> {
let (sender, receiver) = ipc::channel().unwrap();
renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateRenderbuffer(sender))).unwrap();
let result = receiver.recv().unwrap();
result.map(|renderbuffer_id| WebGLRenderbuffer::new(global, renderer, *renderbuffer_id))
}
pub fn new(global: GlobalRef, renderer: Sender<CanvasMsg>, id: u32) -> Root<WebGLRenderbuffer> {
pub fn new(global: GlobalRef, renderer: IpcSender<CanvasMsg>, id: u32)
-> Root<WebGLRenderbuffer> {
reflect_dom_object(box WebGLRenderbuffer::new_inherited(renderer, id), global, WebGLRenderbufferBinding::Wrap)
}
}

View file

@ -2,7 +2,6 @@
* 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::webgl_paint_task::WebGLPaintTask;
use canvas_traits::
{CanvasMsg, CanvasWebGLMsg, CanvasCommonMsg, WebGLError,
WebGLShaderParameter, WebGLFramebufferBindingRequest};
@ -23,14 +22,16 @@ use dom::webglshader::{WebGLShader, WebGLShaderHelpers};
use dom::webglprogram::{WebGLProgram, WebGLProgramHelpers};
use dom::webgluniformlocation::{WebGLUniformLocation, WebGLUniformLocationHelpers};
use euclid::size::Size2D;
use ipc_channel::ipc::{self, IpcSender};
use js::jsapi::{JSContext, JSObject, RootedValue};
use js::jsapi::{JS_GetFloat32ArrayData, JS_GetObjectAsArrayBufferView};
use js::jsval::{JSVal, UndefinedValue, NullValue, Int32Value, BooleanValue};
use msg::constellation_msg::Msg as ConstellationMsg;
use std::cell::Cell;
use std::mem;
use std::ptr;
use std::slice;
use std::sync::mpsc::{channel, Sender};
use std::sync::mpsc::channel;
use util::str::DOMString;
use offscreen_gl_context::GLContextAttributes;
@ -52,7 +53,8 @@ macro_rules! handle_potential_webgl_error {
pub struct WebGLRenderingContext {
reflector_: Reflector,
global: GlobalField,
renderer: Sender<CanvasMsg>,
renderer_id: usize,
ipc_renderer: IpcSender<CanvasMsg>,
canvas: JS<HTMLCanvasElement>,
last_error: Cell<Option<WebGLError>>,
}
@ -63,12 +65,17 @@ impl WebGLRenderingContext {
size: Size2D<i32>,
attrs: GLContextAttributes)
-> Result<WebGLRenderingContext, &'static str> {
let chan = try!(WebGLPaintTask::start(size, attrs));
let (sender, receiver) = ipc::channel().unwrap();
let constellation_chan = global.constellation_chan();
constellation_chan.0
.send(ConstellationMsg::CreateWebGLPaintTask(size, attrs, sender))
.unwrap();
let (ipc_renderer, renderer_id) = receiver.recv().unwrap();
Ok(WebGLRenderingContext {
reflector_: Reflector::new(),
global: GlobalField::from_rooted(&global),
renderer: chan,
renderer_id: renderer_id,
ipc_renderer: ipc_renderer,
last_error: Cell::new(None),
canvas: JS::from_ref(canvas),
})
@ -87,13 +94,13 @@ impl WebGLRenderingContext {
}
pub fn recreate(&self, size: Size2D<i32>) {
self.renderer.send(CanvasMsg::Common(CanvasCommonMsg::Recreate(size))).unwrap();
self.ipc_renderer.send(CanvasMsg::Common(CanvasCommonMsg::Recreate(size))).unwrap();
}
}
impl Drop for WebGLRenderingContext {
fn drop(&mut self) {
self.renderer.send(CanvasMsg::Common(CanvasCommonMsg::Close)).unwrap();
self.ipc_renderer.send(CanvasMsg::Common(CanvasCommonMsg::Close)).unwrap();
}
}
@ -105,15 +112,19 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.1
fn DrawingBufferWidth(self) -> i32 {
let (sender, receiver) = channel();
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DrawingBufferWidth(sender))).unwrap();
let (sender, receiver) = ipc::channel().unwrap();
self.ipc_renderer
.send(CanvasMsg::WebGL(CanvasWebGLMsg::DrawingBufferWidth(sender)))
.unwrap();
receiver.recv().unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.1
fn DrawingBufferHeight(self) -> i32 {
let (sender, receiver) = channel();
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DrawingBufferHeight(sender))).unwrap();
let (sender, receiver) = ipc::channel().unwrap();
self.ipc_renderer
.send(CanvasMsg::WebGL(CanvasWebGLMsg::DrawingBufferHeight(sender)))
.unwrap();
receiver.recv().unwrap()
}
@ -151,10 +162,11 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.2
fn GetContextAttributes(self) -> Option<WebGLContextAttributes> {
let (sender, receiver) = channel();
let (sender, receiver) = ipc::channel().unwrap();
// If the send does not succeed, assume context lost
if let Err(_) = self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::GetContextAttributes(sender))) {
if let Err(_) = self.ipc_renderer
.send(CanvasMsg::WebGL(CanvasWebGLMsg::GetContextAttributes(sender))) {
return None;
}
let attrs = receiver.recv().unwrap();
@ -180,32 +192,36 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn ActiveTexture(self, texture: u32) {
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::ActiveTexture(texture))).unwrap();
self.ipc_renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::ActiveTexture(texture))).unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn BlendColor(self, r: f32, g: f32, b: f32, a: f32) {
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BlendColor(r, g, b, a))).unwrap();
self.ipc_renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BlendColor(r, g, b, a))).unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn BlendEquation(self, mode: u32) {
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BlendEquation(mode))).unwrap();
self.ipc_renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BlendEquation(mode))).unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn BlendEquationSeparate(self, mode_rgb: u32, mode_alpha: u32) {
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BlendEquationSeparate(mode_rgb, mode_alpha))).unwrap();
self.ipc_renderer
.send(CanvasMsg::WebGL(CanvasWebGLMsg::BlendEquationSeparate(mode_rgb, mode_alpha)))
.unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn BlendFunc(self, src_factor: u32, dest_factor: u32) {
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BlendFunc(src_factor, dest_factor))).unwrap();
self.ipc_renderer
.send(CanvasMsg::WebGL(CanvasWebGLMsg::BlendFunc(src_factor, dest_factor)))
.unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn BlendFuncSeparate(self, src_rgb: u32, dest_rgb: u32, src_alpha: u32, dest_alpha: u32) {
self.renderer.send(
self.ipc_renderer.send(
CanvasMsg::WebGL(CanvasWebGLMsg::BlendFuncSeparate(src_rgb, dest_rgb, src_alpha, dest_alpha))).unwrap();
}
@ -224,7 +240,9 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
buffer.bind(target)
} else {
// Unbind the current buffer
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BindBuffer(target, 0))).unwrap()
self.ipc_renderer
.send(CanvasMsg::WebGL(CanvasWebGLMsg::BindBuffer(target, 0)))
.unwrap()
}
}
@ -235,7 +253,7 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
} else {
// Bind the default framebuffer
let cmd = CanvasWebGLMsg::BindFramebuffer(target, WebGLFramebufferBindingRequest::Default);
self.renderer.send(CanvasMsg::WebGL(cmd)).unwrap();
self.ipc_renderer.send(CanvasMsg::WebGL(cmd)).unwrap();
}
}
@ -245,7 +263,9 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
renderbuffer.bind(target)
} else {
// Unbind the currently bound renderbuffer
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BindRenderbuffer(target, 0))).unwrap()
self.ipc_renderer
.send(CanvasMsg::WebGL(CanvasWebGLMsg::BindRenderbuffer(target, 0)))
.unwrap()
}
}
@ -274,17 +294,21 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
let data_vec_length = length / mem::size_of::<f32>() as u32;
slice::from_raw_parts(data_f32, data_vec_length as usize).to_vec()
};
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BufferData(target, data_vec, usage))).unwrap()
self.ipc_renderer
.send(CanvasMsg::WebGL(CanvasWebGLMsg::BufferData(target, data_vec, usage)))
.unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.11
fn Clear(self, mask: u32) {
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::Clear(mask))).unwrap()
self.ipc_renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::Clear(mask))).unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn ClearColor(self, red: f32, green: f32, blue: f32, alpha: f32) {
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::ClearColor(red, green, blue, alpha))).unwrap()
self.ipc_renderer
.send(CanvasMsg::WebGL(CanvasWebGLMsg::ClearColor(red, green, blue, alpha)))
.unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
@ -298,34 +322,34 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
// generated objects, either here or in the webgl task
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
fn CreateBuffer(self) -> Option<Root<WebGLBuffer>> {
WebGLBuffer::maybe_new(self.global.root().r(), self.renderer.clone())
WebGLBuffer::maybe_new(self.global.root().r(), self.ipc_renderer.clone())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6
fn CreateFramebuffer(self) -> Option<Root<WebGLFramebuffer>> {
WebGLFramebuffer::maybe_new(self.global.root().r(), self.renderer.clone())
WebGLFramebuffer::maybe_new(self.global.root().r(), self.ipc_renderer.clone())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7
fn CreateRenderbuffer(self) -> Option<Root<WebGLRenderbuffer>> {
WebGLRenderbuffer::maybe_new(self.global.root().r(), self.renderer.clone())
WebGLRenderbuffer::maybe_new(self.global.root().r(), self.ipc_renderer.clone())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
fn CreateTexture(self) -> Option<Root<WebGLTexture>> {
WebGLTexture::maybe_new(self.global.root().r(), self.renderer.clone())
WebGLTexture::maybe_new(self.global.root().r(), self.ipc_renderer.clone())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
fn CreateProgram(self) -> Option<Root<WebGLProgram>> {
WebGLProgram::maybe_new(self.global.root().r(), self.renderer.clone())
WebGLProgram::maybe_new(self.global.root().r(), self.ipc_renderer.clone())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
// TODO(ecoal95): Check if constants are cross-platform or if we must make a translation
// between WebGL constants and native ones.
fn CreateShader(self, shader_type: u32) -> Option<Root<WebGLShader>> {
WebGLShader::maybe_new(self.global.root().r(), self.renderer.clone(), shader_type)
WebGLShader::maybe_new(self.global.root().r(), self.ipc_renderer.clone(), shader_type)
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
@ -372,12 +396,16 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.11
fn DrawArrays(self, mode: u32, first: i32, count: i32) {
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DrawArrays(mode, first, count))).unwrap()
self.ipc_renderer
.send(CanvasMsg::WebGL(CanvasWebGLMsg::DrawArrays(mode, first, count)))
.unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
fn EnableVertexAttribArray(self, attrib_id: u32) {
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::EnableVertexAttribArray(attrib_id))).unwrap()
self.ipc_renderer
.send(CanvasMsg::WebGL(CanvasWebGLMsg::EnableVertexAttribArray(attrib_id)))
.unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@ -466,7 +494,9 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
let data_f32 = JS_GetFloat32ArrayData(data, ptr::null());
slice::from_raw_parts(data_f32, 4).to_vec()
};
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::Uniform4fv(uniform_id, data_vec))).unwrap()
self.ipc_renderer
.send(CanvasMsg::WebGL(CanvasWebGLMsg::Uniform4fv(uniform_id, data_vec)))
.unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
@ -483,7 +513,7 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
constants::FLOAT => {
let msg = CanvasMsg::WebGL(
CanvasWebGLMsg::VertexAttribPointer2f(attrib_id, size, normalized, stride, offset));
self.renderer.send(msg).unwrap()
self.ipc_renderer.send(msg).unwrap()
}
_ => panic!("VertexAttribPointer: Data Type not supported")
}
@ -492,7 +522,9 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.4
fn Viewport(self, x: i32, y: i32, width: i32, height: i32) {
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::Viewport(x, y, width, height))).unwrap()
self.ipc_renderer
.send(CanvasMsg::WebGL(CanvasWebGLMsg::Viewport(x, y, width, height)))
.unwrap()
}
}
@ -512,12 +544,18 @@ impl<'a> WebGLRenderingContextHelpers for &'a WebGLRenderingContext {
pub trait LayoutCanvasWebGLRenderingContextHelpers {
#[allow(unsafe_code)]
unsafe fn get_renderer(&self) -> Sender<CanvasMsg>;
unsafe fn get_renderer_id(&self) -> usize;
#[allow(unsafe_code)]
unsafe fn get_ipc_renderer(&self) -> IpcSender<CanvasMsg>;
}
impl LayoutCanvasWebGLRenderingContextHelpers for LayoutJS<WebGLRenderingContext> {
#[allow(unsafe_code)]
unsafe fn get_renderer(&self) -> Sender<CanvasMsg> {
(*self.unsafe_get()).renderer.clone()
unsafe fn get_renderer_id(&self) -> usize {
(*self.unsafe_get()).renderer_id
}
#[allow(unsafe_code)]
unsafe fn get_ipc_renderer(&self) -> IpcSender<CanvasMsg> {
(*self.unsafe_get()).ipc_renderer.clone()
}
}

View file

@ -12,7 +12,7 @@ use dom::webglobject::WebGLObject;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
use canvas_traits::{CanvasMsg, CanvasWebGLMsg, WebGLResult, WebGLError, WebGLShaderParameter};
use std::sync::mpsc::{channel, Sender};
use ipc_channel::ipc::{self, IpcSender};
use std::cell::Cell;
use std::cell::RefCell;
@ -24,11 +24,11 @@ pub struct WebGLShader {
source: RefCell<Option<String>>,
is_deleted: Cell<bool>,
// TODO(ecoal95): Evaluate moving this to `WebGLObject`
renderer: Sender<CanvasMsg>,
renderer: IpcSender<CanvasMsg>,
}
impl WebGLShader {
fn new_inherited(renderer: Sender<CanvasMsg>, id: u32, shader_type: u32) -> WebGLShader {
fn new_inherited(renderer: IpcSender<CanvasMsg>, id: u32, shader_type: u32) -> WebGLShader {
WebGLShader {
webgl_object: WebGLObject::new_inherited(),
id: id,
@ -40,9 +40,9 @@ impl WebGLShader {
}
pub fn maybe_new(global: GlobalRef,
renderer: Sender<CanvasMsg>,
renderer: IpcSender<CanvasMsg>,
shader_type: u32) -> Option<Root<WebGLShader>> {
let (sender, receiver) = channel();
let (sender, receiver) = ipc::channel().unwrap();
renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateShader(shader_type, sender))).unwrap();
let result = receiver.recv().unwrap();
@ -50,7 +50,7 @@ impl WebGLShader {
}
pub fn new(global: GlobalRef,
renderer: Sender<CanvasMsg>,
renderer: IpcSender<CanvasMsg>,
id: u32,
shader_type: u32) -> Root<WebGLShader> {
reflect_dom_object(
@ -95,7 +95,7 @@ impl<'a> WebGLShaderHelpers for &'a WebGLShader {
/// glGetShaderInfoLog
fn info_log(self) -> Option<String> {
let (sender, receiver) = channel();
let (sender, receiver) = ipc::channel().unwrap();
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::GetShaderInfoLog(self.id, sender))).unwrap();
receiver.recv().unwrap()
}
@ -107,7 +107,7 @@ impl<'a> WebGLShaderHelpers for &'a WebGLShader {
_ => return Err(WebGLError::InvalidEnum),
}
let (sender, receiver) = channel();
let (sender, receiver) = ipc::channel().unwrap();
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::GetShaderParameter(self.id, param_id, sender))).unwrap();
Ok(receiver.recv().unwrap())
}

View file

@ -10,7 +10,7 @@ use dom::bindings::utils::reflect_dom_object;
use dom::webglobject::WebGLObject;
use canvas_traits::{CanvasMsg, CanvasWebGLMsg};
use std::sync::mpsc::{channel, Sender};
use ipc_channel::ipc::{self, IpcSender};
use std::cell::Cell;
#[dom_struct]
@ -18,11 +18,11 @@ pub struct WebGLTexture {
webgl_object: WebGLObject,
id: u32,
is_deleted: Cell<bool>,
renderer: Sender<CanvasMsg>,
renderer: IpcSender<CanvasMsg>,
}
impl WebGLTexture {
fn new_inherited(renderer: Sender<CanvasMsg>, id: u32) -> WebGLTexture {
fn new_inherited(renderer: IpcSender<CanvasMsg>, id: u32) -> WebGLTexture {
WebGLTexture {
webgl_object: WebGLObject::new_inherited(),
id: id,
@ -31,15 +31,16 @@ impl WebGLTexture {
}
}
pub fn maybe_new(global: GlobalRef, renderer: Sender<CanvasMsg>) -> Option<Root<WebGLTexture>> {
let (sender, receiver) = channel();
pub fn maybe_new(global: GlobalRef, renderer: IpcSender<CanvasMsg>)
-> Option<Root<WebGLTexture>> {
let (sender, receiver) = ipc::channel().unwrap();
renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateTexture(sender))).unwrap();
let result = receiver.recv().unwrap();
result.map(|texture_id| WebGLTexture::new(global, renderer, *texture_id))
}
pub fn new(global: GlobalRef, renderer: Sender<CanvasMsg>, id: u32) -> Root<WebGLTexture> {
pub fn new(global: GlobalRef, renderer: IpcSender<CanvasMsg>, id: u32) -> Root<WebGLTexture> {
reflect_dom_object(box WebGLTexture::new_inherited(renderer, id), global, WebGLTextureBinding::Wrap)
}
}

View file

@ -70,6 +70,7 @@ impl Worker {
};
let resource_task = global.resource_task();
let constellation_chan = global.constellation_chan();
let (sender, receiver) = channel();
let worker = Worker::new(global, sender.clone());
@ -91,7 +92,7 @@ impl Worker {
DedicatedWorkerGlobalScope::run_worker_scope(
worker_url, global.pipeline(), global.mem_profiler_chan(), global.devtools_chan(),
worker_ref, resource_task, global.script_chan(), sender, receiver);
worker_ref, resource_task, constellation_chan, global.script_chan(), sender, receiver);
Ok(worker)
}

View file

@ -22,7 +22,7 @@ use timers::{IsInterval, TimerId, TimerManager, TimerCallback};
use devtools_traits::DevtoolsControlChan;
use msg::constellation_msg::{PipelineId, WorkerId};
use msg::constellation_msg::{ConstellationChan, PipelineId, WorkerId};
use profile_traits::mem;
use net_traits::{load_whole_resource, ResourceTask};
use util::str::DOMString;
@ -55,6 +55,7 @@ pub struct WorkerGlobalScope {
timers: TimerManager,
mem_profiler_chan: mem::ProfilerChan,
devtools_chan: Option<DevtoolsControlChan>,
constellation_chan: ConstellationChan,
}
impl WorkerGlobalScope {
@ -63,7 +64,8 @@ impl WorkerGlobalScope {
runtime: Rc<Runtime>,
resource_task: ResourceTask,
mem_profiler_chan: mem::ProfilerChan,
devtools_chan: Option<DevtoolsControlChan>) -> WorkerGlobalScope {
devtools_chan: Option<DevtoolsControlChan>,
constellation_chan: ConstellationChan) -> WorkerGlobalScope {
WorkerGlobalScope {
eventtarget: EventTarget::new_inherited(EventTargetTypeId::WorkerGlobalScope(type_id)),
next_worker_id: Cell::new(WorkerId(0)),
@ -77,6 +79,7 @@ impl WorkerGlobalScope {
timers: TimerManager::new(),
mem_profiler_chan: mem_profiler_chan,
devtools_chan: devtools_chan,
constellation_chan: constellation_chan,
}
}
@ -88,6 +91,10 @@ impl WorkerGlobalScope {
self.devtools_chan.clone()
}
pub fn constellation_chan(&self) -> ConstellationChan {
self.constellation_chan.clone()
}
#[inline]
pub fn eventtarget<'a>(&'a self) -> &'a EventTarget {
&self.eventtarget