diff options
Diffstat (limited to 'components/layout_thread/lib.rs')
-rw-r--r-- | components/layout_thread/lib.rs | 75 |
1 files changed, 39 insertions, 36 deletions
diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 9d576e3bd02..403f30a96f5 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -232,6 +232,10 @@ pub struct LayoutThread { /// The timer object to control the timing of the animations. This should /// only be a test-mode timer during testing for animations. timer: Timer, + + // Number of layout threads. This is copied from `util::opts`, but we'd + // rather limit the dependency on that module here. + layout_threads: usize, } impl LayoutThreadFactory for LayoutThread { @@ -251,7 +255,8 @@ impl LayoutThreadFactory for LayoutThread { time_profiler_chan: time::ProfilerChan, mem_profiler_chan: mem::ProfilerChan, content_process_shutdown_chan: IpcSender<()>, - webrender_api_sender: Option<webrender_traits::RenderApiSender>) { + webrender_api_sender: Option<webrender_traits::RenderApiSender>, + layout_threads: usize) { thread::spawn_named(format!("LayoutThread {:?}", id), move || { thread_state::initialize(thread_state::LAYOUT); @@ -270,7 +275,8 @@ impl LayoutThreadFactory for LayoutThread { font_cache_thread, time_profiler_chan, mem_profiler_chan.clone(), - webrender_api_sender); + webrender_api_sender, + layout_threads); let reporter_name = format!("layout-reporter-{}", id); mem_profiler_chan.run_with_memory_reporting(|| { @@ -381,14 +387,14 @@ impl LayoutThread { font_cache_thread: FontCacheThread, time_profiler_chan: time::ProfilerChan, mem_profiler_chan: mem::ProfilerChan, - webrender_api_sender: Option<webrender_traits::RenderApiSender>) + webrender_api_sender: Option<webrender_traits::RenderApiSender>, + layout_threads: usize) -> LayoutThread { let device = Device::new( MediaType::Screen, opts::get().initial_window_size.as_f32() * ScaleFactor::new(1.0)); - let parallel_traversal = if opts::get().layout_threads != 1 { - Some(WorkQueue::new("LayoutWorker", thread_state::LAYOUT, - opts::get().layout_threads)) + let parallel_traversal = if layout_threads != 1 { + Some(WorkQueue::new("LayoutWorker", thread_state::LAYOUT, layout_threads)) } else { None }; @@ -479,6 +485,7 @@ impl LayoutThread { } else { Timer::new() }, + layout_threads: layout_threads, } } @@ -754,7 +761,8 @@ impl LayoutThread { self.time_profiler_chan.clone(), self.mem_profiler_chan.clone(), info.content_process_shutdown_chan, - self.webrender_api.as_ref().map(|wr| wr.clone_sender())); + self.webrender_api.as_ref().map(|wr| wr.clone_sender()), + info.layout_threads); } /// Enters a quiescent state in which no new messages will be processed until an `ExitNow` is @@ -961,7 +969,7 @@ impl LayoutThread { self.epoch.next(); - if opts::get().use_webrender { + if let Some(ref mut webrender_api) = self.webrender_api { // TODO: Avoid the temporary conversion and build webrender sc/dl directly! let Epoch(epoch_number) = self.epoch; let epoch = webrender_traits::Epoch(epoch_number); @@ -971,7 +979,7 @@ impl LayoutThread { let mut frame_builder = WebRenderFrameBuilder::new(pipeline_id); let root_scroll_layer_id = frame_builder.next_scroll_layer_id(); let sc_id = rw_data.display_list.as_ref().unwrap().convert_to_webrender( - &mut self.webrender_api.as_mut().unwrap(), + webrender_api, pipeline_id, epoch, Some(root_scroll_layer_id), @@ -987,16 +995,15 @@ impl LayoutThread { let viewport_size = Size2D::new(self.viewport_size.width.to_f32_px(), self.viewport_size.height.to_f32_px()); - let api = self.webrender_api.as_ref().unwrap(); - api.set_root_stacking_context(sc_id, - root_background_color, - epoch, - pipeline_id, - viewport_size, - frame_builder.stacking_contexts, - frame_builder.display_lists, - frame_builder.auxiliary_lists_builder - .finalize()); + webrender_api.set_root_stacking_context( + sc_id, + root_background_color, + epoch, + pipeline_id, + viewport_size, + frame_builder.stacking_contexts, + frame_builder.display_lists, + frame_builder.auxiliary_lists_builder.finalize()); } else { self.paint_chan .send(LayoutToPaintMsg::PaintInit(self.epoch, display_list)) @@ -1097,12 +1104,16 @@ impl LayoutThread { .unwrap(); } if data.document_stylesheets.iter().any(|sheet| sheet.dirty_on_viewport_size_change) { - for node in node.traverse_preorder() { + let mut iter = node.traverse_preorder(); + + let mut next = iter.next(); + while let Some(node) = next { if node.needs_dirty_on_viewport_size_changed() { - node.dirty_self(); - node.dirty_descendants(); - // TODO(shinglyu): We can skip the traversal if the descendants were already - // dirtied + // NB: The dirty bit is propagated down the tree. + unsafe { node.set_dirty(true); } + next = iter.next_skipping_children(); + } else { + next = iter.next(); } } } @@ -1114,7 +1125,9 @@ impl LayoutThread { let needs_reflow = viewport_size_changed && !needs_dirtying; unsafe { if needs_dirtying { - LayoutThread::dirty_all_nodes(node); + // NB: The dirty flag is propagated down during the restyle + // process. + node.set_dirty(true); } } if needs_reflow { @@ -1158,7 +1171,7 @@ impl LayoutThread { // TODO(pcwalton): Measure energy usage of text shaping, perhaps? let text_shaping_time = (font::get_and_reset_text_shaping_performance_counter() as u64) / - (opts::get().layout_threads as u64); + (self.layout_threads as u64); time::send_profile_data(time::ProfilerCategory::LayoutTextShaping, self.profiler_metadata(), self.time_profiler_chan.clone(), @@ -1468,16 +1481,6 @@ impl LayoutThread { } } - unsafe fn dirty_all_nodes<N: LayoutNode>(node: N) { - for node in node.traverse_preorder() { - // TODO(cgaebel): mark nodes which are sensitive to media queries as - // "changed": - // > node.set_changed(true); - node.set_dirty(true); - node.set_dirty_descendants(true); - } - } - fn reflow_all_nodes(flow: &mut Flow) { debug!("reflowing all nodes!"); flow::mut_base(flow).restyle_damage.insert(REPAINT | STORE_OVERFLOW | REFLOW); |