aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2024-04-22 17:28:14 +0200
committerGitHub <noreply@github.com>2024-04-22 15:28:14 +0000
commit7d63c7607f12e6ef89e748b360e8e9265eae577b (patch)
tree3e496041400210645f285f7493377af11d8e2019 /components
parent97376e6d96abcbdfd30f3a91ec5aee7ce2add178 (diff)
downloadservo-7d63c7607f12e6ef89e748b360e8e9265eae577b.tar.gz
servo-7d63c7607f12e6ef89e748b360e8e9265eae577b.zip
script_layout: Remove script to layout messages (#32081)
Instead of communicating with layout via messages, script can simply call methods on the layout trait. This simplifies the way that script communicates with layout and opens the path to sharing more data structures between the two systems. This is part of a continuing series of cleanups after removing the layout thread. <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes do not require tests because they should not change behavior. <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
Diffstat (limited to 'components')
-rw-r--r--components/layout_thread/lib.rs207
-rw-r--r--components/layout_thread_2020/lib.rs118
-rw-r--r--components/script/dom/activation.rs2
-rw-r--r--components/script/dom/document.rs5
-rw-r--r--components/script/dom/documentorshadowroot.rs2
-rw-r--r--components/script/dom/element.rs2
-rw-r--r--components/script/dom/htmlelement.rs2
-rw-r--r--components/script/dom/htmliframeelement.rs2
-rw-r--r--components/script/dom/node.rs3
-rw-r--r--components/script/dom/window.rs7
-rw-r--r--components/script/script_thread.rs11
-rw-r--r--components/shared/msg/constellation_msg.rs19
-rw-r--r--components/shared/script_layout/lib.rs172
-rw-r--r--components/shared/script_layout/message.rs188
14 files changed, 324 insertions, 416 deletions
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<Atom>,
+ painter: Box<dyn 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);
+ }
+
+ 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);
- },
- 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();
+ Request::FromPipeline(LayoutControlMsg::PaintMetric(epoch, paint_time)) => {
+ self.paint_time_metrics.maybe_set_metric(epoch, paint_time);
},
- }
- }
-
- 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<FlowRef> {
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<Atom>,
+ _painter: Box<dyn Painter>,
+ ) {
+ }
}
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
@@ -466,24 +466,6 @@ pub enum InputMethodType {
}
#[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 {
AttachLayout,
@@ -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<ServoArc<Stylesheet>>,
);
+ /// 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<Stylesheet>);
+ /// 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<Atom>,
+ painter: Box<dyn Painter>,
+ );
+
fn query_content_box(&self, node: OpaqueNode) -> Option<Rect<Au>>;
fn query_content_boxes(&self, node: OpaqueNode) -> Vec<Rect<Au>>;
fn query_client_rect(&self, node: OpaqueNode) -> Rect<i32>;
@@ -257,3 +278,138 @@ pub struct OffsetParentResponse {
pub node_address: Option<UntrustedNodeAddress>,
pub rect: Rect<Au>,
}
+
+#[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<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,
+}
+
+/// 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<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,
+}
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<ScrollState>),
-
- /// Tells layout that script has added some paint worklet modules.
- RegisterPaint(Atom, Vec<Atom>, Box<dyn Painter>),
-}
-
-#[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<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,
-}
-
-/// 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 Default for PendingRestyle {
- /// Creates a new empty pending restyle.
- #[inline]
- fn default() -> Self {
- Self {
- snapshot: None,
- hint: RestyleHint::empty(),
- damage: RestyleDamage::empty(),
- }
- }
-}