aboutsummaryrefslogtreecommitdiffstats
path: root/components/shared/script_layout/message.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/shared/script_layout/message.rs')
-rw-r--r--components/shared/script_layout/message.rs260
1 files changed, 260 insertions, 0 deletions
diff --git a/components/shared/script_layout/message.rs b/components/shared/script_layout/message.rs
new file mode 100644
index 00000000000..01c5d58e659
--- /dev/null
+++ b/components/shared/script_layout/message.rs
@@ -0,0 +1,260 @@
+/* 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 std::sync::atomic::AtomicBool;
+use std::sync::Arc;
+
+use app_units::Au;
+use crossbeam_channel::{Receiver, Sender};
+use euclid::default::{Point2D, Rect};
+use gfx_traits::Epoch;
+use ipc_channel::ipc::{IpcReceiver, IpcSender};
+use malloc_size_of_derive::MallocSizeOf;
+use metrics::PaintTimeMetrics;
+use msg::constellation_msg::{BackgroundHangMonitorRegister, BrowsingContextId, PipelineId};
+use net_traits::image_cache::ImageCache;
+use profile_traits::mem::ReportsChan;
+use script_traits::{
+ ConstellationControlMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg, Painter, ScrollState,
+ WindowSizeData,
+};
+use servo_arc::Arc as ServoArc;
+use servo_atoms::Atom;
+use servo_url::{ImmutableOrigin, ServoUrl};
+use style::animation::DocumentAnimationSet;
+use style::context::QuirksMode;
+use style::dom::OpaqueNode;
+use style::invalidation::element::restyle_hints::RestyleHint;
+use style::properties::PropertyId;
+use style::selector_parser::{PseudoElement, RestyleDamage, Snapshot};
+use style::stylesheets::Stylesheet;
+
+use crate::rpc::LayoutRPC;
+use crate::{PendingImage, TrustedNodeAddress};
+
+/// Asynchronous messages that script can send to layout.
+pub enum Msg {
+ /// Adds the given stylesheet to the document. The second stylesheet is the
+ /// insertion point (if it exists, the sheet needs to be inserted before
+ /// it).
+ AddStylesheet(ServoArc<Stylesheet>, Option<ServoArc<Stylesheet>>),
+
+ /// Removes a stylesheet from the document.
+ RemoveStylesheet(ServoArc<Stylesheet>),
+
+ /// Change the quirks mode.
+ SetQuirksMode(QuirksMode),
+
+ /// Requests a reflow.
+ Reflow(ScriptReflow),
+
+ /// Get an RPC interface.
+ GetRPC(Sender<Box<dyn LayoutRPC + Send>>),
+
+ /// Requests that the layout thread measure its memory usage. The resulting reports are sent back
+ /// via the supplied channel.
+ CollectReports(ReportsChan),
+
+ /// Requests that the layout thread enter a quiescent state in which no more messages are
+ /// accepted except `ExitMsg`. A response message will be sent on the supplied channel when
+ /// this happens.
+ PrepareToExit(Sender<()>),
+
+ /// Requests that the layout thread immediately shut down. There must be no more nodes left after
+ /// this, or layout will crash.
+ ExitNow,
+
+ /// Get the last epoch counter for this layout thread.
+ GetCurrentEpoch(IpcSender<Epoch>),
+
+ /// Asks the layout thread whether any Web fonts have yet to load (if true, loads are pending;
+ /// false otherwise).
+ GetWebFontLoadState(IpcSender<bool>),
+
+ /// Creates a new layout thread.
+ ///
+ /// This basically exists to keep the script-layout dependency one-way.
+ CreateLayoutThread(LayoutThreadInit),
+
+ /// Set the final Url.
+ SetFinalUrl(ServoUrl),
+
+ /// Tells layout about the new scrolling offsets of each scrollable stacking context.
+ SetScrollStates(Vec<ScrollState>),
+
+ /// Tells layout that script has added some paint worklet modules.
+ RegisterPaint(Atom, Vec<Atom>, Box<dyn Painter>),
+
+ /// Send to layout the precise time when the navigation started.
+ SetNavigationStart(u64),
+}
+
+#[derive(Debug, PartialEq)]
+pub enum NodesFromPointQueryType {
+ All,
+ Topmost,
+}
+
+#[derive(Debug, PartialEq)]
+pub enum QueryMsg {
+ ContentBoxQuery(OpaqueNode),
+ ContentBoxesQuery(OpaqueNode),
+ ClientRectQuery(OpaqueNode),
+ ScrollingAreaQuery(Option<OpaqueNode>),
+ OffsetParentQuery(OpaqueNode),
+ TextIndexQuery(OpaqueNode, Point2D<f32>),
+ NodesFromPointQuery(Point2D<f32>, NodesFromPointQueryType),
+
+ // FIXME(nox): The following queries use the TrustedNodeAddress to
+ // access actual DOM nodes, but those values can be constructed from
+ // garbage values such as `0xdeadbeef as *const _`, this is unsound.
+ NodeScrollIdQuery(TrustedNodeAddress),
+ ResolvedStyleQuery(TrustedNodeAddress, Option<PseudoElement>, PropertyId),
+ StyleQuery,
+ ElementInnerTextQuery(TrustedNodeAddress),
+ ResolvedFontStyleQuery(TrustedNodeAddress, PropertyId, String),
+ InnerWindowDimensionsQuery(BrowsingContextId),
+}
+
+/// 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::NodesFromPointQuery(..) |
+ QueryMsg::TextIndexQuery(..) |
+ QueryMsg::InnerWindowDimensionsQuery(_) |
+ QueryMsg::ElementInnerTextQuery(_) => true,
+ QueryMsg::ContentBoxQuery(_) |
+ QueryMsg::ContentBoxesQuery(_) |
+ QueryMsg::ClientRectQuery(_) |
+ QueryMsg::ScrollingAreaQuery(_) |
+ QueryMsg::NodeScrollIdQuery(_) |
+ QueryMsg::ResolvedStyleQuery(..) |
+ QueryMsg::ResolvedFontStyleQuery(..) |
+ QueryMsg::OffsetParentQuery(_) |
+ 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::ContentBoxQuery(_) |
+ QueryMsg::ContentBoxesQuery(_) |
+ QueryMsg::ClientRectQuery(_) |
+ QueryMsg::ScrollingAreaQuery(_) |
+ QueryMsg::NodeScrollIdQuery(_) |
+ 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<Au>,
+}
+
+/// 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<PendingImage>,
+}
+
+/// 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<TrustedNodeAddress>,
+ /// 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<ReflowComplete>,
+ /// 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,
+}
+
+pub struct LayoutThreadInit {
+ pub id: PipelineId,
+ pub url: ServoUrl,
+ pub is_parent: bool,
+ pub layout_pair: (Sender<Msg>, Receiver<Msg>),
+ pub pipeline_port: IpcReceiver<LayoutControlMsg>,
+ pub background_hang_monitor_register: Box<dyn BackgroundHangMonitorRegister>,
+ pub constellation_chan: IpcSender<ConstellationMsg>,
+ pub script_chan: IpcSender<ConstellationControlMsg>,
+ pub image_cache: Arc<dyn ImageCache>,
+ pub paint_time_metrics: PaintTimeMetrics,
+ pub layout_is_busy: Arc<AtomicBool>,
+ pub window_size: WindowSizeData,
+}
+
+/// 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<Snapshot>,
+
+ /// 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 PendingRestyle {
+ /// Creates a new empty pending restyle.
+ #[inline]
+ pub fn new() -> Self {
+ PendingRestyle {
+ snapshot: None,
+ hint: RestyleHint::empty(),
+ damage: RestyleDamage::empty(),
+ }
+ }
+}