Remove more IPC messages between script and layout (#32377)

Instead of bouncing messages from the compositor to script and then to
layout, just have script call methods on Layout. Additionally, we do not
need to send any followup messages to script for these messages. Instead
just execute code after calling the method on Layout.
This commit is contained in:
Martin Robinson 2024-05-27 09:30:51 +02:00 committed by GitHub
parent a7bf099cb1
commit 5f0866379a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 103 additions and 165 deletions

View file

@ -30,9 +30,8 @@ use pixels::{CorsStatus, Image, PixelFormat};
use profile_traits::time::{self as profile_time, profile, ProfilerCategory}; use profile_traits::time::{self as profile_time, profile, ProfilerCategory};
use script_traits::CompositorEvent::{MouseButtonEvent, MouseMoveEvent, TouchEvent, WheelEvent}; use script_traits::CompositorEvent::{MouseButtonEvent, MouseMoveEvent, TouchEvent, WheelEvent};
use script_traits::{ use script_traits::{
AnimationState, AnimationTickType, ConstellationControlMsg, LayoutControlMsg, MouseButton, AnimationState, AnimationTickType, ConstellationControlMsg, MouseButton, MouseEventType,
MouseEventType, ScrollState, TouchEventType, TouchId, WheelDelta, WindowSizeData, ScrollState, TouchEventType, TouchId, WheelDelta, WindowSizeData, WindowSizeType,
WindowSizeType,
}; };
use servo_geometry::{DeviceIndependentPixel, FramebufferUintLength}; use servo_geometry::{DeviceIndependentPixel, FramebufferUintLength};
use style_traits::{CSSPixel, DevicePixel, PinchZoomFactor}; use style_traits::{CSSPixel, DevicePixel, PinchZoomFactor};
@ -1940,10 +1939,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
}); });
if let Some(pipeline) = details.pipeline.as_ref() { if let Some(pipeline) = details.pipeline.as_ref() {
let message = ConstellationControlMsg::ForLayoutFromConstellation( let message = ConstellationControlMsg::SetScrollStates(*pipeline_id, scroll_states);
LayoutControlMsg::SetScrollStates(scroll_states),
*pipeline_id,
);
let _ = pipeline.script_chan.send(message); let _ = pipeline.script_chan.send(message);
} }
} }
@ -2154,11 +2150,14 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
to_remove.push(*id); to_remove.push(*id);
if let Some(pipeline) = self.pipeline(*id) { if let Some(pipeline) = self.pipeline(*id) {
// and inform layout with the measured paint time. // and inform layout with the measured paint time.
let message = LayoutControlMsg::PaintMetric(epoch, paint_time); if let Err(e) =
let message = pipeline
ConstellationControlMsg::ForLayoutFromConstellation(message, *id); .script_chan
if let Err(e) = pipeline.script_chan.send(message) { .send(ConstellationControlMsg::SetEpochPaintTime(
warn!("Sending PaintMetric message to layout failed ({:?}).", e); *id, epoch, paint_time,
))
{
warn!("Sending RequestLayoutPaintMetric message to layout failed ({e:?}).");
} }
} }
} }

View file

@ -10,7 +10,6 @@
use std::borrow::ToOwned; use std::borrow::ToOwned;
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
use std::collections::HashMap;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use std::process; use std::process;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
@ -63,13 +62,12 @@ use profile_traits::time::{
use script::layout_dom::{ServoLayoutDocument, ServoLayoutElement, ServoLayoutNode}; use script::layout_dom::{ServoLayoutDocument, ServoLayoutElement, ServoLayoutNode};
use script_layout_interface::wrapper_traits::LayoutNode; use script_layout_interface::wrapper_traits::LayoutNode;
use script_layout_interface::{ use script_layout_interface::{
node_id_from_scroll_id, Layout, LayoutConfig, LayoutFactory, NodesFromPointQueryType, Layout, LayoutConfig, LayoutFactory, NodesFromPointQueryType, OffsetParentResponse, Reflow,
OffsetParentResponse, Reflow, ReflowComplete, ReflowGoal, ScriptReflow, TrustedNodeAddress, ReflowComplete, ReflowGoal, ScriptReflow, TrustedNodeAddress,
}; };
use script_traits::{ use script_traits::{
ConstellationControlMsg, DrawAPaintImageResult, IFrameSizeMsg, LayoutControlMsg, ConstellationControlMsg, DrawAPaintImageResult, IFrameSizeMsg, LayoutMsg as ConstellationMsg,
LayoutMsg as ConstellationMsg, PaintWorkletError, Painter, ScrollState, UntrustedNodeAddress, PaintWorkletError, Painter, ScrollState, UntrustedNodeAddress, WindowSizeData, WindowSizeType,
WindowSizeData, WindowSizeType,
}; };
use servo_arc::Arc as ServoArc; use servo_arc::Arc as ServoArc;
use servo_atoms::Atom; use servo_atoms::Atom;
@ -245,20 +243,6 @@ impl Drop for ScriptReflowResult {
} }
impl Layout for LayoutThread { impl Layout for LayoutThread {
fn handle_constellation_message(
&mut self,
constellation_message: script_traits::LayoutControlMsg,
) {
match constellation_message {
LayoutControlMsg::SetScrollStates(new_scroll_states) => {
self.set_scroll_states(new_scroll_states);
},
LayoutControlMsg::PaintMetric(epoch, paint_time) => {
self.paint_time_metrics.maybe_set_metric(epoch, paint_time);
},
}
}
fn device(&self) -> &Device { fn device(&self) -> &Device {
self.stylist.device() self.stylist.device()
} }
@ -550,6 +534,17 @@ impl Layout for LayoutThread {
|| self.handle_reflow(&mut result), || self.handle_reflow(&mut result),
); );
} }
fn set_scroll_states(&mut self, scroll_states: &[ScrollState]) {
*self.scroll_offsets.borrow_mut() = scroll_states
.iter()
.map(|scroll_state| (scroll_state.scroll_id, scroll_state.scroll_offset))
.collect();
}
fn set_epoch_paint_time(&mut self, epoch: Epoch, paint_time: u64) {
self.paint_time_metrics.maybe_set_metric(epoch, paint_time);
}
} }
impl LayoutThread { impl LayoutThread {
fn root_flow_for_query(&self) -> Option<FlowRef> { fn root_flow_for_query(&self) -> Option<FlowRef> {
@ -1181,28 +1176,6 @@ impl LayoutThread {
); );
} }
fn set_scroll_states(&mut self, new_scroll_states: Vec<ScrollState>) {
let mut script_scroll_states = vec![];
let mut layout_scroll_states = HashMap::new();
for new_state in &new_scroll_states {
let offset = new_state.scroll_offset;
layout_scroll_states.insert(new_state.scroll_id, offset);
if new_state.scroll_id.is_root() {
script_scroll_states.push((UntrustedNodeAddress::from_id(0), offset))
} else if let Some(node_id) = node_id_from_scroll_id(new_state.scroll_id.0 as usize) {
script_scroll_states.push((UntrustedNodeAddress::from_id(node_id), offset))
}
}
let _ = self
.script_chan
.send(ConstellationControlMsg::SetScrollState(
self.id,
script_scroll_states,
));
*self.scroll_offsets.borrow_mut() = layout_scroll_states
}
/// Cancel animations for any nodes which have been removed from flow tree. /// Cancel animations for any nodes which have been removed from flow tree.
/// TODO(mrobinson): We should look into a way of doing this during flow tree construction. /// TODO(mrobinson): We should look into a way of doing this during flow tree construction.
/// This also doesn't yet handles nodes that have been reparented. /// This also doesn't yet handles nodes that have been reparented.

View file

@ -50,13 +50,12 @@ use profile_traits::time::{
}; };
use script::layout_dom::{ServoLayoutDocument, ServoLayoutElement, ServoLayoutNode}; use script::layout_dom::{ServoLayoutDocument, ServoLayoutElement, ServoLayoutNode};
use script_layout_interface::{ use script_layout_interface::{
node_id_from_scroll_id, Layout, LayoutConfig, LayoutFactory, NodesFromPointQueryType, Layout, LayoutConfig, LayoutFactory, NodesFromPointQueryType, OffsetParentResponse,
OffsetParentResponse, ReflowComplete, ReflowGoal, ScriptReflow, TrustedNodeAddress, ReflowComplete, ReflowGoal, ScriptReflow, TrustedNodeAddress,
}; };
use script_traits::{ use script_traits::{
ConstellationControlMsg, DrawAPaintImageResult, IFrameSizeMsg, LayoutControlMsg, ConstellationControlMsg, DrawAPaintImageResult, IFrameSizeMsg, LayoutMsg as ConstellationMsg,
LayoutMsg as ConstellationMsg, PaintWorkletError, Painter, ScrollState, UntrustedNodeAddress, PaintWorkletError, Painter, ScrollState, UntrustedNodeAddress, WindowSizeData, WindowSizeType,
WindowSizeData, WindowSizeType,
}; };
use servo_arc::Arc as ServoArc; use servo_arc::Arc as ServoArc;
use servo_atoms::Atom; use servo_atoms::Atom;
@ -221,20 +220,6 @@ impl Drop for ScriptReflowResult {
} }
impl Layout for LayoutThread { impl Layout for LayoutThread {
fn handle_constellation_message(
&mut self,
constellation_message: script_traits::LayoutControlMsg,
) {
match constellation_message {
LayoutControlMsg::SetScrollStates(new_scroll_states) => {
self.set_scroll_states(new_scroll_states);
},
LayoutControlMsg::PaintMetric(epoch, paint_time) => {
self.paint_time_metrics.maybe_set_metric(epoch, paint_time);
},
}
}
fn device(&self) -> &Device { fn device(&self) -> &Device {
self.stylist.device() self.stylist.device()
} }
@ -469,6 +454,17 @@ impl Layout for LayoutThread {
_painter: Box<dyn Painter>, _painter: Box<dyn Painter>,
) { ) {
} }
fn set_scroll_states(&mut self, scroll_states: &[ScrollState]) {
*self.scroll_offsets.borrow_mut() = scroll_states
.iter()
.map(|scroll_state| (scroll_state.scroll_id, scroll_state.scroll_offset))
.collect();
}
fn set_epoch_paint_time(&mut self, epoch: Epoch, paint_time: u64) {
self.paint_time_metrics.maybe_set_metric(epoch, paint_time);
}
} }
impl LayoutThread { impl LayoutThread {
@ -831,28 +827,6 @@ impl LayoutThread {
); );
} }
fn set_scroll_states(&mut self, new_scroll_states: Vec<ScrollState>) {
let mut script_scroll_states = vec![];
let mut layout_scroll_states = HashMap::new();
for new_state in &new_scroll_states {
let offset = new_state.scroll_offset;
layout_scroll_states.insert(new_state.scroll_id, offset);
if new_state.scroll_id.is_root() {
script_scroll_states.push((UntrustedNodeAddress::from_id(0), offset))
} else if let Some(node_id) = node_id_from_scroll_id(new_state.scroll_id.0 as usize) {
script_scroll_states.push((UntrustedNodeAddress::from_id(node_id), offset))
}
}
let _ = self
.script_chan
.send(ConstellationControlMsg::SetScrollState(
self.id,
script_scroll_states,
));
self.scroll_offsets = RefCell::new(layout_scroll_states);
}
fn perform_post_style_recalc_layout_passes( fn perform_post_style_recalc_layout_passes(
&self, &self,
fragment_tree: Arc<FragmentTree>, fragment_tree: Arc<FragmentTree>,

View file

@ -26,8 +26,8 @@ use std::rc::Rc;
use std::result::Result; use std::result::Result;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc; use std::sync::Arc;
use std::thread;
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
use std::{ptr, thread};
use background_hang_monitor_api::{ use background_hang_monitor_api::{
BackgroundHangMonitor, BackgroundHangMonitorExitSignal, HangAnnotation, MonitoredComponentId, BackgroundHangMonitor, BackgroundHangMonitorExitSignal, HangAnnotation, MonitoredComponentId,
@ -36,6 +36,7 @@ use background_hang_monitor_api::{
use base::id::{ use base::id::{
BrowsingContextId, HistoryStateId, PipelineId, PipelineNamespace, TopLevelBrowsingContextId, BrowsingContextId, HistoryStateId, PipelineId, PipelineNamespace, TopLevelBrowsingContextId,
}; };
use base::Epoch;
use bluetooth_traits::BluetoothRequest; use bluetooth_traits::BluetoothRequest;
use canvas_traits::webgl::WebGLPipeline; use canvas_traits::webgl::WebGLPipeline;
use chrono::{DateTime, Local}; use chrono::{DateTime, Local};
@ -46,7 +47,6 @@ use devtools_traits::{
}; };
use embedder_traits::EmbedderMsg; use embedder_traits::EmbedderMsg;
use euclid::default::{Point2D, Rect}; use euclid::default::{Point2D, Rect};
use euclid::Vector2D;
use gfx::font_cache_thread::FontCacheThread; use gfx::font_cache_thread::FontCacheThread;
use headers::{HeaderMapExt, LastModified, ReferrerPolicy as ReferrerPolicyHeader}; use headers::{HeaderMapExt, LastModified, ReferrerPolicy as ReferrerPolicyHeader};
use html5ever::{local_name, namespace_url, ns}; use html5ever::{local_name, namespace_url, ns};
@ -73,13 +73,15 @@ use parking_lot::Mutex;
use percent_encoding::percent_decode; use percent_encoding::percent_decode;
use profile_traits::mem::{self as profile_mem, OpaqueSender, ReportsChan}; use profile_traits::mem::{self as profile_mem, OpaqueSender, ReportsChan};
use profile_traits::time::{self as profile_time, profile, ProfilerCategory}; use profile_traits::time::{self as profile_time, profile, ProfilerCategory};
use script_layout_interface::{LayoutConfig, LayoutFactory, ReflowGoal, ScriptThreadFactory}; use script_layout_interface::{
node_id_from_scroll_id, LayoutConfig, LayoutFactory, ReflowGoal, ScriptThreadFactory,
};
use script_traits::webdriver_msg::WebDriverScriptCommand; use script_traits::webdriver_msg::WebDriverScriptCommand;
use script_traits::{ use script_traits::{
CompositorEvent, ConstellationControlMsg, DiscardBrowsingContext, DocumentActivity, CompositorEvent, ConstellationControlMsg, DiscardBrowsingContext, DocumentActivity,
EventResult, HistoryEntryReplacement, InitialScriptState, JsEvalResult, LayoutControlMsg, EventResult, HistoryEntryReplacement, InitialScriptState, JsEvalResult, LayoutMsg, LoadData,
LayoutMsg, LoadData, LoadOrigin, MediaSessionActionType, MouseButton, MouseEventType, LoadOrigin, MediaSessionActionType, MouseButton, MouseEventType, NewLayoutInfo, Painter,
NewLayoutInfo, Painter, ProgressiveWebMetricType, ScriptMsg, ScriptToConstellationChan, ProgressiveWebMetricType, ScriptMsg, ScriptToConstellationChan, ScrollState,
StructuredSerializedData, TimerSchedulerMsg, TouchEventType, TouchId, UntrustedNodeAddress, StructuredSerializedData, TimerSchedulerMsg, TouchEventType, TouchId, UntrustedNodeAddress,
UpdatePipelineIdReason, WheelDelta, WindowSizeData, WindowSizeType, UpdatePipelineIdReason, WheelDelta, WindowSizeData, WindowSizeType,
}; };
@ -91,7 +93,6 @@ use style::thread_state::{self, ThreadState};
use time::precise_time_ns; use time::precise_time_ns;
use url::Position; use url::Position;
use webgpu::WebGPUMsg; use webgpu::WebGPUMsg;
use webrender_api::units::LayoutPixel;
use webrender_api::DocumentId; use webrender_api::DocumentId;
use webrender_traits::WebRenderScriptApi; use webrender_traits::WebRenderScriptApi;
@ -1836,11 +1837,6 @@ impl ScriptThread {
.profile_event(ScriptThreadEventCategory::SetViewport, Some(id), || { .profile_event(ScriptThreadEventCategory::SetViewport, Some(id), || {
self.handle_viewport(id, rect); self.handle_viewport(id, rect);
}), }),
FromConstellation(ConstellationControlMsg::SetScrollState(id, scroll_state)) => {
self.profile_event(ScriptThreadEventCategory::SetScrollState, Some(id), || {
self.handle_set_scroll_state(id, &scroll_state);
})
},
FromConstellation(ConstellationControlMsg::TickAllAnimations( FromConstellation(ConstellationControlMsg::TickAllAnimations(
pipeline_id, pipeline_id,
tick_type, tick_type,
@ -2097,7 +2093,6 @@ impl ScriptThread {
ExitScriptThread => None, ExitScriptThread => None,
SendEvent(id, ..) => Some(id), SendEvent(id, ..) => Some(id),
Viewport(id, ..) => Some(id), Viewport(id, ..) => Some(id),
SetScrollState(id, ..) => Some(id),
GetTitle(id) => Some(id), GetTitle(id) => Some(id),
SetDocumentActivity(id, ..) => Some(id), SetDocumentActivity(id, ..) => Some(id),
SetThrottled(id, ..) => Some(id), SetThrottled(id, ..) => Some(id),
@ -2123,7 +2118,8 @@ impl ScriptThread {
ExitFullScreen(id, ..) => Some(id), ExitFullScreen(id, ..) => Some(id),
MediaSessionAction(..) => None, MediaSessionAction(..) => None,
SetWebGPUPort(..) => None, SetWebGPUPort(..) => None,
ForLayoutFromConstellation(_, id) => Some(id), SetScrollStates(id, ..) => Some(id),
SetEpochPaintTime(id, ..) => Some(id),
}, },
MixedMessage::FromDevtools(_) => None, MixedMessage::FromDevtools(_) => None,
MixedMessage::FromScript(ref inner_msg) => match *inner_msg { MixedMessage::FromScript(ref inner_msg) => match *inner_msg {
@ -2348,7 +2344,6 @@ impl ScriptThread {
}, },
msg @ ConstellationControlMsg::AttachLayout(..) | msg @ ConstellationControlMsg::AttachLayout(..) |
msg @ ConstellationControlMsg::Viewport(..) | msg @ ConstellationControlMsg::Viewport(..) |
msg @ ConstellationControlMsg::SetScrollState(..) |
msg @ ConstellationControlMsg::Resize(..) | msg @ ConstellationControlMsg::Resize(..) |
msg @ ConstellationControlMsg::ExitFullScreen(..) | msg @ ConstellationControlMsg::ExitFullScreen(..) |
msg @ ConstellationControlMsg::SendEvent(..) | msg @ ConstellationControlMsg::SendEvent(..) |
@ -2356,22 +2351,53 @@ impl ScriptThread {
msg @ ConstellationControlMsg::ExitScriptThread => { msg @ ConstellationControlMsg::ExitScriptThread => {
panic!("should have handled {:?} already", msg) panic!("should have handled {:?} already", msg)
}, },
ConstellationControlMsg::ForLayoutFromConstellation(msg, pipeline_id) => { ConstellationControlMsg::SetScrollStates(pipeline_id, scroll_states) => {
self.handle_layout_message_from_constellation(msg, pipeline_id) self.handle_set_scroll_states_msg(pipeline_id, scroll_states)
},
ConstellationControlMsg::SetEpochPaintTime(pipeline_id, epoch, time) => {
self.handle_set_epoch_paint_time(pipeline_id, epoch, time)
}, },
} }
} }
fn handle_layout_message_from_constellation( fn handle_set_scroll_states_msg(
&self, &self,
msg: LayoutControlMsg,
pipeline_id: PipelineId, pipeline_id: PipelineId,
scroll_states: Vec<ScrollState>,
) { ) {
let Some(window) = self.documents.borrow().find_window(pipeline_id) else { let Some(window) = self.documents.borrow().find_window(pipeline_id) else {
warn!("Received layout message pipeline {pipeline_id} closed: {msg:?}."); warn!("Received scroll states for closed pipeline {pipeline_id}");
return; return;
}; };
window.layout_mut().handle_constellation_message(msg);
self.profile_event(
ScriptThreadEventCategory::SetScrollState,
Some(pipeline_id),
|| {
window.layout_mut().set_scroll_states(&scroll_states);
let mut scroll_offsets = HashMap::new();
for scroll_state in scroll_states.into_iter() {
let scroll_offset = scroll_state.scroll_offset;
if scroll_state.scroll_id.is_root() {
window.update_viewport_for_scroll(-scroll_offset.x, -scroll_offset.y);
} else if let Some(node_id) =
node_id_from_scroll_id(scroll_state.scroll_id.0 as usize)
{
scroll_offsets.insert(OpaqueNode(node_id), -scroll_offset);
}
}
window.set_scroll_offsets(scroll_offsets)
},
)
}
fn handle_set_epoch_paint_time(&self, pipeline_id: PipelineId, epoch: Epoch, time: u64) {
let Some(window) = self.documents.borrow().find_window(pipeline_id) else {
warn!("Received set epoch paint time message for closed pipeline {pipeline_id}.");
return;
};
window.layout_mut().set_epoch_paint_time(epoch, time);
} }
fn handle_msg_from_webgpu_server(&self, msg: WebGPUMsg) { fn handle_msg_from_webgpu_server(&self, msg: WebGPUMsg) {
@ -2763,32 +2789,6 @@ impl ScriptThread {
warn!("Page rect message sent to nonexistent pipeline"); warn!("Page rect message sent to nonexistent pipeline");
} }
fn handle_set_scroll_state(
&self,
id: PipelineId,
scroll_states: &[(UntrustedNodeAddress, Vector2D<f32, LayoutPixel>)],
) {
let window = match self.documents.borrow().find_window(id) {
Some(window) => window,
None => {
return warn!(
"Set scroll state message sent to nonexistent pipeline: {:?}",
id
);
},
};
let mut scroll_offsets = HashMap::new();
for &(node_address, ref scroll_offset) in scroll_states {
if node_address == UntrustedNodeAddress(ptr::null()) {
window.update_viewport_for_scroll(-scroll_offset.x, -scroll_offset.y);
} else {
scroll_offsets.insert(OpaqueNode(node_address.0 as usize), -*scroll_offset);
}
}
window.set_scroll_offsets(scroll_offsets)
}
fn handle_new_layout(&self, new_layout_info: NewLayoutInfo, origin: MutableOrigin) { fn handle_new_layout(&self, new_layout_info: NewLayoutInfo, origin: MutableOrigin) {
let NewLayoutInfo { let NewLayoutInfo {
parent_info, parent_info,

View file

@ -110,15 +110,6 @@ impl UntrustedNodeAddress {
} }
} }
/// Messages sent to layout from the constellation and/or compositor.
#[derive(Debug, Deserialize, Serialize)]
pub enum LayoutControlMsg {
/// Tells layout about the new scrolling offsets of each scrollable stacking context.
SetScrollStates(Vec<ScrollState>),
/// Send the paint time for a specific epoch to layout.
PaintMetric(Epoch, u64),
}
/// The origin where a given load was initiated. /// The origin where a given load was initiated.
/// Useful for origin checks, for example before evaluation a JS URL. /// Useful for origin checks, for example before evaluation a JS URL.
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
@ -302,11 +293,6 @@ pub enum ConstellationControlMsg {
SendEvent(PipelineId, CompositorEvent), SendEvent(PipelineId, CompositorEvent),
/// Notifies script of the viewport. /// Notifies script of the viewport.
Viewport(PipelineId, Rect<f32, UnknownUnit>), Viewport(PipelineId, Rect<f32, UnknownUnit>),
/// Notifies script of a new set of scroll offsets.
SetScrollState(
PipelineId,
Vec<(UntrustedNodeAddress, Vector2D<f32, LayoutPixel>)>,
),
/// Requests that the script thread immediately send the constellation the title of a pipeline. /// Requests that the script thread immediately send the constellation the title of a pipeline.
GetTitle(PipelineId), GetTitle(PipelineId),
/// Notifies script thread of a change to one of its document's activity /// Notifies script thread of a change to one of its document's activity
@ -391,8 +377,11 @@ pub enum ConstellationControlMsg {
MediaSessionAction(PipelineId, MediaSessionActionType), MediaSessionAction(PipelineId, MediaSessionActionType),
/// Notifies script thread that WebGPU server has started /// Notifies script thread that WebGPU server has started
SetWebGPUPort(IpcReceiver<WebGPUMsg>), SetWebGPUPort(IpcReceiver<WebGPUMsg>),
/// A mesage for a layout from the constellation. /// The compositor scrolled and is updating the scroll states of the nodes in the given
ForLayoutFromConstellation(LayoutControlMsg, PipelineId), /// pipeline via the Constellation.
SetScrollStates(PipelineId, Vec<ScrollState>),
/// Send the paint time for a specific epoch.
SetEpochPaintTime(PipelineId, Epoch, u64),
} }
impl fmt::Debug for ConstellationControlMsg { impl fmt::Debug for ConstellationControlMsg {
@ -409,7 +398,6 @@ impl fmt::Debug for ConstellationControlMsg {
ExitScriptThread => "ExitScriptThread", ExitScriptThread => "ExitScriptThread",
SendEvent(..) => "SendEvent", SendEvent(..) => "SendEvent",
Viewport(..) => "Viewport", Viewport(..) => "Viewport",
SetScrollState(..) => "SetScrollState",
GetTitle(..) => "GetTitle", GetTitle(..) => "GetTitle",
SetDocumentActivity(..) => "SetDocumentActivity", SetDocumentActivity(..) => "SetDocumentActivity",
SetThrottled(..) => "SetThrottled", SetThrottled(..) => "SetThrottled",
@ -431,7 +419,8 @@ impl fmt::Debug for ConstellationControlMsg {
ExitFullScreen(..) => "ExitFullScreen", ExitFullScreen(..) => "ExitFullScreen",
MediaSessionAction(..) => "MediaSessionAction", MediaSessionAction(..) => "MediaSessionAction",
SetWebGPUPort(..) => "SetWebGPUPort", SetWebGPUPort(..) => "SetWebGPUPort",
ForLayoutFromConstellation(..) => "ForLayoutFromConstellation", SetScrollStates(..) => "SetScrollStates",
SetEpochPaintTime(..) => "SetEpochPaintTime",
}; };
write!(formatter, "ConstellationControlMsg::{}", variant) write!(formatter, "ConstellationControlMsg::{}", variant)
} }

View file

@ -33,8 +33,8 @@ use net_traits::ResourceThreads;
use profile_traits::mem::Report; use profile_traits::mem::Report;
use profile_traits::time; use profile_traits::time;
use script_traits::{ use script_traits::{
ConstellationControlMsg, InitialScriptState, LayoutControlMsg, LayoutMsg, LoadData, Painter, ConstellationControlMsg, InitialScriptState, LayoutMsg, LoadData, Painter, ScrollState,
ScrollState, UntrustedNodeAddress, WindowSizeData, UntrustedNodeAddress, WindowSizeData,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use servo_arc::Arc as ServoArc; use servo_arc::Arc as ServoArc;
@ -178,9 +178,6 @@ pub trait LayoutFactory: Send + Sync {
} }
pub trait Layout { pub trait Layout {
/// Handle a single message from the Constellation.
fn handle_constellation_message(&mut self, msg: LayoutControlMsg);
/// Get a reference to this Layout's Stylo `Device` used to handle media queries and /// Get a reference to this Layout's Stylo `Device` used to handle media queries and
/// resolve font metrics. /// resolve font metrics.
fn device(&self) -> &Device; fn device(&self) -> &Device;
@ -228,6 +225,12 @@ pub trait Layout {
painter: Box<dyn Painter>, painter: Box<dyn Painter>,
); );
/// Set the scroll states of this layout after a compositor scroll.
fn set_scroll_states(&mut self, scroll_states: &[ScrollState]);
/// Set the paint time for a specific epoch.
fn set_epoch_paint_time(&mut self, epoch: Epoch, paint_time: u64);
fn query_content_box(&self, node: OpaqueNode) -> Option<Rect<Au>>; fn query_content_box(&self, node: OpaqueNode) -> Option<Rect<Au>>;
fn query_content_boxes(&self, node: OpaqueNode) -> Vec<Rect<Au>>; fn query_content_boxes(&self, node: OpaqueNode) -> Vec<Rect<Au>>;
fn query_client_rect(&self, node: OpaqueNode) -> Rect<i32>; fn query_client_rect(&self, node: OpaqueNode) -> Rect<i32>;