diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2016-03-22 03:37:49 +0530 |
---|---|---|
committer | bors-servo <lbergstrom+bors@mozilla.com> | 2016-03-22 03:37:49 +0530 |
commit | 9813d11f862a61a7cffb4cf2d7de0fa7d269c62a (patch) | |
tree | 45a7eba38f075a3fe36d860b69d66f6c17c0d387 /components/layout/layout_thread.rs | |
parent | 95de8b2b03c521011f3e3b9c4b7db89f108a16db (diff) | |
parent | 7a131ba104fe5500ab4bd46ae9c3e35ffba5054d (diff) | |
download | servo-9813d11f862a61a7cffb4cf2d7de0fa7d269c62a.tar.gz servo-9813d11f862a61a7cffb4cf2d7de0fa7d269c62a.zip |
Auto merge of #10021 - pcwalton:skip-layout-traversals, r=mbrubeck
layout: Skip layout traversals that obviously won't do anything.
This reduces CPU usage when mousing over simple pages (example.com). More complex pages (Wikipedia) still reflow a lot due to other bugs.
Additionally, this change causes Servo to stop painting the results of hit test queries. This is also a win for CPU usage.
This significantly improves #9999, though there's more that can be done. I'll leave it open in case @paulrouget thinks this PR isn't enough.
r? @mbrubeck
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/10021)
<!-- Reviewable:end -->
Diffstat (limited to 'components/layout/layout_thread.rs')
-rw-r--r-- | components/layout/layout_thread.rs | 115 |
1 files changed, 63 insertions, 52 deletions
diff --git a/components/layout/layout_thread.rs b/components/layout/layout_thread.rs index 187655f92b0..f473979c72d 100644 --- a/components/layout/layout_thread.rs +++ b/components/layout/layout_thread.rs @@ -30,7 +30,8 @@ use gfx::font_context; use gfx::paint_thread::LayoutToPaintMsg; use gfx_traits::{color, Epoch, LayerId, ScrollPolicy}; use heapsize::HeapSizeOf; -use incremental::{LayoutDamageComputation, REFLOW, REFLOW_ENTIRE_DOCUMENT, REPAINT}; +use incremental::{LayoutDamageComputation, REFLOW, REFLOW_ENTIRE_DOCUMENT, REFLOW_OUT_OF_FLOW}; +use incremental::{REPAINT}; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use ipc_channel::router::ROUTER; use layout_debug; @@ -869,26 +870,27 @@ impl LayoutThread { flow::mut_base(flow_ref::deref_mut(layout_root)).clip = ClippingRegion::from_rect(&data.page_clip_rect); - let mut root_stacking_context = - StackingContext::new(StackingContextId::new(0), - StackingContextType::Real, - &Rect::zero(), - &Rect::zero(), - 0, - filter::T::new(Vec::new()), - mix_blend_mode::T::normal, - Matrix4::identity(), - Matrix4::identity(), - true, - false, - None); - - let display_list_entries = - sequential::build_display_list_for_subtree(layout_root, - &mut root_stacking_context, - shared_layout_context); + if flow::base(&**layout_root).restyle_damage.contains(REPAINT) || + rw_data.display_list.is_none() { + let mut root_stacking_context = + StackingContext::new(StackingContextId::new(0), + StackingContextType::Real, + &Rect::zero(), + &Rect::zero(), + 0, + filter::T::new(Vec::new()), + mix_blend_mode::T::normal, + Matrix4::identity(), + Matrix4::identity(), + true, + false, + None); + + let display_list_entries = + sequential::build_display_list_for_subtree(layout_root, + &mut root_stacking_context, + shared_layout_context); - if data.goal == ReflowGoal::ForDisplay { debug!("Done building display list."); let root_background_color = get_root_flow_background_color( @@ -905,13 +907,20 @@ impl LayoutThread { let origin = Rect::new(Point2D::new(Au(0), Au(0)), root_size); root_stacking_context.bounds = origin; root_stacking_context.overflow = origin; - root_stacking_context.layer_info = Some(LayerInfo::new(layout_root.layer_id(), - ScrollPolicy::Scrollable, - None, - root_background_color)); + root_stacking_context.layer_info = + Some(LayerInfo::new(layout_root.layer_id(), + ScrollPolicy::Scrollable, + None, + root_background_color)); + + rw_data.display_list = + Some(Arc::new(DisplayList::new(root_stacking_context, + &mut Some(display_list_entries)))) + } + + if data.goal == ReflowGoal::ForDisplay { + let display_list = (*rw_data.display_list.as_ref().unwrap()).clone(); - let display_list = DisplayList::new(root_stacking_context, - &mut Some(display_list_entries)); if opts::get().dump_display_list { display_list.print(); } @@ -919,9 +928,6 @@ impl LayoutThread { println!("{}", serde_json::to_string_pretty(&display_list).unwrap()); } - let display_list = Arc::new(display_list); - rw_data.display_list = Some(display_list.clone()); - debug!("Layout done!"); self.epoch.next(); @@ -942,10 +948,13 @@ impl LayoutThread { epoch, Some(root_scroll_layer_id), &mut auxiliary_lists_builder); - let root_background_color = webrender_traits::ColorF::new(root_background_color.r, - root_background_color.g, - root_background_color.b, - root_background_color.a); + let root_background_color = get_root_flow_background_color( + flow_ref::deref_mut(layout_root)); + let root_background_color = + webrender_traits::ColorF::new(root_background_color.r, + root_background_color.g, + root_background_color.b, + root_background_color.a); let viewport_size = Size2D::new(self.viewport_size.width.to_f32_px(), self.viewport_size.height.to_f32_px()); @@ -1323,26 +1332,28 @@ impl LayoutThread { // Perform the primary layout passes over the flow tree to compute the locations of all // the boxes. - profile(time::ProfilerCategory::LayoutMain, - self.profiler_metadata(), - self.time_profiler_chan.clone(), - || { - let profiler_metadata = self.profiler_metadata(); - match self.parallel_traversal { - None => { - // Sequential mode. - LayoutThread::solve_constraints(&mut root_flow, &layout_context) - } - Some(ref mut parallel) => { - // Parallel mode. - LayoutThread::solve_constraints_parallel(parallel, - &mut root_flow, - profiler_metadata, - self.time_profiler_chan.clone(), - &*layout_context); + if flow::base(&*root_flow).restyle_damage.intersects(REFLOW | REFLOW_OUT_OF_FLOW) { + profile(time::ProfilerCategory::LayoutMain, + self.profiler_metadata(), + self.time_profiler_chan.clone(), + || { + let profiler_metadata = self.profiler_metadata(); + match self.parallel_traversal { + None => { + // Sequential mode. + LayoutThread::solve_constraints(&mut root_flow, &layout_context) + } + Some(ref mut parallel) => { + // Parallel mode. + LayoutThread::solve_constraints_parallel(parallel, + &mut root_flow, + profiler_metadata, + self.time_profiler_chan.clone(), + &*layout_context); + } } - } - }); + }); + } profile(time::ProfilerCategory::LayoutStoreOverflow, self.profiler_metadata(), |