diff options
author | Patrick Walton <pcwalton@mimiga.net> | 2015-07-13 17:02:35 -0700 |
---|---|---|
committer | Patrick Walton <pcwalton@mimiga.net> | 2015-07-25 00:50:12 -0700 |
commit | bb99b2f3c8813919c476930c709b73d3cfbc8c83 (patch) | |
tree | 15641e7ed77b46ab61bab772fa3c63b7e8e8d619 /components/script/dom | |
parent | 886c08c393f51499490702eaf97fc770273a2600 (diff) | |
download | servo-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/script/dom')
-rw-r--r-- | components/script/dom/bindings/global.rs | 10 | ||||
-rw-r--r-- | components/script/dom/bindings/trace.rs | 8 | ||||
-rw-r--r-- | components/script/dom/canvasrenderingcontext2d.rs | 170 | ||||
-rw-r--r-- | components/script/dom/dedicatedworkerglobalscope.rs | 11 | ||||
-rw-r--r-- | components/script/dom/htmlcanvaselement.rs | 29 | ||||
-rw-r--r-- | components/script/dom/webglbuffer.rs | 13 | ||||
-rw-r--r-- | components/script/dom/webglframebuffer.rs | 14 | ||||
-rw-r--r-- | components/script/dom/webglprogram.rs | 17 | ||||
-rw-r--r-- | components/script/dom/webglrenderbuffer.rs | 14 | ||||
-rw-r--r-- | components/script/dom/webglrenderingcontext.rs | 118 | ||||
-rw-r--r-- | components/script/dom/webglshader.rs | 16 | ||||
-rw-r--r-- | components/script/dom/webgltexture.rs | 13 | ||||
-rw-r--r-- | components/script/dom/worker.rs | 3 | ||||
-rw-r--r-- | components/script/dom/workerglobalscope.rs | 11 |
14 files changed, 286 insertions, 161 deletions
diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs index 85dd955628b..5335db1d928 100644 --- a/components/script/dom/bindings/global.rs +++ b/components/script/dom/bindings/global.rs @@ -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> { diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 079f1ecbafc..a2c82b80722 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -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,21 +332,21 @@ impl<A,B> JSTraceable for fn(A) -> B { } } -impl JSTraceable for ScriptListener { +impl<T> JSTraceable for IpcSender<T> where T: Deserialize + Serialize { #[inline] fn trace(&self, _: *mut JSTracer) { // Do nothing } } -impl JSTraceable for Box<LayoutRPC+'static> { +impl JSTraceable for ScriptListener { #[inline] fn trace(&self, _: *mut JSTracer) { // Do nothing } } -impl<T> JSTraceable for IpcSender<T> where T: Serialize { +impl JSTraceable for Box<LayoutRPC+'static> { #[inline] fn trace(&self, _: *mut JSTracer) { // Do nothing diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index 4d9ea26c6b7..671177f95db 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -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(); } } diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs index cf8c22f81d7..6c27b895906 100644 --- a/components/script/dom/dedicatedworkerglobalscope.rs +++ b/components/script/dom/dedicatedworkerglobalscope.rs @@ -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>()); diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index a01a2c4fe26..3c52d99ea4f 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -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_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_renderer()), - CanvasContext::WebGL(context) - => Some(context.to_layout().get_renderer()), + CanvasContext::Context2d(context) => Some(context.to_layout().get_ipc_renderer()), + CanvasContext::WebGL(context) => Some(context.to_layout().get_ipc_renderer()), } } else { None diff --git a/components/script/dom/webglbuffer.rs b/components/script/dom/webglbuffer.rs index 4970b577bb7..432caf6276c 100644 --- a/components/script/dom/webglbuffer.rs +++ b/components/script/dom/webglbuffer.rs @@ -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) } } diff --git a/components/script/dom/webglframebuffer.rs b/components/script/dom/webglframebuffer.rs index 26773ca4b17..2a67bb4dbcb 100644 --- a/components/script/dom/webglframebuffer.rs +++ b/components/script/dom/webglframebuffer.rs @@ -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) } } diff --git a/components/script/dom/webglprogram.rs b/components/script/dom/webglprogram.rs index 71e0d2e6616..a61fc22c905 100644 --- a/components/script/dom/webglprogram.rs +++ b/components/script/dom/webglprogram.rs @@ -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()) } diff --git a/components/script/dom/webglrenderbuffer.rs b/components/script/dom/webglrenderbuffer.rs index d7084564ec3..cfe3fb21261 100644 --- a/components/script/dom/webglrenderbuffer.rs +++ b/components/script/dom/webglrenderbuffer.rs @@ -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) } } diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 123c1e200c3..4dcd1705782 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -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() } } diff --git a/components/script/dom/webglshader.rs b/components/script/dom/webglshader.rs index f5d40b16699..40c26d40c90 100644 --- a/components/script/dom/webglshader.rs +++ b/components/script/dom/webglshader.rs @@ -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()) } diff --git a/components/script/dom/webgltexture.rs b/components/script/dom/webgltexture.rs index ab934a5f47d..06664a01f3d 100644 --- a/components/script/dom/webgltexture.rs +++ b/components/script/dom/webgltexture.rs @@ -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) } } diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs index 257ecbdcef1..26fd1ff7421 100644 --- a/components/script/dom/worker.rs +++ b/components/script/dom/worker.rs @@ -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) } diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index 260476859e9..8d473f6f081 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -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 |