diff options
Diffstat (limited to 'components/script/dom')
25 files changed, 564 insertions, 454 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..ad8da0e41b0 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -62,14 +62,15 @@ 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; use std::ffi::CString; use std::hash::{Hash, Hasher}; use std::intrinsics::return_address; +use std::mem; use std::ops::{Deref, DerefMut}; use std::rc::Rc; use std::sync::Arc; @@ -332,21 +333,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 @@ -482,6 +483,13 @@ impl<T: JSTraceable + Reflectable> RootedVec<T> { } } +impl<T: JSTraceable + Reflectable> RootedVec<JS<T>> { + /// Obtain a safe slice of references that can't outlive that RootedVec. + pub fn r(&self) -> &[&T] { + unsafe { mem::transmute(&*self.v) } + } +} + impl<T: JSTraceable + Reflectable> Drop for RootedVec<T> { fn drop(&mut self) { RootedTraceableSet::remove(self); 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 b298f37bee1..6c27b895906 100644 --- a/components/script/dom/dedicatedworkerglobalscope.rs +++ b/components/script/dom/dedicatedworkerglobalscope.rs @@ -24,16 +24,18 @@ 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; use net_traits::{load_whole_resource, ResourceTask}; -use profile_traits::mem::{self, Reporter, ReportsChan}; +use profile_traits::mem::{self, Reporter, ReporterRequest}; use util::task::spawn_named; use util::task_state; use util::task_state::{SCRIPT, IN_WORKER}; +use ipc_channel::ipc; +use ipc_channel::router::ROUTER; use js::jsapi::{JSContext, RootedValue, HandleValue}; use js::jsapi::{JSAutoRequest, JSAutoCompartment}; use js::jsval::UndefinedValue; @@ -66,13 +68,6 @@ impl ScriptChan for SendableWorkerScriptChan { } } -impl Reporter for SendableWorkerScriptChan { - // Just injects an appropriate event into the worker task's queue. - fn collect_reports(&self, reports_chan: ReportsChan) -> bool { - self.send(ScriptMsg::CollectReports(reports_chan)).is_ok() - } -} - /// Set the `worker` field of a related DedicatedWorkerGlobalScope object to a particular /// value for the duration of this object's lifetime. This ensures that the related Worker /// object only lives as long as necessary (ie. while events are being executed), while @@ -118,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)>) @@ -125,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, @@ -140,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) } } @@ -158,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)>) { @@ -182,9 +180,10 @@ impl DedicatedWorkerGlobalScope { let runtime = Rc::new(ScriptTask::new_rt_and_cx()); let serialized_url = url.serialize(); + 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>()); @@ -206,9 +205,16 @@ impl DedicatedWorkerGlobalScope { // Register this task as a memory reporter. This needs to be done within the // scope of `_ar` otherwise script_chan_as_reporter() will panic. - let reporter = global.script_chan_as_reporter(); - let msg = mem::ProfilerMsg::RegisterReporter(reporter_name.clone(), reporter); - mem_profiler_chan.send(msg); + let (reporter_sender, reporter_receiver) = ipc::channel().unwrap(); + ROUTER.add_route(reporter_receiver.to_opaque(), box move |reporter_request| { + // Just injects an appropriate event into the worker task's queue. + let reporter_request: ReporterRequest = reporter_request.to().unwrap(); + parent_sender_for_reporter.send(ScriptMsg::CollectReports( + reporter_request.reports_channel)).unwrap() + }); + mem_profiler_chan.send(mem::ProfilerMsg::RegisterReporter( + reporter_name.clone(), + Reporter(reporter_sender))); } loop { @@ -230,7 +236,6 @@ impl DedicatedWorkerGlobalScope { pub trait DedicatedWorkerGlobalScopeHelpers { fn script_chan(self) -> Box<ScriptChan+Send>; - fn script_chan_as_reporter(self) -> Box<Reporter+Send>; fn pipeline(self) -> PipelineId; fn new_script_pair(self) -> (Box<ScriptChan+Send>, Box<ScriptPort+Send>); fn process_event(self, msg: ScriptMsg); @@ -244,14 +249,6 @@ impl<'a> DedicatedWorkerGlobalScopeHelpers for &'a DedicatedWorkerGlobalScope { } } - fn script_chan_as_reporter(self) -> Box<Reporter+Send> { - box SendableWorkerScriptChan { - sender: self.own_sender.clone(), - worker: self.worker.borrow().as_ref().unwrap().clone(), - } - } - - fn pipeline(self) -> PipelineId { self.id } diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index d074dca0d4e..0e494b79a89 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -733,15 +733,13 @@ impl<'a> DocumentHelpers<'a> for &'a Document { // Set hover state for any elements in the current mouse over list. // Check if any of them changed state to determine whether to // force a reflow below. - for target in mouse_over_targets.iter() { - let target = target.root(); - let target_ref = target.r(); - if !target_ref.get_hover_state() { - target_ref.set_hover_state(true); + for target in mouse_over_targets.r() { + if !target.get_hover_state() { + target.set_hover_state(true); - let target = EventTargetCast::from_ref(target_ref); + let target = EventTargetCast::from_ref(*target); - self.fire_mouse_event(point, &target, "mouseover".to_owned()); + self.fire_mouse_event(point, target, "mouseover".to_owned()); } } diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 0fb55d0ff82..dd6afd3061b 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -866,9 +866,9 @@ impl<'a> AttributeHandlers for &'a Element { fn get_attribute(self, namespace: &Namespace, local_name: &Atom) -> Option<Root<Attr>> { let mut attributes = RootedVec::new(); self.get_attributes(local_name, &mut attributes); - attributes.iter() - .map(|attr| attr.root()) - .find(|attr| attr.r().namespace() == namespace) + attributes.r().iter() + .find(|attr| attr.namespace() == namespace) + .map(|attr| Root::from_ref(*attr)) } // https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name diff --git a/components/script/dom/eventdispatcher.rs b/components/script/dom/eventdispatcher.rs index 8633f63df7c..0c6c7e14b18 100644 --- a/components/script/dom/eventdispatcher.rs +++ b/components/script/dom/eventdispatcher.rs @@ -41,14 +41,13 @@ pub fn dispatch_event<'a, 'b>(target: &'a EventTarget, //FIXME: The "callback this value" should be currentTarget /* capturing */ - for cur_target in chain.iter().rev() { - let cur_target = cur_target.root(); - let stopped = match cur_target.r().get_listeners_for(&type_, ListenerPhase::Capturing) { + for cur_target in chain.r().iter().rev() { + let stopped = match cur_target.get_listeners_for(&type_, ListenerPhase::Capturing) { Some(listeners) => { - event.set_current_target(cur_target.r()); + event.set_current_target(cur_target); for listener in listeners.iter() { // Explicitly drop any exception on the floor. - let _ = listener.HandleEvent_(cur_target.r(), event, Report); + let _ = listener.HandleEvent_(*cur_target, event, Report); if event.stop_immediate() { break; @@ -87,14 +86,13 @@ pub fn dispatch_event<'a, 'b>(target: &'a EventTarget, if event.bubbles() && !event.stop_propagation() { event.set_phase(EventPhase::Bubbling); - for cur_target in chain.iter() { - let cur_target = cur_target.root(); - let stopped = match cur_target.r().get_listeners_for(&type_, ListenerPhase::Bubbling) { + for cur_target in chain.r() { + let stopped = match cur_target.get_listeners_for(&type_, ListenerPhase::Bubbling) { Some(listeners) => { - event.set_current_target(cur_target.r()); + event.set_current_target(cur_target); for listener in listeners.iter() { // Explicitly drop any exception on the floor. - let _ = listener.HandleEvent_(cur_target.r(), event, Report); + let _ = listener.HandleEvent_(*cur_target, event, Report); if event.stop_immediate() { break; diff --git a/components/script/dom/filereader.rs b/components/script/dom/filereader.rs index 7ac8f876157..964a980a0b1 100644 --- a/components/script/dom/filereader.rs +++ b/components/script/dom/filereader.rs @@ -2,8 +2,7 @@ * 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 dom::bindings::codegen::Bindings::FileReaderBinding; -use dom::bindings::codegen::Bindings::FileReaderBinding::{FileReaderConstants, FileReaderMethods}; +use dom::bindings::codegen::Bindings::FileReaderBinding::{self, FileReaderConstants, FileReaderMethods}; use dom::bindings::codegen::InheritTypes::{EventCast, EventTargetCast}; use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; use dom::bindings::error::{ErrorResult, Fallible}; @@ -14,8 +13,7 @@ use dom::bindings::refcounted::Trusted; use dom::bindings::utils::{reflect_dom_object, Reflectable}; use dom::event::{EventHelpers, EventCancelable, EventBubbles}; use dom::eventtarget::{EventTarget, EventTargetHelpers, EventTargetTypeId}; -use dom::blob::Blob; -use dom::blob::BlobHelpers; +use dom::blob::{Blob, BlobHelpers}; use dom::domexception::{DOMException, DOMErrorName}; use dom::progressevent::ProgressEvent; use encoding::all::UTF_8; @@ -229,33 +227,30 @@ impl FileReader { fn perform_readastext(blob_body: BlobBody) -> Result<Option<DOMString>, DOMErrorName> { + let blob_label = &blob_body.label; + let blob_type = &blob_body.blobtype; + let blob_bytes = &blob_body.bytes[..]; + //https://w3c.github.io/FileAPI/#encoding-determination // Steps 1 & 2 & 3 - let mut encoding = match blob_body.label { - Some(e) => encoding_from_whatwg_label(&e), - None => None - }; + let mut encoding = blob_label.as_ref() + .map(|string| &**string) + .and_then(encoding_from_whatwg_label); // Step 4 & 5 - encoding = match encoding { - Some(e) => Some(e), - None => { - let resultmime = blob_body.blobtype.parse::<Mime>().ok(); - resultmime.and_then(|Mime(_, _, ref parameters)| { - parameters.iter() - .find(|&&(ref k, _)| &Attr::Charset == k) - .and_then(|&(_, ref v)| encoding_from_whatwg_label(&v.to_string())) - }) - } - }; + encoding = encoding.or_else(|| { + let resultmime = blob_type.parse::<Mime>().ok(); + resultmime.and_then(|Mime(_, _, ref parameters)| { + parameters.iter() + .find(|&&(ref k, _)| &Attr::Charset == k) + .and_then(|&(_, ref v)| encoding_from_whatwg_label(&v.to_string())) + }) + }); // Step 6 - let enc = match encoding { - Some(code) => code, - None => UTF_8 as EncodingRef - }; + let enc = encoding.unwrap_or(UTF_8 as EncodingRef); - let convert = &blob_body.bytes[..]; + let convert = blob_bytes; // Step 7 let output = enc.decode(convert, DecoderTrap::Replace).unwrap(); Ok(Some(output)) @@ -409,73 +404,51 @@ impl<'a> PrivateFileReaderHelpers for &'a FileReader { } #[derive(Clone)] -pub enum Process { +pub enum FileReaderEvent { ProcessRead(TrustedFileReader, GenerationId), ProcessReadData(TrustedFileReader, GenerationId, DOMString), ProcessReadError(TrustedFileReader, GenerationId, DOMErrorName), ProcessReadEOF(TrustedFileReader, GenerationId, Option<BlobBody>) } -impl Process { - fn call(self, chan: &Box<ScriptChan + Send>) { - let task = box FileReaderEvent::new(self); - chan.send(ScriptMsg::RunnableMsg(task)).unwrap(); - } - - pub fn handle(process: Process) { - match process { - Process::ProcessRead(filereader, gen_id) => { +impl Runnable for FileReaderEvent { + fn handler(self: Box<FileReaderEvent>) { + let file_reader_event = *self; + match file_reader_event { + FileReaderEvent::ProcessRead(filereader, gen_id) => { FileReader::process_read(filereader, gen_id); }, - Process::ProcessReadData(filereader, gen_id, _) => { + FileReaderEvent::ProcessReadData(filereader, gen_id, _) => { FileReader::process_read_data(filereader, gen_id); }, - Process::ProcessReadError(filereader, gen_id, error) => { + FileReaderEvent::ProcessReadError(filereader, gen_id, error) => { FileReader::process_read_error(filereader, gen_id, error); }, - Process::ProcessReadEOF(filereader, gen_id, blob_body) => { + FileReaderEvent::ProcessReadEOF(filereader, gen_id, blob_body) => { FileReader::process_read_eof(filereader, gen_id, blob_body); } } } } -pub struct FileReaderEvent { - process: Process, -} - -impl FileReaderEvent { - pub fn new(process: Process) -> FileReaderEvent { - FileReaderEvent { - process: process, - } - } - -} - -impl Runnable for FileReaderEvent { - fn handler(self: Box<FileReaderEvent>) { - let this = *self; - Process::handle(this.process); - } -} - -//https://w3c.github.io/FileAPI/#task-read-operation +// https://w3c.github.io/FileAPI/#task-read-operation fn perform_annotated_read_operation(gen_id: GenerationId, read_data: ReadData, filereader: TrustedFileReader, script_chan: Box<ScriptChan + Send>) { let chan = &script_chan; // Step 4 - Process::ProcessRead(filereader.clone(), - gen_id).call(chan); + let task = box FileReaderEvent::ProcessRead(filereader.clone(), gen_id); + chan.send(ScriptMsg::RunnableMsg(task)).unwrap(); - Process::ProcessReadData(filereader.clone(), - gen_id, DOMString::new()).call(chan); + let task = box FileReaderEvent::ProcessReadData(filereader.clone(), + gen_id, DOMString::new()); + chan.send(ScriptMsg::RunnableMsg(task)).unwrap(); let output = match read_data.bytes.recv() { Ok(bytes) => bytes, Err(_) => { - Process::ProcessReadError(filereader, - gen_id, DOMErrorName::NotFoundError).call(chan); + let task = box FileReaderEvent::ProcessReadError(filereader, + gen_id, DOMErrorName::NotFoundError); + chan.send(ScriptMsg::RunnableMsg(task)).unwrap(); return; } }; @@ -487,5 +460,6 @@ fn perform_annotated_read_operation(gen_id: GenerationId, read_data: ReadData, BlobBody::new(bytes, blobtype, label, read_data.function) }); - Process::ProcessReadEOF(filereader, gen_id, blob_body).call(chan); + let task = box FileReaderEvent::ProcessReadEOF(filereader, gen_id, blob_body); + chan.send(ScriptMsg::RunnableMsg(task)).unwrap(); } 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/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 8bdbdb8759e..3329e0f0af9 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -27,7 +27,8 @@ use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::event::{Event, EventBubbles, EventCancelable, EventHelpers}; use dom::element::ElementTypeId; use dom::htmlelement::{HTMLElement, HTMLElementTypeId}; -use dom::node::{Node, NodeHelpers, NodeTypeId, document_from_node, window_from_node, CloneChildrenFlag}; +use dom::node::{ChildrenMutation, CloneChildrenFlag, Node, NodeHelpers}; +use dom::node::{NodeTypeId, document_from_node, window_from_node}; use dom::servohtmlparser::ServoHTMLParserHelpers; use dom::virtualmethods::VirtualMethods; use dom::window::{WindowHelpers, ScriptHelpers}; @@ -564,9 +565,9 @@ impl<'a> VirtualMethods for &'a HTMLScriptElement { } } - fn child_inserted(&self, child: &Node) { + fn children_changed(&self, mutation: &ChildrenMutation) { if let Some(ref s) = self.super_type() { - s.child_inserted(child); + s.children_changed(mutation); } let node = NodeCast::from_ref(*self); if !self.parser_inserted.get() && node.is_in_doc() { diff --git a/components/script/dom/htmlstyleelement.rs b/components/script/dom/htmlstyleelement.rs index 7c1c06412ef..22c4c705ccb 100644 --- a/components/script/dom/htmlstyleelement.rs +++ b/components/script/dom/htmlstyleelement.rs @@ -11,7 +11,8 @@ use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::{ElementTypeId, AttributeHandlers}; use dom::htmlelement::{HTMLElement, HTMLElementTypeId}; -use dom::node::{Node, NodeHelpers, NodeTypeId, window_from_node}; +use dom::node::{ChildrenMutation, Node, NodeHelpers, NodeTypeId}; +use dom::node::window_from_node; use dom::virtualmethods::VirtualMethods; use dom::window::WindowHelpers; use layout_interface::{LayoutChan, Msg}; @@ -86,11 +87,10 @@ impl<'a> VirtualMethods for &'a HTMLStyleElement { Some(htmlelement as &VirtualMethods) } - fn child_inserted(&self, child: &Node) { + fn children_changed(&self, mutation: &ChildrenMutation) { if let Some(ref s) = self.super_type() { - s.child_inserted(child); + s.children_changed(mutation); } - let node = NodeCast::from_ref(*self); if node.is_in_doc() { self.parse_own_css(); diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs index 17e646d71ed..22e843fa08f 100644 --- a/components/script/dom/htmltextareaelement.rs +++ b/components/script/dom/htmltextareaelement.rs @@ -11,7 +11,7 @@ use dom::bindings::codegen::Bindings::HTMLTextAreaElementBinding::HTMLTextAreaEl use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::InheritTypes::{ElementCast, EventTargetCast, HTMLElementCast, NodeCast}; use dom::bindings::codegen::InheritTypes::{HTMLTextAreaElementDerived, HTMLFieldSetElementDerived}; -use dom::bindings::codegen::InheritTypes::{KeyboardEventCast, TextDerived}; +use dom::bindings::codegen::InheritTypes::KeyboardEventCast; use dom::bindings::global::GlobalRef; use dom::bindings::js::{LayoutJS, Root}; use dom::bindings::refcounted::Trusted; @@ -23,8 +23,8 @@ use dom::element::ElementTypeId; use dom::htmlelement::{HTMLElement, HTMLElementTypeId}; use dom::htmlformelement::FormControl; use dom::keyboardevent::KeyboardEvent; -use dom::node::{DisabledStateHelpers, Node, NodeHelpers, NodeDamage, NodeTypeId}; -use dom::node::{document_from_node, window_from_node}; +use dom::node::{ChildrenMutation, DisabledStateHelpers, Node, NodeDamage}; +use dom::node::{NodeHelpers, NodeTypeId, document_from_node, window_from_node}; use textinput::{TextInput, Lines, KeyReaction}; use dom::virtualmethods::VirtualMethods; use dom::window::WindowHelpers; @@ -330,12 +330,11 @@ impl<'a> VirtualMethods for &'a HTMLTextAreaElement { } } - fn child_inserted(&self, child: &Node) { - if let Some(s) = self.super_type() { - s.child_inserted(child); + fn children_changed(&self, mutation: &ChildrenMutation) { + if let Some(ref s) = self.super_type() { + s.children_changed(mutation); } - - if child.is_text() && !self.value_changed.get() { + if !self.value_changed.get() { self.reset(); } } diff --git a/components/script/dom/htmltitleelement.rs b/components/script/dom/htmltitleelement.rs index a6585bd17b4..e4f51b03629 100644 --- a/components/script/dom/htmltitleelement.rs +++ b/components/script/dom/htmltitleelement.rs @@ -13,7 +13,7 @@ use dom::document::{Document, DocumentHelpers}; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; use dom::htmlelement::{HTMLElement, HTMLElementTypeId}; -use dom::node::{Node, NodeHelpers, NodeTypeId}; +use dom::node::{ChildrenMutation, Node, NodeHelpers, NodeTypeId}; use dom::text::Text; use dom::virtualmethods::VirtualMethods; use util::str::DOMString; @@ -75,15 +75,13 @@ impl<'a> VirtualMethods for &'a HTMLTitleElement { Some(htmlelement as &VirtualMethods) } - fn child_inserted(&self, child: &Node) { + fn children_changed(&self, mutation: &ChildrenMutation) { if let Some(ref s) = self.super_type() { - s.child_inserted(child); + s.children_changed(mutation); } - let node = NodeCast::from_ref(*self); if node.is_in_doc() { - let document = node.owner_doc(); - document.r().title_changed(); + node.owner_doc().title_changed(); } } diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 0a06a5253c5..42ad7608580 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -67,6 +67,7 @@ use std::cell::{Cell, RefCell, Ref, RefMut}; use std::default::Default; use std::iter::{FilterMap, Peekable}; use std::mem; +use std::slice::ref_slice; use std::sync::Arc; use uuid; use string_cache::{Atom, Namespace, QualName}; @@ -282,42 +283,11 @@ pub enum NodeTypeId { } trait PrivateNodeHelpers { - fn node_inserted(self); - fn node_removed(self, parent_in_doc: bool); fn add_child(self, new_child: &Node, before: Option<&Node>); fn remove_child(self, child: &Node); } impl<'a> PrivateNodeHelpers for &'a Node { - // https://dom.spec.whatwg.org/#node-is-inserted - fn node_inserted(self) { - assert!(self.parent_node.get().is_some()); - let document = document_from_node(self); - let is_in_doc = self.is_in_doc(); - - for node in self.traverse_preorder() { - vtable_for(&node.r()).bind_to_tree(is_in_doc); - } - - let parent = self.parent_node.get().map(Root::from_rooted); - parent.r().map(|parent| vtable_for(&parent).child_inserted(self)); - document.r().content_and_heritage_changed(self, NodeDamage::OtherNodeDamage); - } - - // https://dom.spec.whatwg.org/#node-is-removed - fn node_removed(self, parent_in_doc: bool) { - assert!(self.parent_node.get().is_none()); - for node in self.traverse_preorder() { - node.r().set_flag(IS_IN_DOC, false); - vtable_for(&node.r()).unbind_from_tree(parent_in_doc); - } - self.layout_data.dispose(self); - } - - // - // Pointer stitching - // - /// Adds a new child to the end of this node's list of children. /// /// Fails unless `new_child` is disconnected from the tree. @@ -358,6 +328,14 @@ impl<'a> PrivateNodeHelpers for &'a Node { } new_child.parent_node.set(Some(JS::from_ref(self))); + + let parent_in_doc = self.is_in_doc(); + for node in new_child.traverse_preorder() { + node.set_flag(IS_IN_DOC, parent_in_doc); + vtable_for(&&*node).bind_to_tree(parent_in_doc); + } + let document = new_child.owner_doc(); + document.content_and_heritage_changed(new_child, NodeDamage::OtherNodeDamage); } /// Removes the given child from this node's list of children. @@ -387,6 +365,15 @@ impl<'a> PrivateNodeHelpers for &'a Node { child.prev_sibling.set(None); child.next_sibling.set(None); child.parent_node.set(None); + + let parent_in_doc = self.is_in_doc(); + for node in child.traverse_preorder() { + node.set_flag(IS_IN_DOC, false); + vtable_for(&&*node).unbind_from_tree(parent_in_doc); + } + child.layout_data.dispose(child); + let document = child.owner_doc(); + document.content_and_heritage_changed(child, NodeDamage::OtherNodeDamage); } } @@ -971,9 +958,8 @@ impl<'a> NodeHelpers for &'a Node { } fn remove_self(self) { - match self.parent_node.get() { - Some(parent) => parent.root().r().remove_child(self), - None => () + if let Some(ref parent) = self.GetParentNode() { + Node::remove(self, parent.r(), SuppressObserver::Unsuppressed); } } @@ -1638,110 +1624,79 @@ impl Node { parent: &Node, child: Option<&Node>, suppress_observers: SuppressObserver) { - fn do_insert(node: &Node, parent: &Node, child: Option<&Node>) { - parent.add_child(node, child); - let is_in_doc = parent.is_in_doc(); - for kid in node.traverse_preorder() { - let mut flags = kid.r().flags.get(); - if is_in_doc { - flags.insert(IS_IN_DOC); - } else { - flags.remove(IS_IN_DOC); - } - kid.r().flags.set(flags); - } - } + debug_assert!(&*node.owner_doc() == &*parent.owner_doc()); + debug_assert!(child.map_or(true, |child| Some(parent) == child.GetParentNode().r())); - fn fire_observer_if_necessary(node: &Node, suppress_observers: SuppressObserver) { - match suppress_observers { - SuppressObserver::Unsuppressed => node.node_inserted(), - SuppressObserver::Suppressed => () + // Steps 1-2: ranges. + let mut new_nodes = RootedVec::new(); + let new_nodes = if let NodeTypeId::DocumentFragment = node.type_id() { + // Step 3. + new_nodes.extend(node.children().map(|kid| JS::from_rooted(&kid))); + // Step 4: mutation observers. + // Step 5. + for kid in new_nodes.r() { + Node::remove(*kid, node, SuppressObserver::Suppressed); } - } - - // XXX assert owner_doc - // Step 1-3: ranges. - - match node.type_id() { - NodeTypeId::DocumentFragment => { - // Step 4. - // Step 5: DocumentFragment, mutation records. - // Step 6: DocumentFragment. - let kids: Vec<Root<Node>> = node.children().collect(); - for kid in &kids { - Node::remove(kid.r(), node, SuppressObserver::Suppressed); - } - - // Step 7: mutation records. - // Step 8. - for kid in &kids { - do_insert(kid.r(), parent, child); - } - - for kid in kids { - fire_observer_if_necessary(kid.r(), suppress_observers); + vtable_for(&node).children_changed(&ChildrenMutation::replace_all(new_nodes.r(), &[])); + new_nodes.r() + } else { + // Step 3. + ref_slice(&node) + }; + // Step 6: mutation observers. + let previous_sibling = match suppress_observers { + SuppressObserver::Unsuppressed => { + match child { + Some(child) => child.GetPreviousSibling(), + None => parent.GetLastChild(), } - } - _ => { - // Step 4. - // Step 5: DocumentFragment, mutation records. - // Step 6: DocumentFragment. - // Step 7: mutation records. - // Step 8. - do_insert(node, parent, child); - // Step 9. - fire_observer_if_necessary(node, suppress_observers); - } + }, + SuppressObserver::Suppressed => None, + }; + // Step 7. + for kid in new_nodes { + // Step 7.1. + parent.add_child(*kid, child); + // Step 7.2: insertion steps. + } + if let SuppressObserver::Unsuppressed = suppress_observers { + vtable_for(&parent).children_changed( + &ChildrenMutation::insert(previous_sibling.r(), new_nodes, child)); } } // https://dom.spec.whatwg.org/#concept-node-replace-all pub fn replace_all(node: Option<&Node>, parent: &Node) { // Step 1. - match node { - Some(node) => { - let document = document_from_node(parent); - Node::adopt(node, document.r()); - } - None => (), + if let Some(node) = node { + Node::adopt(node, &*parent.owner_doc()); } - // Step 2. - let mut removed_nodes: RootedVec<JS<Node>> = RootedVec::new(); - for child in parent.children() { - removed_nodes.push(JS::from_rooted(&child)); - } - + let mut removed_nodes = RootedVec::new(); + removed_nodes.extend(parent.children().map(|child| JS::from_rooted(&child))); // Step 3. - let added_nodes = match node { - None => vec!(), - Some(node) => match node.type_id() { - NodeTypeId::DocumentFragment => node.children().collect(), - _ => vec!(Root::from_ref(node)), - }, + let mut added_nodes = RootedVec::new(); + let added_nodes = if let Some(node) = node.as_ref() { + if let NodeTypeId::DocumentFragment = node.type_id() { + added_nodes.extend(node.children().map(|child| JS::from_rooted(&child))); + added_nodes.r() + } else { + ref_slice(node) + } + } else { + &[] as &[&Node] }; - // Step 4. - for child in parent.children() { - Node::remove(child.r(), parent, SuppressObserver::Suppressed); + for child in removed_nodes.r() { + Node::remove(*child, parent, SuppressObserver::Suppressed); } - // Step 5. - match node { - Some(node) => Node::insert(node, parent, None, SuppressObserver::Suppressed), - None => (), - } - - // Step 6: mutation records. - - // Step 7. - let parent_in_doc = parent.is_in_doc(); - for removed_node in removed_nodes.iter() { - removed_node.root().r().node_removed(parent_in_doc); - } - for added_node in added_nodes { - added_node.r().node_inserted(); + if let Some(node) = node { + Node::insert(node, parent, None, SuppressObserver::Suppressed); } + // Step 6: mutation observers. + vtable_for(&parent).children_changed( + &ChildrenMutation::replace_all(removed_nodes.r(), added_nodes)); } // https://dom.spec.whatwg.org/#concept-node-pre-remove @@ -1761,16 +1716,22 @@ impl Node { } // https://dom.spec.whatwg.org/#concept-node-remove - fn remove(node: &Node, parent: &Node, _suppress_observers: SuppressObserver) { + fn remove(node: &Node, parent: &Node, suppress_observers: SuppressObserver) { assert!(node.GetParentNode().map_or(false, |node_parent| node_parent.r() == parent)); // Step 1-5: ranges. - // Step 6-7: mutation observers. - // Step 8. - parent.remove_child(node); - + // Step 6. + let old_previous_sibling = node.GetPreviousSibling(); + // Steps 7-8: mutation observers. // Step 9. - node.node_removed(parent.is_in_doc()); + let old_next_sibling = node.GetNextSibling(); + parent.remove_child(node); + if let SuppressObserver::Unsuppressed = suppress_observers { + vtable_for(&parent).children_changed( + &ChildrenMutation::replace(old_previous_sibling.r(), + &node, &[], + old_next_sibling.r())); + } } // https://dom.spec.whatwg.org/#concept-node-clone @@ -1855,10 +1816,9 @@ impl Node { copy_doc.set_quirks_mode(node_doc.quirks_mode()); }, NodeTypeId::Element(..) => { - let node_elem: &Element = ElementCast::to_ref(node).unwrap(); - let copy_elem: &Element = ElementCast::to_ref(copy.r()).unwrap(); + let node_elem = ElementCast::to_ref(node).unwrap(); + let copy_elem = ElementCast::to_ref(copy.r()).unwrap(); - // FIXME: https://github.com/mozilla/servo/issues/1737 let window = document.r().window(); for ref attr in node_elem.attrs().iter() { let attr = attr.root(); @@ -2275,36 +2235,31 @@ impl<'a> NodeMethods for &'a Node { let document = document_from_node(self); Node::adopt(node, document.r()); - // Step 12. - let mut nodes: RootedVec<JS<Node>> = RootedVec::new(); - if node.type_id() == NodeTypeId::DocumentFragment { - // Collect fragment children before Step 11, - // because Node::insert removes a DocumentFragment's children, - // and we need them in Step 13. - // Issue filed against the spec: - // https://www.w3.org/Bugs/Public/show_bug.cgi?id=28330 - for child_node in node.children() { - nodes.push(JS::from_rooted(&child_node)); - } - } else { - nodes.push(JS::from_ref(node)); - } + // Step 10. + let previous_sibling = child.GetPreviousSibling(); - { - // Step 10. - Node::remove(child, self, SuppressObserver::Suppressed); + // Step 11. + Node::remove(child, self, SuppressObserver::Suppressed); - // Step 11. - Node::insert(node, self, reference_child, SuppressObserver::Suppressed); - } + // Step 12. + let mut nodes = RootedVec::new(); + let nodes = if node.type_id() == NodeTypeId::DocumentFragment { + nodes.extend(node.children().map(|node| JS::from_rooted(&node))); + nodes.r() + } else { + ref_slice(&node) + }; - // Step 13: mutation records. - child.node_removed(self.is_in_doc()); - for child_node in &*nodes { - child_node.root().r().node_inserted(); - } + // Step 13. + Node::insert(node, self, reference_child, SuppressObserver::Suppressed); // Step 14. + vtable_for(&self).children_changed( + &ChildrenMutation::replace(previous_sibling.r(), + &child, nodes, + reference_child)); + + // Step 15. Ok(Root::from_ref(child)) } @@ -2322,14 +2277,14 @@ impl<'a> NodeMethods for &'a Node { Some(text) => { let characterdata: &CharacterData = CharacterDataCast::from_ref(text); if characterdata.Length() == 0 { - self.remove_child(child.r()); + Node::remove(&*child, self, SuppressObserver::Unsuppressed); } else { match prev_text { Some(ref text_node) => { let prev_characterdata = CharacterDataCast::from_ref(text_node.r()); prev_characterdata.append_data(&**characterdata.data()); - self.remove_child(child.r()); + Node::remove(&*child, self, SuppressObserver::Unsuppressed); }, None => prev_text = Some(Root::from_ref(text)) } @@ -2635,3 +2590,61 @@ pub enum NodeDamage { /// Other parts of a node changed; attributes, text content, etc. OtherNodeDamage, } + +pub enum ChildrenMutation<'a> { + Append { prev: &'a Node, added: &'a [&'a Node] }, + Insert { prev: &'a Node, added: &'a [&'a Node], next: &'a Node }, + Prepend { added: &'a [&'a Node], next: &'a Node }, + Replace { + prev: Option<&'a Node>, + removed: &'a Node, + added: &'a [&'a Node], + next: Option<&'a Node>, + }, + ReplaceAll { removed: &'a [&'a Node], added: &'a [&'a Node] }, +} + +impl<'a> ChildrenMutation<'a> { + fn insert(prev: Option<&'a Node>, added: &'a [&'a Node], next: Option<&'a Node>) + -> ChildrenMutation<'a> { + match (prev, next) { + (None, None) => { + ChildrenMutation::ReplaceAll { removed: &[], added: added } + }, + (Some(prev), None) => { + ChildrenMutation::Append { prev: prev, added: added } + }, + (None, Some(next)) => { + ChildrenMutation::Prepend { added: added, next: next } + }, + (Some(prev), Some(next)) => { + ChildrenMutation::Insert { prev: prev, added: added, next: next } + }, + } + } + + fn replace(prev: Option<&'a Node>, + removed: &'a &'a Node, + added: &'a [&'a Node], + next: Option<&'a Node>) + -> ChildrenMutation<'a> { + if let (None, None) = (prev, next) { + ChildrenMutation::ReplaceAll { + removed: ref_slice(removed), + added: added, + } + } else { + ChildrenMutation::Replace { + prev: prev, + removed: *removed, + added: added, + next: next, + } + } + } + + fn replace_all(removed: &'a [&'a Node], added: &'a [&'a Node]) + -> ChildrenMutation<'a> { + ChildrenMutation::ReplaceAll { removed: removed, added: added } + } +} diff --git a/components/script/dom/storage.rs b/components/script/dom/storage.rs index 42c564d9e2c..518d3c9c8f8 100644 --- a/components/script/dom/storage.rs +++ b/components/script/dom/storage.rs @@ -13,6 +13,7 @@ use dom::event::{EventHelpers, EventBubbles, EventCancelable}; use dom::storageevent::StorageEvent; use dom::urlhelper::UrlHelper; use dom::window::WindowHelpers; +use ipc_channel::ipc; use util::str::DOMString; use page::IterablePage; use net_traits::storage_task::{StorageTask, StorageTaskMsg, StorageType}; @@ -58,21 +59,21 @@ impl Storage { impl<'a> StorageMethods for &'a Storage { fn Length(self) -> u32 { - let (sender, receiver) = channel(); + let (sender, receiver) = ipc::channel().unwrap(); self.get_storage_task().send(StorageTaskMsg::Length(sender, self.get_url(), self.storage_type)).unwrap(); receiver.recv().unwrap() as u32 } fn Key(self, index: u32) -> Option<DOMString> { - let (sender, receiver) = channel(); + let (sender, receiver) = ipc::channel().unwrap(); self.get_storage_task().send(StorageTaskMsg::Key(sender, self.get_url(), self.storage_type, index)).unwrap(); receiver.recv().unwrap() } fn GetItem(self, name: DOMString) -> Option<DOMString> { - let (sender, receiver) = channel(); + let (sender, receiver) = ipc::channel().unwrap(); let msg = StorageTaskMsg::GetItem(sender, self.get_url(), self.storage_type, name); self.get_storage_task().send(msg).unwrap(); @@ -86,7 +87,7 @@ impl<'a> StorageMethods for &'a Storage { } fn SetItem(self, name: DOMString, value: DOMString) { - let (sender, receiver) = channel(); + let (sender, receiver) = ipc::channel().unwrap(); let msg = StorageTaskMsg::SetItem(sender, self.get_url(), self.storage_type, name.clone(), value.clone()); self.get_storage_task().send(msg).unwrap(); @@ -105,7 +106,7 @@ impl<'a> StorageMethods for &'a Storage { } fn RemoveItem(self, name: DOMString) { - let (sender, receiver) = channel(); + let (sender, receiver) = ipc::channel().unwrap(); let msg = StorageTaskMsg::RemoveItem(sender, self.get_url(), self.storage_type, name.clone()); self.get_storage_task().send(msg).unwrap(); @@ -119,7 +120,7 @@ impl<'a> StorageMethods for &'a Storage { } fn Clear(self) { - let (sender, receiver) = channel(); + let (sender, receiver) = ipc::channel().unwrap(); self.get_storage_task().send(StorageTaskMsg::Clear(sender, self.get_url(), self.storage_type)).unwrap(); if receiver.recv().unwrap() { diff --git a/components/script/dom/virtualmethods.rs b/components/script/dom/virtualmethods.rs index 8bb62637ac6..88cc024acd5 100644 --- a/components/script/dom/virtualmethods.rs +++ b/components/script/dom/virtualmethods.rs @@ -35,7 +35,8 @@ use dom::document::Document; use dom::element::ElementTypeId; use dom::event::Event; use dom::htmlelement::HTMLElementTypeId; -use dom::node::{Node, NodeHelpers, NodeTypeId, CloneChildrenFlag}; +use dom::node::{ChildrenMutation, CloneChildrenFlag, Node, NodeHelpers}; +use dom::node::NodeTypeId; use util::str::DOMString; @@ -97,10 +98,10 @@ pub trait VirtualMethods { } } - /// Called on the parent when a node is added to its child list. - fn child_inserted(&self, child: &Node) { + /// Called on the parent when its children are changed. + fn children_changed(&self, mutation: &ChildrenMutation) { if let Some(ref s) = self.super_type() { - s.child_inserted(child); + s.children_changed(mutation); } } 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 |