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