From acfd8e448cb01a8765de73c2a4fd43cbadda6310 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 15 Mar 2016 16:13:46 -0700 Subject: [PATCH] layout: Don't rebuild display lists at all unless restyling tells us some object needs to be repainted. Reduces CPU usage when mousing over simple documents. (More complex documents tend to trigger unnecessary reflow bugs and so still have high CPU.) Part of #9999. --- components/layout/layout_thread.rs | 70 +++++++++++++++++------------- components/layout/traversal.rs | 2 +- 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/components/layout/layout_thread.rs b/components/layout/layout_thread.rs index 187655f92b0..26c14af3b80 100644 --- a/components/layout/layout_thread.rs +++ b/components/layout/layout_thread.rs @@ -869,26 +869,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); + 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); + 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 +906,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 +927,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 +947,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()); diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index 139cd0ead05..6c774b76bcf 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -234,6 +234,6 @@ impl<'a> BuildDisplayList<'a> { #[inline] fn should_process(&self) -> bool { - self.state.layout_context.shared_context().goal == ReflowGoal::ForDisplay + true } }