From 21ea8eef1957f62c6a922d69a0f906bbd2e255dd Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 16 Mar 2016 14:53:43 -0700 Subject: [PATCH 1/6] layout: Make transform changes require incremental repaint. The progress bar in browser.html was only accidentally working before, so actually making use of `REPAINT` makes it stop working without this change. --- components/layout/incremental.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/layout/incremental.rs b/components/layout/incremental.rs index 362ec2a472c..7b5838ea19a 100644 --- a/components/layout/incremental.rs +++ b/components/layout/incremental.rs @@ -167,7 +167,8 @@ pub fn compute_damage(old: Option<&Arc>, new: &ComputedValues) - [ REPAINT ], [ get_color.color, get_background.background_color, get_border.border_top_color, get_border.border_right_color, - get_border.border_bottom_color, get_border.border_left_color + get_border.border_bottom_color, get_border.border_left_color, + get_effects.transform ]); add_if_not_equal!(old, new, damage, From 5dca00592066e48503b411054bd7c1fbd91dea14 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Mon, 21 Mar 2016 08:39:21 -0700 Subject: [PATCH 2/6] layout: Repaint when `z-index` is modified. --- components/layout/incremental.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/layout/incremental.rs b/components/layout/incremental.rs index 7b5838ea19a..d02bcde6cd2 100644 --- a/components/layout/incremental.rs +++ b/components/layout/incremental.rs @@ -168,7 +168,7 @@ pub fn compute_damage(old: Option<&Arc>, new: &ComputedValues) - get_color.color, get_background.background_color, get_border.border_top_color, get_border.border_right_color, get_border.border_bottom_color, get_border.border_left_color, - get_effects.transform + get_effects.transform, get_box.z_index ]); add_if_not_equal!(old, new, damage, From acfd8e448cb01a8765de73c2a4fd43cbadda6310 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 15 Mar 2016 16:13:46 -0700 Subject: [PATCH 3/6] 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 } } From 7cb9429a0f7eb6f3dc9a5b6d3306bea7536fa44a Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 15 Mar 2016 16:18:00 -0700 Subject: [PATCH 4/6] layout: Don't start the reflow pass unless some node needs to be reflowed. Reduces CPU usage when mousing over simple pages. Part of #9999. --- components/layout/layout_thread.rs | 43 ++++++++++++++++-------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/components/layout/layout_thread.rs b/components/layout/layout_thread.rs index 26c14af3b80..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; @@ -1331,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) + 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); + } } - 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(), From ed6ee299517968e532a1ff2883936db48787de5b Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 15 Mar 2016 16:18:33 -0700 Subject: [PATCH 5/6] script: Don't paint layouts induced by hit test queries. Reduces CPU usage when mousing over simple pages. Part of #9999. --- components/script/dom/window.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index df7d1f92de7..9ee7fd81160 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -1021,7 +1021,11 @@ impl Window { debug!("script: layout joined"); - self.pending_reflow_count.set(0); + // Pending reflows require display, so only reset the pending reflow count if this reflow + // was to be displayed. + if goal == ReflowGoal::ForDisplay { + self.pending_reflow_count.set(0); + } if let Some(marker) = marker { self.emit_timeline_marker(marker.end()); @@ -1104,7 +1108,7 @@ impl Window { pub fn hit_test_query(&self, hit_test_request: Point2D, update_cursor: bool) -> Option { - self.reflow(ReflowGoal::ForDisplay, + self.reflow(ReflowGoal::ForScriptQuery, ReflowQueryType::HitTestQuery(hit_test_request, update_cursor), ReflowReason::Query); self.layout_rpc.hit_test().node_address From 7a131ba104fe5500ab4bd46ae9c3e35ffba5054d Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 15 Mar 2016 16:19:43 -0700 Subject: [PATCH 6/6] layout: Minor whitespace cleanup. --- components/layout/incremental.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/components/layout/incremental.rs b/components/layout/incremental.rs index d02bcde6cd2..9fbd5e6ce49 100644 --- a/components/layout/incremental.rs +++ b/components/layout/incremental.rs @@ -253,7 +253,6 @@ impl<'a> LayoutDamageComputation for &'a mut Flow { has_counter_affecting_children = has_counter_affecting_children || flow::base(kid).flags.intersects(AFFECTS_COUNTERS | HAS_COUNTER_AFFECTING_CHILDREN); - } }