diff options
Diffstat (limited to 'src/components/main/layout/layout_task.rs')
-rw-r--r-- | src/components/main/layout/layout_task.rs | 98 |
1 files changed, 51 insertions, 47 deletions
diff --git a/src/components/main/layout/layout_task.rs b/src/components/main/layout/layout_task.rs index 2224401188a..740576617fd 100644 --- a/src/components/main/layout/layout_task.rs +++ b/src/components/main/layout/layout_task.rs @@ -16,7 +16,7 @@ use layout::flow::{Flow, ImmutableFlowUtils, MutableFlowUtils, PreorderFlowTrave use layout::flow::{PostorderFlowTraversal}; use layout::flow; use layout::incremental::{RestyleDamage}; -use layout::util::{LayoutData, LayoutDataAccess, OpaqueNode}; +use layout::util::{LayoutDataAccess, OpaqueNode, LayoutDataWrapper}; use layout::wrapper::LayoutNode; use extra::arc::{Arc, RWArc, MutexArc}; @@ -34,7 +34,7 @@ use script::dom::element::{HTMLBodyElementTypeId, HTMLHtmlElementTypeId}; use script::layout_interface::{AddStylesheetMsg, ContentBoxQuery}; use script::layout_interface::{ContentBoxesQuery, ContentBoxesResponse, ExitNowMsg, LayoutQuery}; use script::layout_interface::{HitTestQuery, ContentBoxResponse, HitTestResponse}; -use script::layout_interface::{ContentChangedDocumentDamage, Msg, PrepareToExitMsg}; +use script::layout_interface::{ContentChangedDocumentDamage, LayoutChan, Msg, PrepareToExitMsg}; use script::layout_interface::{QueryMsg, ReapLayoutDataMsg, Reflow, ReflowDocumentDamage}; use script::layout_interface::{ReflowForDisplay, ReflowMsg}; use script::script_task::{ReflowCompleteMsg, ScriptChan, SendEventMsg}; @@ -46,20 +46,22 @@ use servo_util::time::{ProfilerChan, profile}; use servo_util::time; use std::cast::transmute; use std::cast; -use std::cell::Cell; +use std::cell::RefCell; use std::comm::Port; -use std::task; use std::util; use style::{AuthorOrigin, Stylesheet, Stylist}; /// Information needed by the layout task. -struct LayoutTask { +pub struct LayoutTask { /// The ID of the pipeline that we belong to. id: PipelineId, /// The port on which we receive messages. port: Port<Msg>, + //// The channel to send messages to ourself. + chan: LayoutChan, + /// The channel on which messages can be sent to the constellation. constellation_chan: ConstellationChan, @@ -132,9 +134,9 @@ impl PreorderFlowTraversal for PropagateDamageTraversal { /// The bubble-widths traversal, the first part of layout computation. This computes preferred /// and intrinsic widths and bubbles them up the tree. -struct BubbleWidthsTraversal<'self>(&'self mut LayoutContext); +struct BubbleWidthsTraversal<'a>(&'a mut LayoutContext); -impl<'self> PostorderFlowTraversal for BubbleWidthsTraversal<'self> { +impl<'a> PostorderFlowTraversal for BubbleWidthsTraversal<'a> { #[inline] fn process(&mut self, flow: &mut Flow) -> bool { flow.bubble_widths(**self); @@ -151,9 +153,9 @@ impl<'self> PostorderFlowTraversal for BubbleWidthsTraversal<'self> { } /// The assign-widths traversal. In Gecko this corresponds to `Reflow`. -struct AssignWidthsTraversal<'self>(&'self mut LayoutContext); +struct AssignWidthsTraversal<'a>(&'a mut LayoutContext); -impl<'self> PreorderFlowTraversal for AssignWidthsTraversal<'self> { +impl<'a> PreorderFlowTraversal for AssignWidthsTraversal<'a> { #[inline] fn process(&mut self, flow: &mut Flow) -> bool { flow.assign_widths(**self); @@ -164,9 +166,9 @@ impl<'self> PreorderFlowTraversal for AssignWidthsTraversal<'self> { /// The assign-heights-and-store-overflow traversal, the last (and most expensive) part of layout /// computation. Determines the final heights for all layout objects, computes positions, and /// computes overflow regions. In Gecko this corresponds to `FinishAndStoreOverflow`. -struct AssignHeightsAndStoreOverflowTraversal<'self>(&'self mut LayoutContext); +struct AssignHeightsAndStoreOverflowTraversal<'a>(&'a mut LayoutContext); -impl<'self> PostorderFlowTraversal for AssignHeightsAndStoreOverflowTraversal<'self> { +impl<'a> PostorderFlowTraversal for AssignHeightsAndStoreOverflowTraversal<'a> { #[inline] fn process(&mut self, flow: &mut Flow) -> bool { flow.assign_height(**self); @@ -186,10 +188,10 @@ struct LayoutImageResponder { } impl ImageResponder for LayoutImageResponder { - fn respond(&self) -> ~fn(ImageResponseMsg) { + fn respond(&self) -> proc(ImageResponseMsg) { let id = self.id.clone(); let script_chan = self.script_chan.clone(); - let f: ~fn(ImageResponseMsg) = |_| { + let f: proc(ImageResponseMsg) = proc(_) { script_chan.send(SendEventMsg(id.clone(), ReflowEvent)) }; f @@ -200,6 +202,7 @@ impl LayoutTask { /// Spawns a new layout task. pub fn create(id: PipelineId, port: Port<Msg>, + chan: LayoutChan, constellation_chan: ConstellationChan, script_chan: ScriptChan, render_chan: RenderChan<OpaqueNode>, @@ -207,11 +210,11 @@ impl LayoutTask { opts: Opts, profiler_chan: ProfilerChan, shutdown_chan: Chan<()>) { - spawn_with!(task::task(), [port, constellation_chan, script_chan, - render_chan, img_cache_task, profiler_chan, shutdown_chan], { - { // Ensures LayoutTask gets destroyed before we send the shutdown message + spawn(proc() { + { // Ensures layout task is destroyed before we send shutdown message let mut layout = LayoutTask::new(id, port, + chan, constellation_chan, script_chan, render_chan, @@ -220,7 +223,6 @@ impl LayoutTask { profiler_chan); layout.start(); } - shutdown_chan.send(()); }); } @@ -228,6 +230,7 @@ impl LayoutTask { /// Creates a new `LayoutTask` structure. fn new(id: PipelineId, port: Port<Msg>, + chan: LayoutChan, constellation_chan: ConstellationChan, script_chan: ScriptChan, render_chan: RenderChan<OpaqueNode>, @@ -239,6 +242,7 @@ impl LayoutTask { LayoutTask { id: id, port: port, + chan: chan, constellation_chan: constellation_chan, script_chan: script_chan, render_chan: render_chan, @@ -281,17 +285,15 @@ impl LayoutTask { match self.port.recv() { AddStylesheetMsg(sheet) => self.handle_add_stylesheet(sheet), ReflowMsg(data) => { - let data = Cell::new(data); - - do profile(time::LayoutPerformCategory, self.profiler_chan.clone()) { - self.handle_reflow(data.take()); - } + profile(time::LayoutPerformCategory, self.profiler_chan.clone(), || { + self.handle_reflow(data); + }); } QueryMsg(query) => { - let query = Cell::new(query); - do profile(time::LayoutQueryCategory, self.profiler_chan.clone()) { - self.handle_query(query.take()); - } + let mut query = Some(query); + profile(time::LayoutQueryCategory, self.profiler_chan.clone(), || { + self.handle_query(query.take_unwrap()); + }); } ReapLayoutDataMsg(dead_layout_data) => { unsafe { @@ -340,16 +342,16 @@ impl LayoutTask { /// Shuts down the layout task now. If there are any DOM nodes left, layout will now (safely) /// crash. fn exit_now(&mut self) { - let (response_port, response_chan) = stream(); + let (response_port, response_chan) = Chan::new(); self.render_chan.send(render_task::ExitMsg(response_chan)); response_port.recv() } fn handle_add_stylesheet(&mut self, sheet: Stylesheet) { - let sheet = Cell::new(sheet); - do self.stylist.write |stylist| { - stylist.add_stylesheet(sheet.take(), AuthorOrigin); - } + let mut sheet = Some(sheet); + self.stylist.write(|stylist| { + stylist.add_stylesheet(sheet.take_unwrap(), AuthorOrigin); + }); } /// Builds the flow tree. @@ -359,12 +361,13 @@ impl LayoutTask { /// is intertwined with selector matching, making it difficult to compare directly. It is /// marked `#[inline(never)]` to aid benchmarking in sampling profilers. #[inline(never)] - fn construct_flow_tree(&self, layout_context: &mut LayoutContext, node: LayoutNode) -> ~Flow: { + fn construct_flow_tree(&self, layout_context: &mut LayoutContext, node: LayoutNode) -> ~Flow { node.traverse_postorder_mut(&mut FlowConstructor::init(layout_context)); - let result = match *node.mutate_layout_data().ptr { + let mut layout_data_ref = node.mutate_layout_data(); + let result = match *layout_data_ref.get() { Some(ref mut layout_data) => { - util::replace(&mut layout_data.flow_construction_result, NoConstructionResult) + util::replace(&mut layout_data.data.flow_construction_result, NoConstructionResult) } None => fail!("no layout data for root node"), }; @@ -436,18 +439,18 @@ impl LayoutTask { // Initialize layout data for each node. // // FIXME: This is inefficient. We don't need an entire traversal to do this! - do profile(time::LayoutAuxInitCategory, self.profiler_chan.clone()) { - node.initialize_style_for_subtree(); - } + profile(time::LayoutAuxInitCategory, self.profiler_chan.clone(), || { + node.initialize_style_for_subtree(self.chan.clone()); + }); // Perform CSS selector matching if necessary. match data.damage.level { ReflowDocumentDamage => {} _ => { - do profile(time::LayoutSelectorMatchCategory, self.profiler_chan.clone()) { + profile(time::LayoutSelectorMatchCategory, self.profiler_chan.clone(), || { node.match_subtree(self.stylist.clone()); node.cascade_subtree(None); - } + }); } } @@ -464,25 +467,25 @@ impl LayoutTask { // Perform the primary layout passes over the flow tree to compute the locations of all // the boxes. - do profile(time::LayoutMainCategory, self.profiler_chan.clone()) { + profile(time::LayoutMainCategory, self.profiler_chan.clone(), || { self.solve_constraints(layout_root, &mut layout_ctx) - } + }); debug!("layout: constraint solving done:"); debug!("{:?}", layout_root.dump()); // Build the display list if necessary, and send it to the renderer. if data.goal == ReflowForDisplay { - do profile(time::LayoutDispListBuildCategory, self.profiler_chan.clone()) { + profile(time::LayoutDispListBuildCategory, self.profiler_chan.clone(), || { let root_size = flow::base(layout_root).position.size; - let display_list = ~Cell::new(DisplayList::<OpaqueNode>::new()); + let display_list = ~RefCell::new(DisplayList::<OpaqueNode>::new()); let dirty = flow::base(layout_root).position.clone(); let display_list_builder = DisplayListBuilder { ctx: &layout_ctx, }; layout_root.build_display_list(&display_list_builder, &dirty, display_list); - let display_list = Arc::new(display_list.take()); + let display_list = Arc::new(display_list.unwrap()); let mut color = color::rgba(255.0, 255.0, 255.0, 255.0); @@ -516,7 +519,7 @@ impl LayoutTask { self.display_list = Some(display_list.clone()); self.render_chan.send(RenderMsg(render_layer)); - } // time(layout: display list building) + }); } // Tell script that we're done. @@ -663,8 +666,9 @@ impl LayoutTask { /// Handles a message to destroy layout data. Layout data must be destroyed on *this* task /// because it contains local managed pointers. unsafe fn handle_reap_layout_data(&self, layout_data: LayoutDataRef) { - let ptr: &mut Option<~LayoutData> = cast::transmute(layout_data.borrow_unchecked()); - *ptr = None + let mut layout_data_ref = layout_data.borrow_mut(); + let _: Option<LayoutDataWrapper> = cast::transmute( + util::replace(layout_data_ref.get(), None)); } } |