aboutsummaryrefslogtreecommitdiffstats
path: root/components/constellation
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2025-03-21 15:55:00 +0100
committerGitHub <noreply@github.com>2025-03-21 14:55:00 +0000
commit54244797688fbeec85baac6fcfc9b71d555bf72c (patch)
tree5e9914cce8a83a8d8b171da0ead4d6f1cf725ca5 /components/constellation
parent1f232eb17c031fe18035a17249de99b2af6fa53e (diff)
downloadservo-54244797688fbeec85baac6fcfc9b71d555bf72c.tar.gz
servo-54244797688fbeec85baac6fcfc9b71d555bf72c.zip
metrics: Simplify `ProgressiveWebMetrics` (#35985)
Simply how `ProgressiveWebMetrics` works: 1. Keep only a single struct instead of one in layout and one script that both implement the `ProgressiveWebMetrics` trait. Since layout and script are the same thread these can now just be a single `ProgressiveWebMetrics` struct stored in script. 2. Have the compositor be responsible for informing the Constellation (which informs the ScripThread) about paint metrics. This makes communication flow one way and removes one dependency between the compositor and script (of two). 3. All units tests are moved into the `metrics` crate itself since there is only one struct there now. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Diffstat (limited to 'components/constellation')
-rw-r--r--components/constellation/constellation.rs97
-rw-r--r--components/constellation/pipeline.rs11
-rw-r--r--components/constellation/tracing.rs30
3 files changed, 41 insertions, 97 deletions
diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs
index 6734eb6f46f..192e2485547 100644
--- a/components/constellation/constellation.rs
+++ b/components/constellation/constellation.rs
@@ -109,7 +109,8 @@ use canvas_traits::ConstellationCanvasMsg;
use canvas_traits::canvas::{CanvasId, CanvasMsg};
use canvas_traits::webgl::WebGLThreads;
use compositing_traits::{
- CompositorMsg, CompositorProxy, ConstellationMsg as FromCompositorMsg, SendableFrameTree,
+ CompositorMsg, CompositorProxy, ConstellationMsg as FromCompositorMsg, PaintMetricEvent,
+ SendableFrameTree,
};
use crossbeam_channel::{Receiver, Sender, select, unbounded};
use devtools_traits::{
@@ -141,8 +142,8 @@ use script_traits::{
AnimationState, AnimationTickType, AuxiliaryWebViewCreationRequest,
AuxiliaryWebViewCreationResponse, BroadcastMsg, ConstellationInputEvent,
DiscardBrowsingContext, DocumentActivity, DocumentState, IFrameLoadInfo,
- IFrameLoadInfoWithData, IFrameSandboxState, IFrameSizeMsg, Job, LayoutMsg as FromLayoutMsg,
- LoadData, LoadOrigin, LogEntry, MessagePortMsg, NavigationHistoryBehavior, PortMessageTask,
+ IFrameLoadInfoWithData, IFrameSandboxState, IFrameSizeMsg, Job, LoadData, LoadOrigin, LogEntry,
+ MessagePortMsg, NavigationHistoryBehavior, PortMessageTask, ProgressiveWebMetricType,
SWManagerMsg, SWManagerSenders, ScriptMsg as FromScriptMsg, ScriptThreadMessage,
ScriptToConstellationChan, ServiceWorkerManagerFactory, ServiceWorkerMsg,
StructuredSerializedData, UpdatePipelineIdReason, WindowSizeData, WindowSizeType,
@@ -309,14 +310,6 @@ pub struct Constellation<STF, SWF> {
/// dependency between script and layout.
layout_factory: Arc<dyn LayoutFactory>,
- /// An IPC channel for layout to send messages to the constellation.
- /// This is the layout's view of `layout_receiver`.
- layout_sender: IpcSender<FromLayoutMsg>,
-
- /// A channel for the constellation to receive messages from layout.
- /// This is the constellation's view of `layout_sender`.
- layout_receiver: Receiver<Result<FromLayoutMsg, IpcError>>,
-
/// A channel for the constellation to receive messages from the compositor thread.
compositor_receiver: Receiver<FromCompositorMsg>,
@@ -661,13 +654,6 @@ where
)
};
- let (layout_ipc_sender, layout_ipc_receiver) =
- ipc::channel().expect("ipc channel failure");
- let layout_receiver =
- route_ipc_receiver_to_new_crossbeam_receiver_preserving_errors(
- layout_ipc_receiver,
- );
-
let swmanager_receiver =
route_ipc_receiver_to_new_crossbeam_receiver_preserving_errors(
swmanager_ipc_receiver,
@@ -693,11 +679,9 @@ where
background_hang_monitor_receiver,
background_monitor_register,
background_monitor_control_senders: background_hang_monitor_control_ipc_senders,
- layout_sender: layout_ipc_sender,
script_receiver,
compositor_receiver,
layout_factory,
- layout_receiver,
embedder_proxy: state.embedder_proxy,
compositor_proxy: state.compositor_proxy,
webviews: WebViewManager::default(),
@@ -967,7 +951,6 @@ where
background_hang_monitor_to_constellation_chan: self
.background_hang_monitor_sender
.clone(),
- layout_to_constellation_chan: self.layout_sender.clone(),
layout_factory: self.layout_factory.clone(),
compositor_proxy: self.compositor_proxy.clone(),
devtools_sender: self.devtools_sender.clone(),
@@ -1132,7 +1115,6 @@ where
Script((PipelineId, FromScriptMsg)),
BackgroundHangMonitor(HangMonitorAlert),
Compositor(FromCompositorMsg),
- Layout(FromLayoutMsg),
FromSWManager(SWManagerMsg),
}
// Get one incoming request.
@@ -1163,9 +1145,6 @@ where
recv(self.compositor_receiver) -> msg => {
Ok(Request::Compositor(msg.expect("Unexpected compositor channel panic in constellation")))
}
- recv(self.layout_receiver) -> msg => {
- msg.expect("Unexpected layout channel panic in constellation").map(Request::Layout)
- }
recv(self.swmanager_receiver) -> msg => {
msg.expect("Unexpected SW channel panic in constellation").map(Request::FromSWManager)
}
@@ -1188,9 +1167,6 @@ where
Request::BackgroundHangMonitor(message) => {
self.handle_request_from_background_hang_monitor(message);
},
- Request::Layout(message) => {
- self.handle_request_from_layout(message);
- },
Request::FromSWManager(message) => {
self.handle_request_from_swmanager(message);
},
@@ -1409,6 +1385,9 @@ where
FromCompositorMsg::SetScrollStates(pipeline_id, scroll_states) => {
self.handle_set_scroll_states(pipeline_id, scroll_states)
},
+ FromCompositorMsg::PaintMetric(pipeline_id, paint_metric_event) => {
+ self.handle_paint_metric(pipeline_id, paint_metric_event);
+ },
}
}
@@ -1984,19 +1963,6 @@ where
feature = "tracing",
tracing::instrument(skip_all, fields(servo_profiling = true), level = "trace")
)]
- fn handle_request_from_layout(&mut self, message: FromLayoutMsg) {
- trace_layout_msg!(message, "{message:?}");
- match message {
- FromLayoutMsg::PendingPaintMetric(webview_id, pipeline_id, epoch) => {
- self.handle_pending_paint_metric(webview_id, pipeline_id, epoch);
- },
- }
- }
-
- #[cfg_attr(
- feature = "tracing",
- tracing::instrument(skip_all, fields(servo_profiling = true), level = "trace")
- )]
fn handle_message_port_transfer_completed(
&mut self,
router_id: Option<MessagePortRouterId>,
@@ -3405,24 +3371,6 @@ where
feature = "tracing",
tracing::instrument(skip_all, fields(servo_profiling = true), level = "trace")
)]
- fn handle_pending_paint_metric(
- &self,
- webview_id: WebViewId,
- pipeline_id: PipelineId,
- epoch: Epoch,
- ) {
- self.compositor_proxy
- .send(CompositorMsg::PendingPaintMetric(
- webview_id,
- pipeline_id,
- epoch,
- ))
- }
-
- #[cfg_attr(
- feature = "tracing",
- tracing::instrument(skip_all, fields(servo_profiling = true), level = "trace")
- )]
fn handle_set_cursor_msg(&mut self, webview_id: WebViewId, cursor: Cursor) {
self.embedder_proxy
.send(EmbedderMsg::SetCursor(webview_id, cursor));
@@ -5585,4 +5533,35 @@ where
warn!("Could not send scroll offsets to pipeline: {pipeline_id:?}: {error:?}");
}
}
+
+ #[cfg_attr(
+ feature = "tracing",
+ tracing::instrument(skip_all, fields(servo_profiling = true), level = "trace")
+ )]
+ fn handle_paint_metric(&mut self, pipeline_id: PipelineId, event: PaintMetricEvent) {
+ let Some(pipeline) = self.pipelines.get(&pipeline_id) else {
+ warn!("Discarding paint metric event for unknown pipeline");
+ return;
+ };
+ let (metric_type, metric_value, first_reflow) = match event {
+ PaintMetricEvent::FirstPaint(metric_value, first_reflow) => (
+ ProgressiveWebMetricType::FirstPaint,
+ metric_value,
+ first_reflow,
+ ),
+ PaintMetricEvent::FirstContentfulPaint(metric_value, first_reflow) => (
+ ProgressiveWebMetricType::FirstContentfulPaint,
+ metric_value,
+ first_reflow,
+ ),
+ };
+ if let Err(error) = pipeline.event_loop.send(ScriptThreadMessage::PaintMetric(
+ pipeline_id,
+ metric_type,
+ metric_value,
+ first_reflow,
+ )) {
+ warn!("Could not sent paint metric event to pipeline: {pipeline_id:?}: {error:?}");
+ }
+ }
}
diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs
index 39b3fce26df..f394c90b6c2 100644
--- a/components/constellation/pipeline.rs
+++ b/components/constellation/pipeline.rs
@@ -34,9 +34,8 @@ use net_traits::image_cache::ImageCache;
use profile_traits::{mem as profile_mem, time};
use script_layout_interface::{LayoutFactory, ScriptThreadFactory};
use script_traits::{
- AnimationState, DiscardBrowsingContext, DocumentActivity, InitialScriptState, LayoutMsg,
- LoadData, NewLayoutInfo, SWManagerMsg, ScriptThreadMessage, ScriptToConstellationChan,
- WindowSizeData,
+ AnimationState, DiscardBrowsingContext, DocumentActivity, InitialScriptState, LoadData,
+ NewLayoutInfo, SWManagerMsg, ScriptThreadMessage, ScriptToConstellationChan, WindowSizeData,
};
use serde::{Deserialize, Serialize};
use servo_config::opts::{self, Opts};
@@ -133,9 +132,6 @@ pub struct InitialPipelineState {
/// A channel for the background hang monitor to send messages to the constellation.
pub background_hang_monitor_to_constellation_chan: IpcSender<HangMonitorAlert>,
- /// A channel for the layout to send messages to the constellation.
- pub layout_to_constellation_chan: IpcSender<LayoutMsg>,
-
/// A fatory for creating layouts to be used by the ScriptThread.
pub layout_factory: Arc<dyn LayoutFactory>,
@@ -279,7 +275,6 @@ impl Pipeline {
time_profiler_chan: state.time_profiler_chan,
mem_profiler_chan: state.mem_profiler_chan,
window_size: state.window_size,
- layout_to_constellation_chan: state.layout_to_constellation_chan,
script_chan: script_chan.clone(),
load_data: state.load_data.clone(),
script_port,
@@ -481,7 +476,6 @@ pub struct UnprivilegedPipelineContent {
script_to_constellation_chan: ScriptToConstellationChan,
background_hang_monitor_to_constellation_chan: IpcSender<HangMonitorAlert>,
bhm_control_port: Option<IpcReceiver<BackgroundHangMonitorControlMsg>>,
- layout_to_constellation_chan: IpcSender<LayoutMsg>,
devtools_ipc_sender: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
#[cfg(feature = "bluetooth")]
bluetooth_thread: IpcSender<BluetoothRequest>,
@@ -533,7 +527,6 @@ impl UnprivilegedPipelineContent {
constellation_receiver: self.script_port,
pipeline_to_constellation_sender: self.script_to_constellation_chan.clone(),
background_hang_monitor_register: background_hang_monitor_register.clone(),
- layout_to_constellation_ipc_sender: self.layout_to_constellation_chan.clone(),
#[cfg(feature = "bluetooth")]
bluetooth_sender: self.bluetooth_thread,
resource_threads: self.resource_threads,
diff --git a/components/constellation/tracing.rs b/components/constellation/tracing.rs
index 38dda83538f..efd3c0e9566 100644
--- a/components/constellation/tracing.rs
+++ b/components/constellation/tracing.rs
@@ -30,17 +30,6 @@ macro_rules! trace_script_msg {
};
}
-/// Log an event from layout at trace level.
-/// - To disable tracing: RUST_LOG='constellation<layout@=off'
-/// - To enable tracing: RUST_LOG='constellation<layout@'
-macro_rules! trace_layout_msg {
- // This macro only exists to put the docs in the same file as the target prefix,
- // so the macro definition is always the same.
- ($event:expr, $($rest:tt)+) => {
- ::log::trace!(target: $crate::tracing::LogTarget::log_target(&$event), $($rest)+)
- };
-}
-
/// Get the log target for an event, as a static string.
pub(crate) trait LogTarget {
fn log_target(&self) -> &'static str;
@@ -87,6 +76,7 @@ mod from_compositor {
Self::MediaSessionAction(_) => target!("MediaSessionAction"),
Self::SetWebViewThrottled(_, _) => target!("SetWebViewThrottled"),
Self::SetScrollStates(..) => target!("SetScrollStates"),
+ Self::PaintMetric(..) => target!("PaintMetric"),
}
}
}
@@ -249,21 +239,3 @@ mod from_script {
}
}
}
-
-mod from_layout {
- use super::LogTarget;
-
- macro_rules! target {
- ($($name:literal)+) => {
- concat!("constellation<layout@", $($name),+)
- };
- }
-
- impl LogTarget for script_traits::LayoutMsg {
- fn log_target(&self) -> &'static str {
- match self {
- Self::PendingPaintMetric(..) => target!("PendingPaintMetric"),
- }
- }
- }
-}