diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index d7d59f5a152..f941cc6a8bb 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -62,12 +62,10 @@ use profile_traits::time::{ self as profile_time, profile, TimerMetadata, TimerMetadataFrameType, TimerMetadataReflowType, }; use script::layout_dom::{ServoLayoutDocument, ServoLayoutElement, ServoLayoutNode}; -use script_layout_interface::message::{ - Msg, NodesFromPointQueryType, Reflow, ReflowComplete, ReflowGoal, ScriptReflow, -}; use script_layout_interface::wrapper_traits::LayoutNode; use script_layout_interface::{ - Layout, LayoutConfig, LayoutFactory, OffsetParentResponse, TrustedNodeAddress, + Layout, LayoutConfig, LayoutFactory, NodesFromPointQueryType, OffsetParentResponse, Reflow, + ReflowComplete, ReflowGoal, ScriptReflow, TrustedNodeAddress, }; use script_traits::{ ConstellationControlMsg, DrawAPaintImageResult, IFrameSizeMsg, LayoutControlMsg, @@ -252,10 +250,6 @@ impl Drop for ScriptReflowResult { } impl Layout for LayoutThread { - fn process(&mut self, msg: script_layout_interface::message::Msg) { - self.handle_request(Request::FromScript(msg)); - } - fn handle_constellation_msg(&mut self, msg: script_traits::LayoutControlMsg) { self.handle_request(Request::FromPipeline(msg)); } @@ -470,10 +464,94 @@ impl Layout for LayoutThread { ); self.indexable_text.borrow().text_index(node, point_in_node) } + + 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.root_flow.borrow_mut().take(); + } + + fn set_quirks_mode(&mut self, quirks_mode: QuirksMode) { + self.stylist.set_quirks_mode(quirks_mode); + } + + fn register_paint_worklet_modules( + &mut self, + name: Atom, + mut properties: Vec, + painter: Box, + ) { + debug!("Registering the painter"); + let properties = properties + .drain(..) + .filter_map(|name| { + let id = PropertyId::parse_enabled_for_all_content(&*name).ok()?; + Some((name.clone(), id)) + }) + .filter(|&(_, ref id)| !id.is_shorthand()) + .collect(); + let registered_painter = RegisteredPainterImpl { + name: name.clone(), + properties, + painter, + }; + self.registered_painters.0.insert(name, registered_painter); + } + + fn collect_reports(&self, reports_chan: ReportsChan) { + let mut reports = vec![]; + // Servo uses vanilla jemalloc, which doesn't have a + // malloc_enclosing_size_of function. + let mut ops = MallocSizeOfOps::new(servo_allocator::usable_size, None, None); + + // FIXME(njn): Just measuring the display tree for now. + let display_list = self.display_list.borrow(); + let display_list_ref = display_list.as_ref(); + let formatted_url = &format!("url({})", self.url); + reports.push(Report { + path: path![formatted_url, "layout-thread", "display-list"], + kind: ReportKind::ExplicitJemallocHeapSize, + size: display_list_ref.map_or(0, |sc| sc.size_of(&mut ops)), + }); + + reports.push(Report { + path: path![formatted_url, "layout-thread", "stylist"], + kind: ReportKind::ExplicitJemallocHeapSize, + size: self.stylist.size_of(&mut ops), + }); + + // The LayoutThread has data in Persistent TLS... + reports.push(Report { + path: path![formatted_url, "layout-thread", "local-context"], + kind: ReportKind::ExplicitJemallocHeapSize, + size: malloc_size_of_persistent_local_context(&mut ops), + }); + + reports_chan.send(reports); + } + + fn reflow(&mut self, script_reflow: script_layout_interface::ScriptReflow) { + let mut result = ScriptReflowResult::new(script_reflow); + profile( + profile_time::ProfilerCategory::LayoutPerform, + self.profiler_metadata(), + self.time_profiler_chan.clone(), + || self.handle_reflow(&mut result), + ); + } } enum Request { FromPipeline(LayoutControlMsg), - FromScript(Msg), FromFontCache, } @@ -610,114 +688,18 @@ impl LayoutThread { /// Receives and dispatches messages from the script and constellation threads fn handle_request(&mut self, request: Request) { match request { - Request::FromPipeline(LayoutControlMsg::SetScrollStates(new_scroll_states)) => { - self.handle_request_helper(Msg::SetScrollStates(new_scroll_states)) - }, - Request::FromPipeline(LayoutControlMsg::ExitNow) => { - self.handle_request_helper(Msg::ExitNow); - }, - Request::FromPipeline(LayoutControlMsg::PaintMetric(epoch, paint_time)) => { - self.paint_time_metrics.maybe_set_metric(epoch, paint_time); - }, - Request::FromScript(msg) => self.handle_request_helper(msg), Request::FromFontCache => { self.outstanding_web_fonts.fetch_sub(1, Ordering::SeqCst); self.handle_web_font_loaded(); }, - }; - } - - /// Receives and dispatches messages from other threads. - fn handle_request_helper(&mut self, request: Msg) { - match request { - Msg::SetQuirksMode(mode) => self.handle_set_quirks_mode(mode), - Msg::Reflow(data) => { - let mut data = ScriptReflowResult::new(data); - profile( - profile_time::ProfilerCategory::LayoutPerform, - self.profiler_metadata(), - self.time_profiler_chan.clone(), - || self.handle_reflow(&mut data), - ); - }, - Msg::SetScrollStates(new_scroll_states) => { + Request::FromPipeline(LayoutControlMsg::ExitNow) => self.exit_now(), + Request::FromPipeline(LayoutControlMsg::SetScrollStates(new_scroll_states)) => { self.set_scroll_states(new_scroll_states); }, - Msg::CollectReports(reports_chan) => { - self.collect_reports(reports_chan); + Request::FromPipeline(LayoutControlMsg::PaintMetric(epoch, paint_time)) => { + self.paint_time_metrics.maybe_set_metric(epoch, paint_time); }, - Msg::RegisterPaint(name, mut properties, painter) => { - debug!("Registering the painter"); - let properties = properties - .drain(..) - .filter_map(|name| { - let id = PropertyId::parse_enabled_for_all_content(&*name).ok()?; - Some((name.clone(), id)) - }) - .filter(|&(_, ref id)| !id.is_shorthand()) - .collect(); - let registered_painter = RegisteredPainterImpl { - name: name.clone(), - properties, - painter, - }; - self.registered_painters.0.insert(name, registered_painter); - }, - // Receiving the Exit message at this stage only happens when layout is undergoing a "force exit". - Msg::ExitNow => { - debug!("layout: ExitNow received"); - self.exit_now(); - }, - } - } - - fn collect_reports(&self, reports_chan: ReportsChan) { - let mut reports = vec![]; - // Servo uses vanilla jemalloc, which doesn't have a - // malloc_enclosing_size_of function. - let mut ops = MallocSizeOfOps::new(servo_allocator::usable_size, None, None); - - // FIXME(njn): Just measuring the display tree for now. - let display_list = self.display_list.borrow(); - let display_list_ref = display_list.as_ref(); - let formatted_url = &format!("url({})", self.url); - reports.push(Report { - path: path![formatted_url, "layout-thread", "display-list"], - kind: ReportKind::ExplicitJemallocHeapSize, - size: display_list_ref.map_or(0, |sc| sc.size_of(&mut ops)), - }); - - reports.push(Report { - path: path![formatted_url, "layout-thread", "stylist"], - kind: ReportKind::ExplicitJemallocHeapSize, - size: self.stylist.size_of(&mut ops), - }); - - // The LayoutThread has data in Persistent TLS... - reports.push(Report { - path: path![formatted_url, "layout-thread", "local-context"], - kind: ReportKind::ExplicitJemallocHeapSize, - size: malloc_size_of_persistent_local_context(&mut ops), - }); - - reports_chan.send(reports); - } - - /// Shuts down layout now. - 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.root_flow.borrow_mut().take(); + }; } fn load_all_web_fonts_from_stylesheet_with_guard( @@ -753,11 +735,6 @@ impl LayoutThread { .unwrap(); } - /// Sets quirks mode for the document, causing the quirks mode stylesheet to be used. - fn handle_set_quirks_mode(&mut self, quirks_mode: QuirksMode) { - self.stylist.set_quirks_mode(quirks_mode); - } - fn try_get_layout_root<'dom>(&self, node: impl LayoutNode<'dom>) -> Option { let result = node .to_threadsafe() diff --git a/components/layout_thread_2020/lib.rs b/components/layout_thread_2020/lib.rs index 49d08e6b4cb..1b9e1498d42 100644 --- a/components/layout_thread_2020/lib.rs +++ b/components/layout_thread_2020/lib.rs @@ -48,11 +48,9 @@ use profile_traits::time::{ self as profile_time, profile, TimerMetadata, TimerMetadataFrameType, TimerMetadataReflowType, }; use script::layout_dom::{ServoLayoutDocument, ServoLayoutElement, ServoLayoutNode}; -use script_layout_interface::message::{ - Msg, NodesFromPointQueryType, ReflowComplete, ReflowGoal, ScriptReflow, -}; use script_layout_interface::{ - Layout, LayoutConfig, LayoutFactory, OffsetParentResponse, TrustedNodeAddress, + Layout, LayoutConfig, LayoutFactory, NodesFromPointQueryType, OffsetParentResponse, + ReflowComplete, ReflowGoal, ScriptReflow, TrustedNodeAddress, }; use script_traits::{ ConstellationControlMsg, DrawAPaintImageResult, IFrameSizeMsg, LayoutControlMsg, @@ -227,10 +225,6 @@ impl Drop for ScriptReflowResult { } impl Layout for LayoutThread { - fn process(&mut self, msg: script_layout_interface::message::Msg) { - self.handle_request(Request::FromScript(msg)); - } - fn handle_constellation_msg(&mut self, msg: script_traits::LayoutControlMsg) { self.handle_request(Request::FromPipeline(msg)); } @@ -420,11 +414,57 @@ impl Layout for LayoutThread { ); process_text_index_request(node, point_in_node) } + + fn exit_now(&mut self) {} + + fn collect_reports(&self, reports_chan: ReportsChan) { + let mut reports = vec![]; + // Servo uses vanilla jemalloc, which doesn't have a + // malloc_enclosing_size_of function. + let mut ops = MallocSizeOfOps::new(servo_allocator::usable_size, None, None); + + // FIXME(njn): Just measuring the display tree for now. + let formatted_url = &format!("url({})", self.url); + reports.push(Report { + path: path![formatted_url, "layout-thread", "display-list"], + kind: ReportKind::ExplicitJemallocHeapSize, + size: 0, + }); + + reports.push(Report { + path: path![formatted_url, "layout-thread", "stylist"], + kind: ReportKind::ExplicitJemallocHeapSize, + size: self.stylist.size_of(&mut ops), + }); + + reports_chan.send(reports); + } + + fn set_quirks_mode(&mut self, quirks_mode: QuirksMode) { + self.stylist.set_quirks_mode(quirks_mode); + } + + fn reflow(&mut self, script_reflow: ScriptReflow) { + let mut result = ScriptReflowResult::new(script_reflow); + profile( + profile_time::ProfilerCategory::LayoutPerform, + self.profiler_metadata(), + self.time_profiler_chan.clone(), + || self.handle_reflow(&mut result), + ); + } + + fn register_paint_worklet_modules( + &mut self, + _name: Atom, + _properties: Vec, + _painter: Box, + ) { + } } enum Request { FromPipeline(LayoutControlMsg), - FromScript(Msg), FromFontCache, } @@ -558,15 +598,12 @@ impl LayoutThread { fn handle_request(&mut self, request: Request) { match request { Request::FromPipeline(LayoutControlMsg::SetScrollStates(new_scroll_states)) => { - self.handle_request_helper(Msg::SetScrollStates(new_scroll_states)) - }, - Request::FromPipeline(LayoutControlMsg::ExitNow) => { - self.handle_request_helper(Msg::ExitNow); + self.set_scroll_states(new_scroll_states); }, + Request::FromPipeline(LayoutControlMsg::ExitNow) => {}, Request::FromPipeline(LayoutControlMsg::PaintMetric(epoch, paint_time)) => { self.paint_time_metrics.maybe_set_metric(epoch, paint_time); }, - Request::FromScript(msg) => self.handle_request_helper(msg), Request::FromFontCache => { self.outstanding_web_fonts.fetch_sub(1, Ordering::SeqCst); self.handle_web_font_loaded(); @@ -574,54 +611,6 @@ impl LayoutThread { }; } - /// Receives and dispatches messages from other threads. - fn handle_request_helper(&mut self, request: Msg) { - match request { - Msg::SetQuirksMode(mode) => self.handle_set_quirks_mode(mode), - Msg::Reflow(data) => { - let mut data = ScriptReflowResult::new(data); - profile( - profile_time::ProfilerCategory::LayoutPerform, - self.profiler_metadata(), - self.time_profiler_chan.clone(), - || self.handle_reflow(&mut data), - ); - }, - Msg::SetScrollStates(new_scroll_states) => { - self.set_scroll_states(new_scroll_states); - }, - Msg::CollectReports(reports_chan) => { - self.collect_reports(reports_chan); - }, - Msg::RegisterPaint(_name, _properties, _painter) => {}, - // Receiving the Exit message at this stage only happens when layout is undergoing a "force exit". - Msg::ExitNow => {}, - } - } - - fn collect_reports(&self, reports_chan: ReportsChan) { - let mut reports = vec![]; - // Servo uses vanilla jemalloc, which doesn't have a - // malloc_enclosing_size_of function. - let mut ops = MallocSizeOfOps::new(servo_allocator::usable_size, None, None); - - // FIXME(njn): Just measuring the display tree for now. - let formatted_url = &format!("url({})", self.url); - reports.push(Report { - path: path![formatted_url, "layout-thread", "display-list"], - kind: ReportKind::ExplicitJemallocHeapSize, - size: 0, - }); - - reports.push(Report { - path: path![formatted_url, "layout-thread", "stylist"], - kind: ReportKind::ExplicitJemallocHeapSize, - size: self.stylist.size_of(&mut ops), - }); - - reports_chan.send(reports); - } - fn load_all_web_fonts_from_stylesheet_with_guard( &self, stylesheet: &Stylesheet, @@ -657,11 +646,6 @@ impl LayoutThread { .unwrap(); } - /// Sets quirks mode for the document, causing the quirks mode stylesheet to be used. - fn handle_set_quirks_mode(&mut self, quirks_mode: QuirksMode) { - self.stylist.set_quirks_mode(quirks_mode); - } - /// The high-level routine that performs layout. fn handle_reflow(&mut self, data: &mut ScriptReflowResult) { let document = unsafe { ServoLayoutNode::new(&data.document) }; diff --git a/components/script/dom/activation.rs b/components/script/dom/activation.rs index 0880d1fdb64..f337560dbfe 100644 --- a/components/script/dom/activation.rs +++ b/components/script/dom/activation.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use script_layout_interface::message::ReflowGoal; +use script_layout_interface::ReflowGoal; use crate::dom::element::Element; use crate::dom::event::Event; diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index c66b82619ea..8ac19c20244 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -44,8 +44,7 @@ use num_traits::ToPrimitive; use percent_encoding::percent_decode; use profile_traits::ipc as profile_ipc; use profile_traits::time::{TimerMetadata, TimerMetadataFrameType, TimerMetadataReflowType}; -use script_layout_interface::message::{Msg, PendingRestyle, ReflowGoal}; -use script_layout_interface::TrustedNodeAddress; +use script_layout_interface::{PendingRestyle, ReflowGoal, TrustedNodeAddress}; use script_traits::{ AnimationState, DocumentActivity, MouseButton, MouseEventType, MsDuration, ScriptMsg, TouchEventType, TouchId, UntrustedNodeAddress, WheelDelta, @@ -841,7 +840,7 @@ impl Document { if old_mode != new_mode { let _ = self .window - .with_layout(move |layout| layout.process(Msg::SetQuirksMode(new_mode))); + .with_layout(move |layout| layout.set_quirks_mode(new_mode)); } } diff --git a/components/script/dom/documentorshadowroot.rs b/components/script/dom/documentorshadowroot.rs index 59e84acf13c..25ada1eddae 100644 --- a/components/script/dom/documentorshadowroot.rs +++ b/components/script/dom/documentorshadowroot.rs @@ -5,7 +5,7 @@ use std::fmt; use euclid::default::Point2D; -use script_layout_interface::message::{NodesFromPointQueryType, QueryMsg}; +use script_layout_interface::{NodesFromPointQueryType, QueryMsg}; use script_traits::UntrustedNodeAddress; use servo_arc::Arc; use servo_atoms::Atom; diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index e6879bb17e6..8edf819325c 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -28,7 +28,7 @@ use js::rust::HandleObject; use msg::constellation_msg::InputMethodType; use net_traits::request::CorsSettings; use net_traits::ReferrerPolicy; -use script_layout_interface::message::ReflowGoal; +use script_layout_interface::ReflowGoal; use selectors::attr::{AttrSelectorOperation, CaseSensitivity, NamespaceConstraint}; use selectors::bloom::{BloomFilter, BLOOM_HASH_MASK}; use selectors::matching::{ElementSelectorFlags, MatchingContext}; diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs index 9b84e9dbe29..3a7bd467215 100644 --- a/components/script/dom/htmlelement.rs +++ b/components/script/dom/htmlelement.rs @@ -9,7 +9,7 @@ use std::rc::Rc; use dom_struct::dom_struct; use html5ever::{local_name, namespace_url, ns, LocalName, Prefix}; use js::rust::HandleObject; -use script_layout_interface::message::QueryMsg; +use script_layout_interface::QueryMsg; use style::attr::AttrValue; use style_traits::dom::ElementState; diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 6d2cd80689a..cb84aa7bb52 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -10,7 +10,7 @@ use html5ever::{local_name, namespace_url, ns, LocalName, Prefix}; use js::rust::HandleObject; use msg::constellation_msg::{BrowsingContextId, PipelineId, TopLevelBrowsingContextId}; use profile_traits::ipc as ProfiledIpc; -use script_layout_interface::message::ReflowGoal; +use script_layout_interface::ReflowGoal; use script_traits::IFrameSandboxState::{IFrameSandboxed, IFrameUnsandboxed}; use script_traits::{ HistoryEntryReplacement, IFrameLoadInfo, IFrameLoadInfoWithData, JsEvalResult, LoadData, diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 783c62204ce..2ddd18f9503 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -24,9 +24,8 @@ use libc::{self, c_void, uintptr_t}; use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; use msg::constellation_msg::{BrowsingContextId, PipelineId}; use net_traits::image::base::{Image, ImageMetadata}; -use script_layout_interface::message::QueryMsg; use script_layout_interface::{ - GenericLayoutData, HTMLCanvasData, HTMLMediaData, LayoutElementType, LayoutNodeType, + GenericLayoutData, HTMLCanvasData, HTMLMediaData, LayoutElementType, LayoutNodeType, QueryMsg, SVGSVGData, StyleData, TrustedNodeAddress, }; use script_traits::{DocumentActivity, UntrustedNodeAddress}; diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 268efc862ba..a8067c6d240 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -49,8 +49,9 @@ use parking_lot::Mutex as ParkMutex; use profile_traits::ipc as ProfiledIpc; use profile_traits::mem::ProfilerChan as MemProfilerChan; use profile_traits::time::ProfilerChan as TimeProfilerChan; -use script_layout_interface::message::{Msg, QueryMsg, Reflow, ReflowGoal, ScriptReflow}; -use script_layout_interface::{Layout, PendingImageState, TrustedNodeAddress}; +use script_layout_interface::{ + Layout, PendingImageState, QueryMsg, Reflow, ReflowGoal, ScriptReflow, TrustedNodeAddress, +}; use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult}; use script_traits::{ ConstellationControlMsg, DocumentState, HistoryEntryReplacement, LoadData, ScriptMsg, @@ -1875,7 +1876,7 @@ impl Window { animations: document.animations().sets.clone(), }; - let _ = self.with_layout(move |layout| layout.process(Msg::Reflow(reflow))); + let _ = self.with_layout(move |layout| layout.reflow(reflow)); let complete = match join_port.try_recv() { Err(TryRecvError::Empty) => { diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index ccd867c1bb7..1991d30ae95 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -71,8 +71,9 @@ use parking_lot::Mutex; use percent_encoding::percent_decode; use profile_traits::mem::{self as profile_mem, OpaqueSender, ReportsChan}; use profile_traits::time::{self as profile_time, profile, ProfilerCategory}; -use script_layout_interface::message::{Msg, ReflowGoal}; -use script_layout_interface::{Layout, LayoutConfig, LayoutFactory, ScriptThreadFactory}; +use script_layout_interface::{ + Layout, LayoutConfig, LayoutFactory, ReflowGoal, ScriptThreadFactory, +}; use script_traits::webdriver_msg::WebDriverScriptCommand; use script_traits::CompositorEvent::{ CompositionEvent, GamepadEvent, IMEDismissedEvent, KeyboardEvent, MouseButtonEvent, @@ -1210,7 +1211,7 @@ impl ScriptThread { }; let _ = window - .with_layout(|layout| layout.process(Msg::RegisterPaint(name, properties, painter))); + .with_layout(|layout| layout.register_paint_worklet_modules(name, properties, painter)); } pub fn push_new_element_queue() { @@ -2907,9 +2908,7 @@ impl ScriptThread { } debug!("{id}: Shutting down layout"); - let _ = document.window().with_layout(|layout| { - layout.process(Msg::ExitNow); - }); + let _ = document.window().with_layout(|layout| layout.exit_now()); debug!("{id}: Sending PipelineExited message to constellation"); self.script_sender diff --git a/components/shared/msg/constellation_msg.rs b/components/shared/msg/constellation_msg.rs index 6893957f46b..93c18790255 100644 --- a/components/shared/msg/constellation_msg.rs +++ b/components/shared/msg/constellation_msg.rs @@ -465,24 +465,6 @@ pub enum InputMethodType { Week, } -#[derive(Clone, Copy, Debug, Deserialize, Serialize)] -/// The equivalent of script_layout_interface::message::Msg -pub enum LayoutHangAnnotation { - AddStylesheet, - RemoveStylesheet, - SetQuirksMode, - Reflow, - CollectReports, - ExitNow, - GetCurrentEpoch, - GetWebFontLoadState, - CreateLayoutThread, - SetFinalUrl, - SetScrollStates, - UpdateScrollStateFromScript, - RegisterPaint, -} - #[derive(Clone, Copy, Debug, Deserialize, Serialize)] /// The equivalent of script::script_runtime::ScriptEventCategory pub enum ScriptHangAnnotation { @@ -518,7 +500,6 @@ pub enum ScriptHangAnnotation { #[derive(Clone, Copy, Debug, Deserialize, Serialize)] pub enum HangAnnotation { - Layout(LayoutHangAnnotation), Script(ScriptHangAnnotation), } diff --git a/components/shared/script_layout/lib.rs b/components/shared/script_layout/lib.rs index b36c0c4ef56..e6d91ee86a0 100644 --- a/components/shared/script_layout/lib.rs +++ b/components/shared/script_layout/lib.rs @@ -8,7 +8,6 @@ #![deny(unsafe_code)] -pub mod message; pub mod wrapper_traits; use std::any::Any; @@ -19,6 +18,7 @@ use std::sync::Arc; use app_units::Au; use atomic_refcell::AtomicRefCell; use canvas_traits::canvas::{CanvasId, CanvasMsg}; +use crossbeam_channel::Sender; use euclid::default::{Point2D, Rect}; use euclid::Size2D; use gfx::font_cache_thread::FontCacheThread; @@ -26,25 +26,28 @@ use gfx_traits::Epoch; use ipc_channel::ipc::IpcSender; use libc::c_void; use malloc_size_of_derive::MallocSizeOf; -use message::NodesFromPointQueryType; use metrics::PaintTimeMetrics; use msg::constellation_msg::{BrowsingContextId, PipelineId}; use net_traits::image_cache::{ImageCache, PendingImageId}; +use profile_traits::mem::ReportsChan; use profile_traits::time; use script_traits::{ - ConstellationControlMsg, InitialScriptState, LayoutControlMsg, LayoutMsg, LoadData, - UntrustedNodeAddress, WebrenderIpcSender, WindowSizeData, + ConstellationControlMsg, InitialScriptState, LayoutControlMsg, LayoutMsg, LoadData, Painter, + ScrollState, UntrustedNodeAddress, WebrenderIpcSender, WindowSizeData, }; use servo_arc::Arc as ServoArc; use servo_url::{ImmutableOrigin, ServoUrl}; use style::animation::DocumentAnimationSet; +use style::context::QuirksMode; use style::data::ElementData; use style::dom::OpaqueNode; +use style::invalidation::element::restyle_hints::RestyleHint; use style::media_queries::Device; use style::properties::style_structs::Font; use style::properties::PropertyId; -use style::selector_parser::PseudoElement; +use style::selector_parser::{PseudoElement, RestyleDamage, Snapshot}; use style::stylesheets::Stylesheet; +use style::Atom; use style_traits::CSSPixel; use webrender_api::ImageKey; @@ -171,9 +174,6 @@ pub trait LayoutFactory: Send + Sync { } pub trait Layout { - /// Process a single message from script. - fn process(&mut self, msg: message::Msg); - /// Handle a single message from the Constellation. fn handle_constellation_msg(&mut self, msg: LayoutControlMsg); @@ -203,9 +203,30 @@ pub trait Layout { before_stylsheet: Option>, ); + /// Inform the layout that its ScriptThread is about to exit. + fn exit_now(&mut self); + + /// Requests that layout measure its memory usage. The resulting reports are sent back + /// via the supplied channel. + fn collect_reports(&self, reports_chan: ReportsChan); + + /// Sets quirks mode for the document, causing the quirks mode stylesheet to be used. + fn set_quirks_mode(&mut self, quirks_mode: QuirksMode); + /// Removes a stylesheet from the Layout. fn remove_stylesheet(&mut self, stylesheet: ServoArc); + /// Requests a reflow. + fn reflow(&mut self, script_reflow: ScriptReflow); + + /// Tells layout that script has added some paint worklet modules. + fn register_paint_worklet_modules( + &mut self, + name: Atom, + properties: Vec, + painter: Box, + ); + fn query_content_box(&self, node: OpaqueNode) -> Option>; fn query_content_boxes(&self, node: OpaqueNode) -> Vec>; fn query_client_rect(&self, node: OpaqueNode) -> Rect; @@ -257,3 +278,138 @@ pub struct OffsetParentResponse { pub node_address: Option, pub rect: Rect, } + +#[derive(Debug, PartialEq)] +pub enum NodesFromPointQueryType { + All, + Topmost, +} + +#[derive(Debug, PartialEq)] +pub enum QueryMsg { + ContentBox, + ContentBoxes, + ClientRectQuery, + ScrollingAreaQuery, + OffsetParentQuery, + TextIndexQuery, + NodesFromPointQuery, + ResolvedStyleQuery, + StyleQuery, + ElementInnerTextQuery, + ResolvedFontStyleQuery, + InnerWindowDimensionsQuery, +} + +/// Any query to perform with this reflow. +#[derive(Debug, PartialEq)] +pub enum ReflowGoal { + Full, + TickAnimations, + LayoutQuery(QueryMsg, u64), + + /// Tells layout about a single new scrolling offset from the script. The rest will + /// remain untouched and layout won't forward this back to script. + UpdateScrollNode(ScrollState), +} + +impl ReflowGoal { + /// Returns true if the given ReflowQuery needs a full, up-to-date display list to + /// be present or false if it only needs stacking-relative positions. + pub fn needs_display_list(&self) -> bool { + match *self { + ReflowGoal::Full | ReflowGoal::TickAnimations | ReflowGoal::UpdateScrollNode(_) => true, + ReflowGoal::LayoutQuery(ref querymsg, _) => match *querymsg { + QueryMsg::ElementInnerTextQuery | + QueryMsg::InnerWindowDimensionsQuery | + QueryMsg::NodesFromPointQuery | + QueryMsg::ResolvedStyleQuery | + QueryMsg::TextIndexQuery => true, + QueryMsg::ClientRectQuery | + QueryMsg::ContentBox | + QueryMsg::ContentBoxes | + QueryMsg::OffsetParentQuery | + QueryMsg::ResolvedFontStyleQuery | + QueryMsg::ScrollingAreaQuery | + QueryMsg::StyleQuery => false, + }, + } + } + + /// Returns true if the given ReflowQuery needs its display list send to WebRender or + /// false if a layout_thread display list is sufficient. + pub fn needs_display(&self) -> bool { + match *self { + ReflowGoal::Full | ReflowGoal::TickAnimations | ReflowGoal::UpdateScrollNode(_) => true, + ReflowGoal::LayoutQuery(ref querymsg, _) => match *querymsg { + QueryMsg::NodesFromPointQuery | + QueryMsg::TextIndexQuery | + QueryMsg::ElementInnerTextQuery => true, + QueryMsg::ContentBox | + QueryMsg::ContentBoxes | + QueryMsg::ClientRectQuery | + QueryMsg::ScrollingAreaQuery | + QueryMsg::ResolvedStyleQuery | + QueryMsg::ResolvedFontStyleQuery | + QueryMsg::OffsetParentQuery | + QueryMsg::InnerWindowDimensionsQuery | + QueryMsg::StyleQuery => false, + }, + } + } +} + +/// Information needed for a reflow. +pub struct Reflow { + /// A clipping rectangle for the page, an enlarged rectangle containing the viewport. + pub page_clip_rect: Rect, +} + +/// Information derived from a layout pass that needs to be returned to the script thread. +#[derive(Default)] +pub struct ReflowComplete { + /// The list of images that were encountered that are in progress. + pub pending_images: Vec, +} + +/// Information needed for a script-initiated reflow. +pub struct ScriptReflow { + /// General reflow data. + pub reflow_info: Reflow, + /// The document node. + pub document: TrustedNodeAddress, + /// The dirty root from which to restyle. + pub dirty_root: Option, + /// Whether the document's stylesheets have changed since the last script reflow. + pub stylesheets_changed: bool, + /// The current window size. + pub window_size: WindowSizeData, + /// The channel that we send a notification to. + pub script_join_chan: Sender, + /// The goal of this reflow. + pub reflow_goal: ReflowGoal, + /// The number of objects in the dom #10110 + pub dom_count: u32, + /// The current window origin + pub origin: ImmutableOrigin, + /// Restyle snapshot map. + pub pending_restyles: Vec<(TrustedNodeAddress, PendingRestyle)>, + /// The current animation timeline value. + pub animation_timeline_value: f64, + /// The set of animations for this document. + pub animations: DocumentAnimationSet, +} + +/// A pending restyle. +#[derive(Debug, Default, MallocSizeOf)] +pub struct PendingRestyle { + /// If this element had a state or attribute change since the last restyle, track + /// the original condition of the element. + pub snapshot: Option, + + /// Any explicit restyles hints that have been accumulated for this element. + pub hint: RestyleHint, + + /// Any explicit restyles damage that have been accumulated for this element. + pub damage: RestyleDamage, +} diff --git a/components/shared/script_layout/message.rs b/components/shared/script_layout/message.rs deleted file mode 100644 index 018e554e893..00000000000 --- a/components/shared/script_layout/message.rs +++ /dev/null @@ -1,188 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ - -use app_units::Au; -use crossbeam_channel::Sender; -use euclid::default::Rect; -use malloc_size_of_derive::MallocSizeOf; -use profile_traits::mem::ReportsChan; -use script_traits::{Painter, ScrollState, WindowSizeData}; -use servo_atoms::Atom; -use servo_url::ImmutableOrigin; -use style::animation::DocumentAnimationSet; -use style::context::QuirksMode; -use style::invalidation::element::restyle_hints::RestyleHint; -use style::selector_parser::{RestyleDamage, Snapshot}; - -use crate::{PendingImage, TrustedNodeAddress}; - -/// Asynchronous messages that script can send to layout. -pub enum Msg { - /// Change the quirks mode. - SetQuirksMode(QuirksMode), - - /// Requests a reflow. - Reflow(ScriptReflow), - - /// Requests that layout measure its memory usage. The resulting reports are sent back - /// via the supplied channel. - CollectReports(ReportsChan), - - /// Requests that layout immediately shut down. There must be no more nodes left after - /// this, or layout will crash. - ExitNow, - - /// Tells layout about the new scrolling offsets of each scrollable stacking context. - SetScrollStates(Vec), - - /// Tells layout that script has added some paint worklet modules. - RegisterPaint(Atom, Vec, Box), -} - -#[derive(Debug, PartialEq)] -pub enum NodesFromPointQueryType { - All, - Topmost, -} - -#[derive(Debug, PartialEq)] -pub enum QueryMsg { - ContentBox, - ContentBoxes, - ClientRectQuery, - ScrollingAreaQuery, - OffsetParentQuery, - TextIndexQuery, - NodesFromPointQuery, - ResolvedStyleQuery, - StyleQuery, - ElementInnerTextQuery, - ResolvedFontStyleQuery, - InnerWindowDimensionsQuery, -} - -/// Any query to perform with this reflow. -#[derive(Debug, PartialEq)] -pub enum ReflowGoal { - Full, - TickAnimations, - LayoutQuery(QueryMsg, u64), - - /// Tells layout about a single new scrolling offset from the script. The rest will - /// remain untouched and layout won't forward this back to script. - UpdateScrollNode(ScrollState), -} - -impl ReflowGoal { - /// Returns true if the given ReflowQuery needs a full, up-to-date display list to - /// be present or false if it only needs stacking-relative positions. - pub fn needs_display_list(&self) -> bool { - match *self { - ReflowGoal::Full | ReflowGoal::TickAnimations | ReflowGoal::UpdateScrollNode(_) => true, - ReflowGoal::LayoutQuery(ref querymsg, _) => match *querymsg { - QueryMsg::ElementInnerTextQuery | - QueryMsg::InnerWindowDimensionsQuery | - QueryMsg::NodesFromPointQuery | - QueryMsg::ResolvedStyleQuery | - QueryMsg::TextIndexQuery => true, - QueryMsg::ClientRectQuery | - QueryMsg::ContentBox | - QueryMsg::ContentBoxes | - QueryMsg::OffsetParentQuery | - QueryMsg::ResolvedFontStyleQuery | - QueryMsg::ScrollingAreaQuery | - QueryMsg::StyleQuery => false, - }, - } - } - - /// Returns true if the given ReflowQuery needs its display list send to WebRender or - /// false if a layout_thread display list is sufficient. - pub fn needs_display(&self) -> bool { - match *self { - ReflowGoal::Full | ReflowGoal::TickAnimations | ReflowGoal::UpdateScrollNode(_) => true, - ReflowGoal::LayoutQuery(ref querymsg, _) => match *querymsg { - QueryMsg::NodesFromPointQuery | - QueryMsg::TextIndexQuery | - QueryMsg::ElementInnerTextQuery => true, - QueryMsg::ContentBox | - QueryMsg::ContentBoxes | - QueryMsg::ClientRectQuery | - QueryMsg::ScrollingAreaQuery | - QueryMsg::ResolvedStyleQuery | - QueryMsg::ResolvedFontStyleQuery | - QueryMsg::OffsetParentQuery | - QueryMsg::InnerWindowDimensionsQuery | - QueryMsg::StyleQuery => false, - }, - } - } -} - -/// Information needed for a reflow. -pub struct Reflow { - /// A clipping rectangle for the page, an enlarged rectangle containing the viewport. - pub page_clip_rect: Rect, -} - -/// Information derived from a layout pass that needs to be returned to the script thread. -#[derive(Default)] -pub struct ReflowComplete { - /// The list of images that were encountered that are in progress. - pub pending_images: Vec, -} - -/// Information needed for a script-initiated reflow. -pub struct ScriptReflow { - /// General reflow data. - pub reflow_info: Reflow, - /// The document node. - pub document: TrustedNodeAddress, - /// The dirty root from which to restyle. - pub dirty_root: Option, - /// Whether the document's stylesheets have changed since the last script reflow. - pub stylesheets_changed: bool, - /// The current window size. - pub window_size: WindowSizeData, - /// The channel that we send a notification to. - pub script_join_chan: Sender, - /// The goal of this reflow. - pub reflow_goal: ReflowGoal, - /// The number of objects in the dom #10110 - pub dom_count: u32, - /// The current window origin - pub origin: ImmutableOrigin, - /// Restyle snapshot map. - pub pending_restyles: Vec<(TrustedNodeAddress, PendingRestyle)>, - /// The current animation timeline value. - pub animation_timeline_value: f64, - /// The set of animations for this document. - pub animations: DocumentAnimationSet, -} - -/// A pending restyle. -#[derive(Debug, MallocSizeOf)] -pub struct PendingRestyle { - /// If this element had a state or attribute change since the last restyle, track - /// the original condition of the element. - pub snapshot: Option, - - /// Any explicit restyles hints that have been accumulated for this element. - pub hint: RestyleHint, - - /// Any explicit restyles damage that have been accumulated for this element. - pub damage: RestyleDamage, -} - -impl Default for PendingRestyle { - /// Creates a new empty pending restyle. - #[inline] - fn default() -> Self { - Self { - snapshot: None, - hint: RestyleHint::empty(), - damage: RestyleDamage::empty(), - } - } -}