aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/layout_thread.rs
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2016-03-22 03:37:49 +0530
committerbors-servo <lbergstrom+bors@mozilla.com>2016-03-22 03:37:49 +0530
commit9813d11f862a61a7cffb4cf2d7de0fa7d269c62a (patch)
tree45a7eba38f075a3fe36d860b69d66f6c17c0d387 /components/layout/layout_thread.rs
parent95de8b2b03c521011f3e3b9c4b7db89f108a16db (diff)
parent7a131ba104fe5500ab4bd46ae9c3e35ffba5054d (diff)
downloadservo-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.rs115
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(),