From 7339e2b421b9982354cd1e8f5499f9a91370a6e6 Mon Sep 17 00:00:00 2001 From: criskell <96352451+criskell@users.noreply.github.com> Date: Tue, 26 Aug 2025 09:47:04 -0300 Subject: [PATCH] Add scroll tree measurement in IOCompositor (#38922) Adds a new memory report that aggregates the size of all scroll trees from within all pipelines for each web view. Testing: Acessing `about:memory` Fixes: #38726 --------- Signed-off-by: criskell <96352451+criskell@users.noreply.github.com> --- Cargo.lock | 1 + components/compositing/Cargo.toml | 1 + components/compositing/compositor.rs | 15 +++++++++++++-- components/compositing/webview_manager.rs | 13 ++++++++++++- components/compositing/webview_renderer.rs | 11 +++++++++++ 5 files changed, 38 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5244a0fb3b8..e5bba184db3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1409,6 +1409,7 @@ dependencies = [ "servo_allocator", "servo_config", "servo_geometry", + "servo_malloc_size_of", "stylo_traits", "surfman", "timers", diff --git a/components/compositing/Cargo.toml b/components/compositing/Cargo.toml index d5792b858db..de35ce24e1f 100644 --- a/components/compositing/Cargo.toml +++ b/components/compositing/Cargo.toml @@ -35,6 +35,7 @@ gleam = { workspace = true } ipc-channel = { workspace = true } libc = { workspace = true } log = { workspace = true } +malloc_size_of = { workspace = true } pixels = { path = "../pixels" } profile_traits = { workspace = true } servo_allocator = { path = "../allocator" } diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index 3943da095d8..40f74b8c20e 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -29,7 +29,9 @@ use euclid::{Point2D, Rect, Scale, Size2D, Transform3D}; use ipc_channel::ipc::{self, IpcSender, IpcSharedMemory}; use log::{debug, info, trace, warn}; use pixels::{CorsStatus, ImageFrame, ImageMetadata, PixelFormat, RasterImage}; -use profile_traits::mem::{ProcessReports, ProfilerRegistration, Report, ReportKind}; +use profile_traits::mem::{ + ProcessReports, ProfilerRegistration, Report, ReportKind, perform_memory_report, +}; use profile_traits::time::{self as profile_time, ProfilerCategory}; use profile_traits::{path, time_profile}; use servo_config::{opts, pref}; @@ -421,7 +423,7 @@ impl IOCompositor { let ops = wr_malloc_size_of::MallocSizeOfOps::new(servo_allocator::usable_size, None); let report = self.global.borrow().webrender_api.report_memory(ops); - let reports = vec![ + let mut reports = vec![ Report { path: path!["webrender", "fonts"], kind: ReportKind::ExplicitJemallocHeapSize, @@ -438,6 +440,15 @@ impl IOCompositor { size: report.display_list, }, ]; + + perform_memory_report(|ops| { + reports.push(Report { + path: path!["compositor", "scroll-tree"], + kind: ReportKind::ExplicitJemallocHeapSize, + size: self.webview_renderers.scroll_trees_memory_usage(ops), + }); + }); + sender.send(ProcessReports::new(reports)); }, diff --git a/components/compositing/webview_manager.rs b/components/compositing/webview_manager.rs index 544f90d489c..953d6e3bd5d 100644 --- a/components/compositing/webview_manager.rs +++ b/components/compositing/webview_manager.rs @@ -7,7 +7,7 @@ use std::collections::hash_map::{Entry, Values, ValuesMut}; use base::id::WebViewId; -use crate::webview_renderer::UnknownWebView; +use crate::webview_renderer::{UnknownWebView, WebViewRenderer}; #[derive(Debug)] pub struct WebViewManager { @@ -109,6 +109,17 @@ impl WebViewManager { } } +impl WebViewManager { + pub(crate) fn scroll_trees_memory_usage( + &self, + ops: &mut malloc_size_of::MallocSizeOfOps, + ) -> usize { + self.iter() + .map(|renderer| renderer.scroll_trees_memory_usage(ops)) + .sum::() + } +} + #[cfg(test)] mod test { use base::id::{BrowsingContextId, Index, PipelineNamespace, PipelineNamespaceId, WebViewId}; diff --git a/components/compositing/webview_renderer.rs b/components/compositing/webview_renderer.rs index 1308574b6fb..ac4d80cb69a 100644 --- a/components/compositing/webview_renderer.rs +++ b/components/compositing/webview_renderer.rs @@ -22,6 +22,7 @@ use embedder_traits::{ use euclid::{Point2D, Scale, Vector2D}; use fnv::FnvHashSet; use log::{debug, warn}; +use malloc_size_of::MallocSizeOf; use servo_geometry::DeviceIndependentPixel; use style_traits::{CSSPixel, PinchZoomFactor}; use webrender_api::units::{DeviceIntPoint, DevicePixel, DevicePoint, DeviceRect, LayoutVector2D}; @@ -1001,6 +1002,16 @@ impl WebViewRenderer { )); self.viewport_description = Some(viewport_description); } + + pub(crate) fn scroll_trees_memory_usage( + &self, + ops: &mut malloc_size_of::MallocSizeOfOps, + ) -> usize { + self.pipelines + .values() + .map(|pipeline| pipeline.scroll_tree.size_of(ops)) + .sum::() + } } #[derive(Clone, Copy, Debug, PartialEq)]