1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 use {OpaqueStyleAndLayoutData, TrustedNodeAddress, PendingImage};
6 use app_units::Au;
7 use euclid::{Point2D, Rect};
8 use gfx_traits::Epoch;
9 use ipc_channel::ipc::{IpcReceiver, IpcSender};
10 use metrics::PaintTimeMetrics;
11 use msg::constellation_msg::PipelineId;
12 use net_traits::image_cache::ImageCache;
13 use profile_traits::mem::ReportsChan;
14 use rpc::LayoutRPC;
15 use script_traits::{ConstellationControlMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg};
16 use script_traits::{ScrollState, UntrustedNodeAddress, WindowSizeData};
17 use script_traits::Painter;
18 use servo_arc::Arc as ServoArc;
19 use servo_atoms::Atom;
20 use servo_url::ServoUrl;
21 use std::sync::Arc;
22 use std::sync::mpsc::{Receiver, Sender};
23 use style::context::QuirksMode;
24 use style::properties::PropertyId;
25 use style::selector_parser::PseudoElement;
26 use style::stylesheets::Stylesheet;
27 
28 /// Asynchronous messages that script can send to layout.
29 pub enum Msg {
30     /// Adds the given stylesheet to the document. The second stylesheet is the
31     /// insertion point (if it exists, the sheet needs to be inserted before
32     /// it).
33     AddStylesheet(ServoArc<Stylesheet>, Option<ServoArc<Stylesheet>>),
34 
35     /// Removes a stylesheet from the document.
36     RemoveStylesheet(ServoArc<Stylesheet>),
37 
38     /// Change the quirks mode.
39     SetQuirksMode(QuirksMode),
40 
41     /// Requests a reflow.
42     Reflow(ScriptReflow),
43 
44     /// Get an RPC interface.
45     GetRPC(Sender<Box<LayoutRPC + Send>>),
46 
47     /// Requests that the layout thread render the next frame of all animations.
48     TickAnimations,
49 
50     /// Updates layout's timer for animation testing from script.
51     ///
52     /// The inner field is the number of *milliseconds* to advance, and the bool
53     /// field is whether animations should be force-ticked.
54     AdvanceClockMs(i32, bool),
55 
56     /// Destroys layout data associated with a DOM node.
57     ///
58     /// TODO(pcwalton): Maybe think about batching to avoid message traffic.
59     ReapStyleAndLayoutData(OpaqueStyleAndLayoutData),
60 
61     /// Requests that the layout thread measure its memory usage. The resulting reports are sent back
62     /// via the supplied channel.
63     CollectReports(ReportsChan),
64 
65     /// Requests that the layout thread enter a quiescent state in which no more messages are
66     /// accepted except `ExitMsg`. A response message will be sent on the supplied channel when
67     /// this happens.
68     PrepareToExit(Sender<()>),
69 
70     /// Requests that the layout thread immediately shut down. There must be no more nodes left after
71     /// this, or layout will crash.
72     ExitNow,
73 
74     /// Get the last epoch counter for this layout thread.
75     GetCurrentEpoch(IpcSender<Epoch>),
76 
77     /// Asks the layout thread whether any Web fonts have yet to load (if true, loads are pending;
78     /// false otherwise).
79     GetWebFontLoadState(IpcSender<bool>),
80 
81     /// Creates a new layout thread.
82     ///
83     /// This basically exists to keep the script-layout dependency one-way.
84     CreateLayoutThread(NewLayoutThreadInfo),
85 
86     /// Set the final Url.
87     SetFinalUrl(ServoUrl),
88 
89     /// Tells layout about the new scrolling offsets of each scrollable stacking context.
90     SetScrollStates(Vec<ScrollState>),
91 
92     /// Tells layout about a single new scrolling offset from the script. The rest will
93     /// remain untouched and layout won't forward this back to script.
94     UpdateScrollStateFromScript(ScrollState),
95 
96     /// Tells layout that script has added some paint worklet modules.
97     RegisterPaint(Atom, Vec<Atom>, Box<Painter>),
98 
99     /// Send to layout the precise time when the navigation started.
100     SetNavigationStart(u64),
101 }
102 
103 #[derive(Debug, PartialEq)]
104 pub enum NodesFromPointQueryType {
105     All,
106     Topmost,
107 }
108 
109 /// Any query to perform with this reflow.
110 #[derive(Debug, PartialEq)]
111 pub enum ReflowGoal {
112     Full,
113     TickAnimations,
114     ContentBoxQuery(TrustedNodeAddress),
115     ContentBoxesQuery(TrustedNodeAddress),
116     NodeScrollIdQuery(TrustedNodeAddress),
117     NodeGeometryQuery(TrustedNodeAddress),
118     NodeScrollGeometryQuery(TrustedNodeAddress),
119     ResolvedStyleQuery(TrustedNodeAddress, Option<PseudoElement>, PropertyId),
120     OffsetParentQuery(TrustedNodeAddress),
121     StyleQuery(TrustedNodeAddress),
122     TextIndexQuery(TrustedNodeAddress, Point2D<f32>),
123     NodesFromPointQuery(Point2D<f32>, NodesFromPointQueryType),
124     ElementInnerTextQuery(TrustedNodeAddress),
125 }
126 
127 impl ReflowGoal {
128     /// Returns true if the given ReflowQuery needs a full, up-to-date display list to
129     /// be present or false if it only needs stacking-relative positions.
needs_display_list(&self) -> bool130     pub fn needs_display_list(&self) -> bool {
131         match *self {
132             ReflowGoal::NodesFromPointQuery(..) | ReflowGoal::TextIndexQuery(..) |
133             ReflowGoal::TickAnimations | ReflowGoal::ElementInnerTextQuery(_) |
134             ReflowGoal::Full => true,
135             ReflowGoal::ContentBoxQuery(_) | ReflowGoal::ContentBoxesQuery(_) |
136             ReflowGoal::NodeGeometryQuery(_) | ReflowGoal::NodeScrollGeometryQuery(_) |
137             ReflowGoal::NodeScrollIdQuery(_) |
138             ReflowGoal::ResolvedStyleQuery(..) | ReflowGoal::OffsetParentQuery(_) |
139             ReflowGoal::StyleQuery(_) => false,
140         }
141     }
142 
143     /// Returns true if the given ReflowQuery needs its display list send to WebRender or
144     /// false if a layout_thread display list is sufficient.
needs_display(&self) -> bool145     pub fn needs_display(&self) -> bool {
146         match *self {
147             ReflowGoal::StyleQuery(_)  | ReflowGoal::TextIndexQuery(..) |
148             ReflowGoal::ContentBoxQuery(_) | ReflowGoal::ContentBoxesQuery(_) |
149             ReflowGoal::NodeGeometryQuery(_) | ReflowGoal::NodeScrollGeometryQuery(_) |
150             ReflowGoal::NodeScrollIdQuery(_) | ReflowGoal::ResolvedStyleQuery(..) |
151             ReflowGoal::OffsetParentQuery(_) => false,
152             ReflowGoal::NodesFromPointQuery(..) | ReflowGoal::Full |
153             ReflowGoal::ElementInnerTextQuery(_) |
154             ReflowGoal::TickAnimations => true,
155         }
156     }
157 }
158 
159 /// Information needed for a reflow.
160 pub struct Reflow {
161     ///  A clipping rectangle for the page, an enlarged rectangle containing the viewport.
162     pub page_clip_rect: Rect<Au>,
163 }
164 
165 /// Information derived from a layout pass that needs to be returned to the script thread.
166 #[derive(Default)]
167 pub struct ReflowComplete {
168     /// The list of images that were encountered that are in progress.
169     pub pending_images: Vec<PendingImage>,
170     /// The list of nodes that initiated a CSS transition.
171     pub newly_transitioning_nodes: Vec<UntrustedNodeAddress>,
172 }
173 
174 /// Information needed for a script-initiated reflow.
175 pub struct ScriptReflow {
176     /// General reflow data.
177     pub reflow_info: Reflow,
178     /// The document node.
179     pub document: TrustedNodeAddress,
180     /// Whether the document's stylesheets have changed since the last script reflow.
181     pub stylesheets_changed: bool,
182     /// The current window size.
183     pub window_size: WindowSizeData,
184     /// The channel that we send a notification to.
185     pub script_join_chan: Sender<ReflowComplete>,
186     /// The goal of this reflow.
187     pub reflow_goal: ReflowGoal,
188     /// The number of objects in the dom #10110
189     pub dom_count: u32,
190 }
191 
192 pub struct NewLayoutThreadInfo {
193     pub id: PipelineId,
194     pub url: ServoUrl,
195     pub is_parent: bool,
196     pub layout_pair: (Sender<Msg>, Receiver<Msg>),
197     pub pipeline_port: IpcReceiver<LayoutControlMsg>,
198     pub constellation_chan: IpcSender<ConstellationMsg>,
199     pub script_chan: IpcSender<ConstellationControlMsg>,
200     pub image_cache: Arc<ImageCache>,
201     pub content_process_shutdown_chan: Option<IpcSender<()>>,
202     pub layout_threads: usize,
203     pub paint_time_metrics: PaintTimeMetrics,
204 }
205