diff options
author | Martin Robinson <mrobinson@igalia.com> | 2024-05-22 10:30:35 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-22 08:30:35 +0000 |
commit | 9f32809671c8c8e79d59c95194dcc466452299fc (patch) | |
tree | e813eb7d1e3971bba08ad119ff6ddf15ebca6d01 /components/layout_thread | |
parent | d47c8ff2aeebe5854a7c8484a33d285268347fee (diff) | |
download | servo-9f32809671c8c8e79d59c95194dcc466452299fc.tar.gz servo-9f32809671c8c8e79d59c95194dcc466452299fc.zip |
fonts: Clean up messaging during web fonts loads (#32332)
Instead of sending a message to the script thread via IPC when a web
font loads and then sending another, just give the `FontContext` a
callback that send a single message to the script thread. This moves all
the cache invalidation internally into `FontContext` as well.
Additionally, the unused LayoutControlMessage::ExitNow enum variant is
removed.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
Diffstat (limited to 'components/layout_thread')
-rw-r--r-- | components/layout_thread/lib.rs | 115 |
1 files changed, 42 insertions, 73 deletions
diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 22cbb52fc6a..f4efdc17c41 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -13,7 +13,6 @@ use std::cell::{Cell, RefCell}; use std::collections::HashMap; use std::ops::{Deref, DerefMut}; use std::process; -use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::{Arc, Mutex}; use app_units::Au; @@ -27,9 +26,9 @@ use fxhash::{FxHashMap, FxHashSet}; use gfx::font; use gfx::font_cache_thread::FontCacheThread; use gfx::font_context::{FontContext, FontContextWebFontMethods}; +use gfx_traits::WebFontLoadFinishedCallback; use histogram::Histogram; -use ipc_channel::ipc::{self, IpcSender}; -use ipc_channel::router::ROUTER; +use ipc_channel::ipc::IpcSender; use layout::construct::ConstructionResult; use layout::context::{LayoutContext, RegisteredPainter, RegisteredPainters}; use layout::display_list::items::{DisplayList, ScrollOffsetMap, WebRenderImageInfo}; @@ -119,9 +118,6 @@ pub struct LayoutThread { /// Is the current reflow of an iframe, as opposed to a root window? is_iframe: bool, - /// The channel on which the font cache can send messages to us. - font_cache_sender: IpcSender<()>, - /// The channel on which messages can be sent to the constellation. constellation_chan: IpcSender<ConstellationMsg>, @@ -147,9 +143,6 @@ pub struct LayoutThread { /// This can be used to easily check for invalid stale data. generation: Cell<u32>, - /// The number of Web fonts that have been requested but not yet loaded. - outstanding_web_fonts: Arc<AtomicUsize>, - /// The root of the flow tree. root_flow: RefCell<Option<FlowRef>>, @@ -252,12 +245,18 @@ impl Drop for ScriptReflowResult { } impl Layout for LayoutThread { - fn handle_constellation_msg(&mut self, msg: script_traits::LayoutControlMsg) { - self.handle_request(Request::FromPipeline(msg)); - } - - fn handle_font_cache_msg(&mut self) { - self.handle_request(Request::FromFontCache); + 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 { @@ -265,7 +264,7 @@ impl Layout for LayoutThread { } fn waiting_for_web_fonts_to_load(&self) -> bool { - self.outstanding_web_fonts.load(Ordering::SeqCst) != 0 + self.font_context.web_fonts_still_loading() != 0 } fn current_epoch(&self) -> Epoch { @@ -548,11 +547,6 @@ impl Layout for LayoutThread { ); } } -enum Request { - FromPipeline(LayoutControlMsg), - FromFontCache, -} - impl LayoutThread { fn root_flow_for_query(&self) -> Option<FlowRef> { self.root_flow.borrow().clone() @@ -584,17 +578,6 @@ impl LayoutThread { Box::new(LayoutFontMetricsProvider), ); - // Ask the router to proxy IPC messages from the font cache thread to layout. - let (ipc_font_cache_sender, ipc_font_cache_receiver) = ipc::channel().unwrap(); - let cloned_script_chan = script_chan.clone(); - ROUTER.add_route( - ipc_font_cache_receiver.to_opaque(), - Box::new(move |_message| { - let _ = - cloned_script_chan.send(ConstellationControlMsg::ForLayoutFromFontCache(id)); - }), - ); - LayoutThread { id, url, @@ -606,10 +589,8 @@ impl LayoutThread { image_cache, font_context, first_reflow: Cell::new(true), - font_cache_sender: ipc_font_cache_sender, parallel_flag: true, generation: Cell::new(0), - outstanding_web_fonts: Arc::new(AtomicUsize::new(0)), root_flow: RefCell::new(None), // Epoch starts at 1 because of the initial display list for epoch 0 that we send to WR epoch: Cell::new(Epoch(1)), @@ -685,53 +666,41 @@ impl LayoutThread { } } - /// Receives and dispatches messages from the script and constellation threads - fn handle_request(&mut self, request: Request) { - match request { - Request::FromFontCache => { - self.outstanding_web_fonts.fetch_sub(1, Ordering::SeqCst); - self.handle_web_font_loaded(); - }, - Request::FromPipeline(LayoutControlMsg::ExitNow) => self.exit_now(), - Request::FromPipeline(LayoutControlMsg::SetScrollStates(new_scroll_states)) => { - self.set_scroll_states(new_scroll_states); - }, - Request::FromPipeline(LayoutControlMsg::PaintMetric(epoch, paint_time)) => { - self.paint_time_metrics.maybe_set_metric(epoch, paint_time); - }, - }; - } - fn load_all_web_fonts_from_stylesheet_with_guard( &self, stylesheet: &Stylesheet, guard: &SharedRwLockReadGuard, ) { - // Find all font-face rules and notify the font cache of them. - // GWTODO: Need to handle unloading web fonts. - if stylesheet.is_effective_for_device(self.stylist.device(), guard) { - let newly_loading_font_count = self.font_context.add_all_web_fonts_from_stylesheet( - stylesheet, - guard, - self.stylist.device(), - &self.font_cache_sender, - self.debug.load_webfonts_synchronously, - ); + if !stylesheet.is_effective_for_device(self.stylist.device(), guard) { + return; + } - if !self.debug.load_webfonts_synchronously { - self.outstanding_web_fonts - .fetch_add(newly_loading_font_count, Ordering::SeqCst); - } else if newly_loading_font_count > 0 { - self.handle_web_font_loaded(); + let locked_script_channel = Mutex::new(self.script_chan.clone()); + let pipeline_id = self.id; + let web_font_finished_loading_callback = move |succeeded: bool| { + if succeeded { + let _ = locked_script_channel + .lock() + .unwrap() + .send(ConstellationControlMsg::WebFontLoaded(pipeline_id)); } - } - } + }; - fn handle_web_font_loaded(&self) { - self.font_context.invalidate_caches(); - self.script_chan - .send(ConstellationControlMsg::WebFontLoaded(self.id)) - .unwrap(); + // Find all font-face rules and notify the FontContext of them. + // GWTODO: Need to handle unloading web fonts. + let newly_loading_font_count = self.font_context.add_all_web_fonts_from_stylesheet( + stylesheet, + guard, + self.stylist.device(), + Arc::new(web_font_finished_loading_callback) as WebFontLoadFinishedCallback, + self.debug.load_webfonts_synchronously, + ); + + if self.debug.load_webfonts_synchronously && newly_loading_font_count > 0 { + let _ = self + .script_chan + .send(ConstellationControlMsg::WebFontLoaded(self.id)); + } } fn try_get_layout_root<'dom>(&self, node: impl LayoutNode<'dom>) -> Option<FlowRef> { |