diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2019-09-11 04:39:53 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-09-11 04:39:53 -0400 |
commit | 86ad84198ef0f53b12e0eecfacd9edbfa0d27a1a (patch) | |
tree | 470d1615acbac670ccf8765fbb4bb1fa723683b2 /components/layout_thread_2020/lib.rs | |
parent | ec1da1d01c0f48544084d9cba4398b592c58e1fe (diff) | |
parent | 4444c5a2adfec909e165497ca331c09e02ee54cc (diff) | |
download | servo-86ad84198ef0f53b12e0eecfacd9edbfa0d27a1a.tar.gz servo-86ad84198ef0f53b12e0eecfacd9edbfa0d27a1a.zip |
Auto merge of #24165 - nox:victor, r=SimonSapin
Import victor's layout system 🍷
<!-- Reviewable:start -->
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/24165)
<!-- Reviewable:end -->
Diffstat (limited to 'components/layout_thread_2020/lib.rs')
-rw-r--r-- | components/layout_thread_2020/lib.rs | 146 |
1 files changed, 26 insertions, 120 deletions
diff --git a/components/layout_thread_2020/lib.rs b/components/layout_thread_2020/lib.rs index ec31d858b9f..5855dea84cf 100644 --- a/components/layout_thread_2020/lib.rs +++ b/components/layout_thread_2020/lib.rs @@ -29,11 +29,9 @@ use embedder_traits::resources::{self, Resource}; use euclid::{default::Size2D as UntypedSize2D, Point2D, Rect, Scale, Size2D}; use fnv::FnvHashMap; use fxhash::FxHashMap; -use gfx::font; use gfx::font_cache_thread::FontCacheThread; use gfx::font_context; use gfx_traits::{node_id_from_scroll_id, Epoch}; -use histogram::Histogram; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use ipc_channel::router::ROUTER; use layout::context::LayoutContext; @@ -46,7 +44,7 @@ use layout::query::{ process_offset_parent_query, process_resolved_style_request, process_style_query, process_text_index_request, }; -use layout::traversal::RecalcStyleAndConstructFlows; +use layout::traversal::RecalcStyle; use layout_traits::LayoutThreadFactory; use libc::c_void; use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; @@ -86,10 +84,10 @@ use std::time::Duration; use style::animation::Animation; use style::context::{QuirksMode, RegisteredSpeculativePainter, RegisteredSpeculativePainters}; use style::context::{SharedStyleContext, ThreadLocalStyleContextCreationInfo}; -use style::dom::{ShowSubtree, TDocument, TElement, TNode}; +use style::dom::{TDocument, TElement, TNode}; use style::driver; use style::error_reporting::RustLogReporter; -use style::global_style_data::{GLOBAL_STYLE_DATA, STYLE_THREAD_POOL}; +use style::global_style_data::GLOBAL_STYLE_DATA; use style::invalidation::element::restyle_hints::RestyleHint; use style::media_queries::{Device, MediaList, MediaType}; use style::properties::PropertyId; @@ -154,9 +152,6 @@ pub struct LayoutThread { /// Is this the first reflow in this LayoutThread? first_reflow: Cell<bool>, - /// Flag to indicate whether to use parallel operations - parallel_flag: bool, - /// Starts at zero, and increased by one every time a layout completes. /// This can be used to easily check for invalid stale data. generation: Cell<u32>, @@ -203,9 +198,6 @@ pub struct LayoutThread { /// Paint time metrics. paint_time_metrics: PaintTimeMetrics, - /// The time a layout query has waited before serviced by layout thread. - layout_query_waiting_time: Histogram, - /// Flag that indicates if LayoutThread is busy handling a request. busy: Arc<AtomicBool>, @@ -496,7 +488,6 @@ impl LayoutThread { first_reflow: Cell::new(true), font_cache_receiver: font_cache_receiver, font_cache_sender: ipc_font_cache_sender, - parallel_flag: true, generation: Cell::new(0), new_animations_sender: new_animations_sender, _new_animations_receiver: new_animations_receiver, @@ -529,7 +520,6 @@ impl LayoutThread { Timer::new() }, paint_time_metrics: paint_time_metrics, - layout_query_waiting_time: Histogram::new(), busy, load_webfonts_synchronously, initial_window_size, @@ -575,6 +565,7 @@ impl LayoutThread { traversal_flags: TraversalFlags::empty(), snapshot_map: snapshot_map, }, + font_cache_thread: Mutex::new(self.font_cache_thread.clone()), } } @@ -853,21 +844,7 @@ impl LayoutThread { } } - /// Shuts down the layout thread now. If there are any DOM nodes left, layout will now (safely) - /// crash. fn exit_now(&mut self) { - // Drop the root flow explicitly to avoid holding style data, such as - // rule nodes. The `Stylist` checks when it is dropped that all rule - // nodes have been GCed, so we want drop anyone who holds them first. - let waiting_time_min = self.layout_query_waiting_time.minimum().unwrap_or(0); - let waiting_time_max = self.layout_query_waiting_time.maximum().unwrap_or(0); - let waiting_time_mean = self.layout_query_waiting_time.mean().unwrap_or(0); - let waiting_time_stddev = self.layout_query_waiting_time.stddev().unwrap_or(0); - debug!( - "layout: query waiting time: min: {}, max: {}, mean: {}, standard_deviation: {}", - waiting_time_min, waiting_time_max, waiting_time_mean, waiting_time_stddev - ); - self.background_hang_monitor.unregister(); } @@ -909,23 +886,8 @@ impl LayoutThread { let document = unsafe { ServoLayoutNode::new(&data.document) }; let document = document.as_document().unwrap(); - // Parallelize if there's more than 750 objects based on rzambre's suggestion - // https://github.com/servo/servo/issues/10110 - self.parallel_flag = data.dom_count > 750; - debug!("layout: received layout request for: {}", self.url); - debug!("Number of objects in DOM: {}", data.dom_count); - debug!("layout: parallel? {}", self.parallel_flag); - let mut rw_data = possibly_locked_rw_data.lock(); - // Record the time that layout query has been waited. - let now = time::precise_time_ns(); - if let ReflowGoal::LayoutQuery(_, timestamp) = data.reflow_goal { - self.layout_query_waiting_time - .increment(now - timestamp) - .expect("layout: wrong layout query timestamp"); - }; - let element = match document.root_element() { None => { // Since we cannot compute anything, give spec-required placeholders. @@ -973,12 +935,6 @@ impl LayoutThread { Some(x) => x, }; - debug!( - "layout: processing reflow request for: {:?} ({}) (query={:?})", - element, self.url, data.reflow_goal - ); - trace!("{:?}", ShowSubtree(element.as_node())); - let initial_viewport = data.window_size.initial_viewport; let device_pixel_ratio = data.window_size.device_pixel_ratio; let old_viewport_size = self.viewport_size; @@ -1010,9 +966,6 @@ impl LayoutThread { self.stylist .viewport_constraints() .map_or(current_screen_size, |constraints| { - debug!("Viewport constraints: {:?}", constraints); - - // other rules are evaluated against the actual viewport Size2D::new( Au::from_f32_px(constraints.size.width), Au::from_f32_px(constraints.size.height), @@ -1038,38 +991,29 @@ impl LayoutThread { } } - { - if self.first_reflow.get() { - debug!("First reflow, rebuilding user and UA rules"); - for stylesheet in &ua_stylesheets.user_or_user_agent_stylesheets { - self.stylist - .append_stylesheet(stylesheet.clone(), &ua_or_user_guard); - self.handle_add_stylesheet(&stylesheet.0, &ua_or_user_guard); - } - - if self.stylist.quirks_mode() != QuirksMode::NoQuirks { - self.stylist.append_stylesheet( - ua_stylesheets.quirks_mode_stylesheet.clone(), - &ua_or_user_guard, - ); - self.handle_add_stylesheet( - &ua_stylesheets.quirks_mode_stylesheet.0, - &ua_or_user_guard, - ); - } + if self.first_reflow.get() { + for stylesheet in &ua_stylesheets.user_or_user_agent_stylesheets { + self.stylist + .append_stylesheet(stylesheet.clone(), &ua_or_user_guard); + self.handle_add_stylesheet(&stylesheet.0, &ua_or_user_guard); } - if data.stylesheets_changed { - debug!("Doc sheets changed, flushing author sheets too"); - self.stylist - .force_stylesheet_origins_dirty(Origin::Author.into()); + if self.stylist.quirks_mode() != QuirksMode::NoQuirks { + self.stylist.append_stylesheet( + ua_stylesheets.quirks_mode_stylesheet.clone(), + &ua_or_user_guard, + ); + self.handle_add_stylesheet( + &ua_stylesheets.quirks_mode_stylesheet.0, + &ua_or_user_guard, + ); } } - debug!( - "Shadow roots in document {:?}", - document.shadow_roots().len() - ); + if data.stylesheets_changed { + self.stylist + .force_stylesheet_origins_dirty(Origin::Author.into()); + } // Flush shadow roots stylesheets if dirty. document.flush_shadow_roots_stylesheets( @@ -1079,7 +1023,6 @@ impl LayoutThread { ); let restyles = document.drain_pending_restyles(); - debug!("Draining restyles: {}", restyles.len()); let mut map = SnapshotMap::new(); let elements_with_snapshot: Vec<_> = restyles @@ -1124,51 +1067,14 @@ impl LayoutThread { // Create a layout context for use throughout the following passes. let mut layout_context = self.build_layout_context(guards.clone(), &map); - let (thread_pool, num_threads) = if self.parallel_flag { - ( - STYLE_THREAD_POOL.style_thread_pool.as_ref(), - STYLE_THREAD_POOL.num_threads, - ) - } else { - (None, 1) - }; - - let traversal = RecalcStyleAndConstructFlows::new(layout_context); + let traversal = RecalcStyle::new(layout_context); let token = { - let shared = - <RecalcStyleAndConstructFlows as DomTraversal<ServoLayoutElement>>::shared_context( - &traversal, - ); - RecalcStyleAndConstructFlows::pre_traverse(element, shared) + let shared = DomTraversal::<ServoLayoutElement>::shared_context(&traversal); + RecalcStyle::pre_traverse(element, shared) }; if token.should_traverse() { - // Recalculate CSS styles and rebuild flows and fragments. - profile( - profile_time::ProfilerCategory::LayoutStyleRecalc, - self.profiler_metadata(), - self.time_profiler_chan.clone(), - || { - // Perform CSS selector matching and flow construction. - driver::traverse_dom::<ServoLayoutElement, RecalcStyleAndConstructFlows>( - &traversal, - token, - thread_pool, - ); - }, - ); - // TODO(pcwalton): Measure energy usage of text shaping, perhaps? - let text_shaping_time = - font::get_and_reset_text_shaping_performance_counter() / num_threads; - profile_time::send_profile_data( - profile_time::ProfilerCategory::LayoutTextShaping, - self.profiler_metadata(), - &self.time_profiler_chan, - 0, - text_shaping_time as u64, - 0, - 0, - ); + driver::traverse_dom(&traversal, token, None); } for element in elements_with_snapshot { |