diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index a01ae8c424d..1a5630293b3 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -23,7 +23,6 @@ use euclid::{Point2D, Rect, Scale, Size2D}; use fnv::FnvHashMap; use fonts::{ get_and_reset_text_shaping_performance_counter, FontContext, FontContextWebFontMethods, - SystemFontServiceProxy, }; use fonts_traits::WebFontLoadFinishedCallback; use fxhash::{FxHashMap, FxHashSet}; @@ -51,7 +50,6 @@ use log::{debug, error, trace}; use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; use metrics::{PaintTimeMetrics, ProfilerMetadataFactory}; use net_traits::image_cache::{ImageCache, UsePlaceholder}; -use net_traits::ResourceThreads; use parking_lot::RwLock; use profile_traits::mem::{Report, ReportKind}; use profile_traits::time::{ @@ -203,8 +201,7 @@ impl LayoutFactory for LayoutFactoryImpl { config.is_iframe, config.script_chan, config.image_cache, - config.resource_threads, - config.system_font_service, + config.font_context, config.time_profiler_chan, config.compositor_api, config.paint_time_metrics, @@ -228,10 +225,6 @@ impl Layout for LayoutThread { self.stylist.device() } - fn waiting_for_web_fonts_to_load(&self) -> bool { - self.font_context.web_fonts_still_loading() != 0 - } - fn current_epoch(&self) -> Epoch { self.epoch.get() } @@ -517,8 +510,7 @@ impl LayoutThread { is_iframe: bool, script_chan: IpcSender, image_cache: Arc, - resource_threads: ResourceThreads, - system_font_service: Arc, + font_context: Arc, time_profiler_chan: profile_time::ProfilerChan, compositor_api: CrossProcessCompositorApi, paint_time_metrics: PaintTimeMetrics, @@ -535,11 +527,6 @@ impl LayoutThread { keyword_info: KeywordInfo::medium(), }; - let font_context = Arc::new(FontContext::new( - system_font_service, - compositor_api.clone(), - resource_threads, - )); let device = Device::new( MediaType::screen(), QuirksMode::NoQuirks, diff --git a/components/layout_thread_2020/lib.rs b/components/layout_thread_2020/lib.rs index 0010f68e022..496e15b16ee 100644 --- a/components/layout_thread_2020/lib.rs +++ b/components/layout_thread_2020/lib.rs @@ -22,7 +22,7 @@ use embedder_traits::resources::{self, Resource}; use euclid::default::{Point2D as UntypedPoint2D, Rect as UntypedRect, Size2D as UntypedSize2D}; use euclid::{Point2D, Scale, Size2D, Vector2D}; use fnv::FnvHashMap; -use fonts::{FontContext, FontContextWebFontMethods, SystemFontServiceProxy}; +use fonts::{FontContext, FontContextWebFontMethods}; use fonts_traits::WebFontLoadFinishedCallback; use fxhash::FxHashMap; use ipc_channel::ipc::IpcSender; @@ -39,7 +39,6 @@ use log::{debug, error}; use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; use metrics::{PaintTimeMetrics, ProfilerMetadataFactory}; use net_traits::image_cache::{ImageCache, UsePlaceholder}; -use net_traits::ResourceThreads; use parking_lot::{Mutex, RwLock}; use profile_traits::mem::{Report, ReportKind}; use profile_traits::time::{ @@ -176,8 +175,7 @@ impl LayoutFactory for LayoutFactoryImpl { config.is_iframe, config.script_chan, config.image_cache, - config.resource_threads, - config.system_font_service, + config.font_context, config.time_profiler_chan, config.compositor_api, config.paint_time_metrics, @@ -201,10 +199,6 @@ impl Layout for LayoutThread { self.stylist.device() } - fn waiting_for_web_fonts_to_load(&self) -> bool { - self.font_context.web_fonts_still_loading() != 0 - } - fn current_epoch(&self) -> Epoch { self.epoch.get() } @@ -491,8 +485,7 @@ impl LayoutThread { is_iframe: bool, script_chan: IpcSender, image_cache: Arc, - resource_threads: ResourceThreads, - system_font_service: Arc, + font_context: Arc, time_profiler_chan: profile_time::ProfilerChan, compositor_api: CrossProcessCompositorApi, paint_time_metrics: PaintTimeMetrics, @@ -511,11 +504,6 @@ impl LayoutThread { // The device pixel ratio is incorrect (it does not have the hidpi value), // but it will be set correctly when the initial reflow takes place. - let font_context = Arc::new(FontContext::new( - system_font_service, - compositor_api.clone(), - resource_threads, - )); let device = Device::new( MediaType::screen(), QuirksMode::NoQuirks, diff --git a/components/malloc_size_of/lib.rs b/components/malloc_size_of/lib.rs index 94e49004e4b..d53aacf27f2 100644 --- a/components/malloc_size_of/lib.rs +++ b/components/malloc_size_of/lib.rs @@ -50,6 +50,7 @@ use std::cell::OnceCell; use std::collections::BinaryHeap; use std::hash::{BuildHasher, Hash}; use std::ops::Range; +use std::sync::Arc; pub use style_malloc_size_of::MallocSizeOfOps; use uuid::Uuid; @@ -523,6 +524,38 @@ impl MallocConditionalSizeOf for servo_arc::Arc { } } +impl MallocUnconditionalShallowSizeOf for Arc { + fn unconditional_shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + unsafe { ops.malloc_size_of(Arc::as_ptr(self)) } + } +} + +impl MallocUnconditionalSizeOf for Arc { + fn unconditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + self.unconditional_shallow_size_of(ops) + (**self).size_of(ops) + } +} + +impl MallocConditionalShallowSizeOf for Arc { + fn conditional_shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + if ops.have_seen_ptr(Arc::as_ptr(self)) { + 0 + } else { + self.unconditional_shallow_size_of(ops) + } + } +} + +impl MallocConditionalSizeOf for Arc { + fn conditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + if ops.have_seen_ptr(Arc::as_ptr(self)) { + 0 + } else { + self.unconditional_size_of(ops) + } + } +} + /// If a mutex is stored directly as a member of a data type that is being measured, /// it is the unique owner of its contents and deserves to be measured. /// diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 270834da574..61ee2412880 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -28,6 +28,7 @@ use dom_struct::dom_struct; use embedder_traits::{EmbedderMsg, PromptDefinition, PromptOrigin, PromptResult}; use euclid::default::{Point2D as UntypedPoint2D, Rect as UntypedRect}; use euclid::{Point2D, Rect, Scale, Size2D, Vector2D}; +use fonts::FontContext; use ipc_channel::ipc::{self, IpcSender}; use ipc_channel::router::ROUTER; use js::conversions::ToJSValConvertible; @@ -207,6 +208,11 @@ pub struct Window { #[no_trace] #[ignore_malloc_size_of = "TODO: Add MallocSizeOf support to layout"] layout: RefCell>, + /// A [`FontContext`] which is used to store and match against fonts for this `Window` and to + /// trigger the download of web fonts. + #[no_trace] + #[conditional_malloc_size_of] + font_context: Arc, navigator: MutNullableDom, #[ignore_malloc_size_of = "Arc"] #[no_trace] @@ -1942,9 +1948,8 @@ impl Window { /// should happen as part of the HTML event loop via *update the rendering*. Currerntly, the /// only exceptions are script queries and scroll requests. pub(crate) fn reflow(&self, reflow_goal: ReflowGoal, can_gc: CanGc) -> bool { - // Fetch the pending web fonts before layout, in case a font loads during - // the layout. - let pending_web_fonts = self.layout.borrow().waiting_for_web_fonts_to_load(); + // Count the pending web fonts before layout, in case a font loads during the layout. + let waiting_for_web_fonts_to_load = self.font_context.web_fonts_still_loading() != 0; self.Document().ensure_safe_to_run_script_or_layout(); @@ -1988,7 +1993,7 @@ impl Window { // Thus, we are queueing promise resolution here. This reflow should have been triggered by // a "rendering opportunity" in `ScriptThread::handle_web_font_loaded, which should also // make sure a microtask checkpoint happens, triggering the promise callback. - if !pending_web_fonts && is_ready_state_complete { + if !waiting_for_web_fonts_to_load && is_ready_state_complete { font_face_set.fulfill_ready_promise_if_needed(); } @@ -2017,7 +2022,7 @@ impl Window { is_ready_state_complete && !reftest_wait && !pending_images && - !pending_web_fonts + !waiting_for_web_fonts_to_load { debug!( "{:?}: Sending DocumentState::Idle to Constellation", @@ -2674,6 +2679,7 @@ impl Window { runtime: Rc, script_chan: MainThreadScriptChan, layout: Box, + font_context: Arc, image_cache_chan: Sender, image_cache: Arc, resource_threads: ResourceThreads, @@ -2737,6 +2743,7 @@ impl Window { ), script_chan, layout: RefCell::new(layout), + font_context, image_cache_chan, image_cache, navigator: Default::default(), diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index b743b8b264f..00d2ef64f0c 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -47,7 +47,7 @@ use devtools_traits::{ }; use embedder_traits::EmbedderMsg; use euclid::default::{Point2D, Rect}; -use fonts::SystemFontServiceProxy; +use fonts::{FontContext, SystemFontServiceProxy}; use headers::{HeaderMapExt, LastModified, ReferrerPolicy as ReferrerPolicyHeader}; use html5ever::{local_name, namespace_url, ns}; use hyper_serde::Serde; @@ -3142,6 +3142,12 @@ impl ScriptThread { incomplete.navigation_start, ); + let font_context = Arc::new(FontContext::new( + self.system_font_service.clone(), + self.compositor_api.clone(), + self.resource_threads.clone(), + )); + let layout_config = LayoutConfig { id: incomplete.pipeline_id, url: final_url.clone(), @@ -3149,8 +3155,7 @@ impl ScriptThread { constellation_chan: self.senders.layout_to_constellation_ipc_sender.clone(), script_chan: self.senders.constellation_sender.clone(), image_cache: self.image_cache.clone(), - system_font_service: self.system_font_service.clone(), - resource_threads: self.resource_threads.clone(), + font_context: font_context.clone(), time_profiler_chan: self.senders.time_profiler_sender.clone(), compositor_api: self.compositor_api.clone(), paint_time_metrics, @@ -3162,6 +3167,7 @@ impl ScriptThread { self.js_runtime.clone(), self.senders.self_sender.clone(), self.layout_factory.create(layout_config), + font_context, self.senders.image_cache_sender.clone(), self.image_cache.clone(), self.resource_threads.clone(), diff --git a/components/shared/script_layout/lib.rs b/components/shared/script_layout/lib.rs index f8643e866e7..d1b31da003f 100644 --- a/components/shared/script_layout/lib.rs +++ b/components/shared/script_layout/lib.rs @@ -24,13 +24,12 @@ use canvas_traits::canvas::{CanvasId, CanvasMsg}; use euclid::default::{Point2D, Rect}; use euclid::Size2D; use fnv::FnvHashMap; -use fonts::SystemFontServiceProxy; +use fonts::{FontContext, SystemFontServiceProxy}; use ipc_channel::ipc::IpcSender; use libc::c_void; use malloc_size_of_derive::MallocSizeOf; use metrics::PaintTimeMetrics; use net_traits::image_cache::{ImageCache, PendingImageId}; -use net_traits::ResourceThreads; use profile_traits::mem::Report; use profile_traits::time; use script_traits::{ @@ -188,8 +187,7 @@ pub struct LayoutConfig { pub constellation_chan: IpcSender, pub script_chan: IpcSender, pub image_cache: Arc, - pub resource_threads: ResourceThreads, - pub system_font_service: Arc, + pub font_context: Arc, pub time_profiler_chan: time::ProfilerChan, pub compositor_api: CrossProcessCompositorApi, pub paint_time_metrics: PaintTimeMetrics, @@ -205,9 +203,6 @@ pub trait Layout { /// resolve font metrics. fn device(&self) -> &Device; - /// Whether or not this layout is waiting for fonts from loaded stylesheets to finish loading. - fn waiting_for_web_fonts_to_load(&self) -> bool; - /// The currently laid out Epoch that this Layout has finished. fn current_epoch(&self) -> Epoch;