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>
This commit is contained in:
Martin Robinson 2025-03-21 15:55:00 +01:00 committed by GitHub
parent 1f232eb17c
commit 5424479768
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
26 changed files with 416 additions and 787 deletions

View file

@ -33,7 +33,6 @@ use background_hang_monitor_api::{
BackgroundHangMonitor, BackgroundHangMonitorExitSignal, HangAnnotation, MonitoredComponentId,
MonitoredComponentType,
};
use base::Epoch;
use base::cross_process_instant::CrossProcessInstant;
use base::id::{BrowsingContextId, HistoryStateId, PipelineId, PipelineNamespace, WebViewId};
use canvas_traits::webgl::WebGLPipeline;
@ -60,7 +59,7 @@ use js::jsapi::{
use js::jsval::UndefinedValue;
use js::rust::ParentRuntime;
use media::WindowGLContext;
use metrics::{MAX_TASK_NS, PaintTimeMetrics};
use metrics::MAX_TASK_NS;
use mime::{self, Mime};
use net_traits::image_cache::{ImageCache, PendingImageResponse};
use net_traits::request::{Referrer, RequestId};
@ -128,8 +127,6 @@ use crate::dom::htmliframeelement::HTMLIFrameElement;
use crate::dom::htmlslotelement::HTMLSlotElement;
use crate::dom::mutationobserver::MutationObserver;
use crate::dom::node::{Node, NodeTraits, ShadowIncluding};
use crate::dom::performanceentry::PerformanceEntry;
use crate::dom::performancepainttiming::PerformancePaintTiming;
use crate::dom::servoparser::{ParserContext, ServoParser};
#[cfg(feature = "webgpu")]
use crate::dom::webgpu::identityhub::IdentityHub;
@ -896,7 +893,6 @@ impl ScriptThread {
bluetooth_sender: state.bluetooth_sender,
constellation_sender: state.constellation_sender,
pipeline_to_constellation_sender: state.pipeline_to_constellation_sender.sender.clone(),
layout_to_constellation_ipc_sender: state.layout_to_constellation_ipc_sender,
image_cache_sender: ipc_image_cache_sender,
time_profiler_sender: state.time_profiler_sender,
memory_profiler_sender: state.memory_profiler_sender,
@ -1849,9 +1845,18 @@ impl ScriptThread {
ScriptThreadMessage::ExitPipeline(pipeline_id, discard_browsing_context) => {
self.handle_exit_pipeline_msg(pipeline_id, discard_browsing_context, can_gc)
},
ScriptThreadMessage::PaintMetric(pipeline_id, metric_type, metric_value) => {
self.handle_paint_metric(pipeline_id, metric_type, metric_value, can_gc)
},
ScriptThreadMessage::PaintMetric(
pipeline_id,
metric_type,
metric_value,
first_reflow,
) => self.handle_paint_metric(
pipeline_id,
metric_type,
metric_value,
first_reflow,
can_gc,
),
ScriptThreadMessage::MediaSessionAction(pipeline_id, action) => {
self.handle_media_session_action(pipeline_id, action, can_gc)
},
@ -1872,9 +1877,6 @@ impl ScriptThread {
ScriptThreadMessage::SetScrollStates(pipeline_id, scroll_states) => {
self.handle_set_scroll_states_offsets(pipeline_id, scroll_states)
},
ScriptThreadMessage::SetEpochPaintTime(pipeline_id, epoch, time) => {
self.handle_set_epoch_paint_time(pipeline_id, epoch, time)
},
}
}
@ -1910,19 +1912,6 @@ impl ScriptThread {
)
}
fn handle_set_epoch_paint_time(
&self,
pipeline_id: PipelineId,
epoch: Epoch,
time: CrossProcessInstant,
) {
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);
}
#[cfg(feature = "webgpu")]
fn handle_msg_from_webgpu_server(&self, msg: WebGPUMsg, can_gc: CanGc) {
match msg {
@ -3056,16 +3045,6 @@ impl ScriptThread {
pipeline_id: incomplete.pipeline_id,
};
let paint_time_metrics = PaintTimeMetrics::new(
incomplete.webview_id,
incomplete.pipeline_id,
self.senders.time_profiler_sender.clone(),
self.senders.layout_to_constellation_ipc_sender.clone(),
self.senders.constellation_sender.clone(),
final_url.clone(),
incomplete.navigation_start,
);
let font_context = Arc::new(FontContext::new(
self.system_font_service.clone(),
self.compositor_api.clone(),
@ -3082,7 +3061,6 @@ impl ScriptThread {
font_context: font_context.clone(),
time_profiler_chan: self.senders.time_profiler_sender.clone(),
compositor_api: self.compositor_api.clone(),
paint_time_metrics,
window_size: incomplete.window_size,
};
@ -3619,19 +3597,16 @@ impl ScriptThread {
pipeline_id: PipelineId,
metric_type: ProgressiveWebMetricType,
metric_value: CrossProcessInstant,
first_reflow: bool,
can_gc: CanGc,
) {
let window = self.documents.borrow().find_window(pipeline_id);
if let Some(window) = window {
let entry = PerformancePaintTiming::new(
window.as_global_scope(),
metric_type,
metric_value,
can_gc,
);
window
.Performance()
.queue_entry(entry.upcast::<PerformanceEntry>(), can_gc);
match self.documents.borrow().find_document(pipeline_id) {
Some(document) => {
document.handle_paint_metric(metric_type, metric_value, first_reflow, can_gc)
},
None => warn!(
"Received paint metric ({metric_type:?}) for unknown document: {pipeline_id:?}"
),
}
}