diff options
author | Emilio Cobos Álvarez <ecoal95@gmail.com> | 2016-08-30 16:37:37 -0700 |
---|---|---|
committer | Emilio Cobos Álvarez <ecoal95@gmail.com> | 2016-08-30 17:01:03 -0700 |
commit | fd9cd2f1036a580eba85dc65c11125a0bc85fb17 (patch) | |
tree | 2cf745b208f82a696e87006746a36881044a7853 /components/layout_thread/lib.rs | |
parent | 1fcc447941b23fb54963f9590219387695e73cb6 (diff) | |
download | servo-fd9cd2f1036a580eba85dc65c11125a0bc85fb17.tar.gz servo-fd9cd2f1036a580eba85dc65c11125a0bc85fb17.zip |
layout: Keep track of whether we've deferred the painting of the document due to
a script query.
This will, rather unfortunately, mean that we might repaint two times if we've
deferred a paint, then get an out-of-band reflow. Still seemed better than not
suppressing paints at all.
Fixes #13131
Diffstat (limited to 'components/layout_thread/lib.rs')
-rw-r--r-- | components/layout_thread/lib.rs | 126 |
1 files changed, 72 insertions, 54 deletions
diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 4cf5a435da7..d3be538e2b3 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -85,7 +85,7 @@ use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheResult, ImageCach use profile_traits::mem::{self, Report, ReportKind, ReportsChan}; use profile_traits::time::{TimerMetadataFrameType, TimerMetadataReflowType}; use profile_traits::time::{self, TimerMetadata, profile}; -use script::layout_wrapper::ServoLayoutNode; +use script::layout_wrapper::{ServoLayoutDocument, ServoLayoutNode}; use script_layout_interface::message::{Msg, NewLayoutThreadInfo, Reflow, ReflowQueryType, ScriptReflow}; use script_layout_interface::reporter::CSSErrorReporter; use script_layout_interface::restyle_damage::{REPAINT, STORE_OVERFLOW, REFLOW_OUT_OF_FLOW, REFLOW}; @@ -629,6 +629,7 @@ impl LayoutThread { reflow_info.goal); self.perform_post_style_recalc_layout_passes(&reflow_info, + None, &mut *rw_data, &mut layout_context); @@ -901,6 +902,7 @@ impl LayoutThread { fn compute_abs_pos_and_build_display_list(&mut self, data: &Reflow, + document: Option<&ServoLayoutDocument>, layout_root: &mut Flow, shared_layout_context: &mut SharedLayoutContext, rw_data: &mut LayoutThreadData) { @@ -962,59 +964,69 @@ impl LayoutThread { Some(Arc::new(DisplayList::new(root_stacking_context, display_list_entries))) } - if data.goal == ReflowGoal::ForDisplay { - let display_list = (*rw_data.display_list.as_ref().unwrap()).clone(); + if data.goal != ReflowGoal::ForDisplay { + // Defer the paint step until the next ForDisplay. + // + // We need to tell the document about this so it doesn't + // incorrectly suppress reflows. See #13131. + document.expect("No document in a non-display reflow?") + .needs_paint_from_layout(); + return; + } + if let Some(document) = document { + document.will_paint(); + } + let display_list = (*rw_data.display_list.as_ref().unwrap()).clone(); - if opts::get().dump_display_list { - display_list.print(); - } - if opts::get().dump_display_list_json { - println!("{}", serde_json::to_string_pretty(&display_list).unwrap()); - } + if opts::get().dump_display_list { + display_list.print(); + } + if opts::get().dump_display_list_json { + println!("{}", serde_json::to_string_pretty(&display_list).unwrap()); + } - debug!("Layout done!"); - - self.epoch.next(); - - 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); - let pipeline_id = self.id.to_webrender(); - - // TODO(gw) For now only create a root scrolling layer! - 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( - webrender_api, - pipeline_id, - epoch, - Some(root_scroll_layer_id), - &mut frame_builder); - let root_background_color = get_root_flow_background_color(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()); - - 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)) - .unwrap(); - } + debug!("Layout done!"); + + self.epoch.next(); + + 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); + let pipeline_id = self.id.to_webrender(); + + // TODO(gw) For now only create a root scrolling layer! + 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( + webrender_api, + pipeline_id, + epoch, + Some(root_scroll_layer_id), + &mut frame_builder); + let root_background_color = get_root_flow_background_color(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()); + + 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)) + .unwrap(); } }); } @@ -1205,6 +1217,7 @@ impl LayoutThread { // Perform post-style recalculation layout passes. self.perform_post_style_recalc_layout_passes(&data.reflow_info, + Some(&document), &mut rw_data, &mut shared_layout_context); @@ -1327,7 +1340,7 @@ impl LayoutThread { false, reflow_info.goal); - self.perform_post_main_layout_passes(&reflow_info, &mut *rw_data, &mut layout_context); + self.perform_post_main_layout_passes(&reflow_info, None, &mut *rw_data, &mut layout_context); true } @@ -1385,6 +1398,7 @@ impl LayoutThread { } self.perform_post_style_recalc_layout_passes(&reflow_info, + None, &mut *rw_data, &mut layout_context); } @@ -1407,12 +1421,14 @@ impl LayoutThread { return } self.perform_post_style_recalc_layout_passes(&reflow_info, + None, &mut *rw_data, &mut layout_context); } fn perform_post_style_recalc_layout_passes(&mut self, data: &Reflow, + document: Option<&ServoLayoutDocument>, rw_data: &mut LayoutThreadData, layout_context: &mut SharedLayoutContext) { if let Some(mut root_flow) = self.root_flow.clone() { @@ -1487,17 +1503,19 @@ impl LayoutThread { flow_ref::deref_mut(&mut root_flow) as &mut Flow); }); - self.perform_post_main_layout_passes(data, rw_data, layout_context); + self.perform_post_main_layout_passes(data, document, rw_data, layout_context); } } fn perform_post_main_layout_passes(&mut self, data: &Reflow, + document: Option<&ServoLayoutDocument>, rw_data: &mut LayoutThreadData, layout_context: &mut SharedLayoutContext) { // Build the display list if necessary, and send it to the painter. if let Some(mut root_flow) = self.root_flow.clone() { self.compute_abs_pos_and_build_display_list(data, + document, flow_ref::deref_mut(&mut root_flow), &mut *layout_context, rw_data); |