fonts: Make FontContext thread-safe and share it per-Layout (#32205)

This allows sharing font templates, fonts, and platform fonts across
layout threads. It's the first step toward storing web fonts in the
layout versus the shared `FontCacheThread`. Now fonts and font groups
have some locking (especially on FreeType), which will probably affect
performance. On the other hand, we measured memory usage and this saves
roughly 40 megabytes of memory when loading servo.org based on data from
the memory profiler.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
This commit is contained in:
Martin Robinson 2024-05-02 12:34:10 +02:00 committed by GitHub
parent 8ec5344f70
commit 556bfb7dff
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 437 additions and 500 deletions

View file

@ -2,7 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::cell::RefCell;
use std::sync::{Arc, Mutex};
use fnv::FnvHashMap;
@ -12,7 +11,7 @@ use msg::constellation_msg::PipelineId;
use net_traits::image_cache::{
ImageCache, ImageCacheResult, ImageOrMetadataAvailable, UsePlaceholder,
};
use parking_lot::{ReentrantMutex, RwLock};
use parking_lot::RwLock;
use script_layout_interface::{PendingImage, PendingImageState};
use servo_url::{ImmutableOrigin, ServoUrl};
use style::context::SharedStyleContext;
@ -20,8 +19,6 @@ use style::dom::OpaqueNode;
use crate::display_list::WebRenderImageInfo;
thread_local!(static FONT_CONTEXT: RefCell<Option<FontContext<FontCacheThread>>> = RefCell::new(None));
pub struct LayoutContext<'a> {
pub id: PipelineId,
pub use_rayon: bool,
@ -31,7 +28,7 @@ pub struct LayoutContext<'a> {
pub style_context: SharedStyleContext<'a>,
/// A FontContext to be used during layout.
pub font_cache_thread: Arc<ReentrantMutex<FontCacheThread>>,
pub font_context: Arc<FontContext<FontCacheThread>>,
/// Reference to the script thread image cache.
pub image_cache: Arc<dyn ImageCache>,
@ -133,27 +130,4 @@ impl<'a> LayoutContext<'a> {
None | Some(ImageOrMetadataAvailable::MetadataAvailable(_)) => None,
}
}
pub fn with_font_context<F, R>(&self, callback: F) -> R
where
F: FnOnce(&mut FontContext<FontCacheThread>) -> R,
{
with_thread_local_font_context(&self.font_cache_thread, callback)
}
}
pub fn with_thread_local_font_context<F, R>(
font_cache_thread: &ReentrantMutex<FontCacheThread>,
callback: F,
) -> R
where
F: FnOnce(&mut FontContext<FontCacheThread>) -> R,
{
FONT_CONTEXT.with(|font_context| {
callback(
font_context
.borrow_mut()
.get_or_insert_with(|| FontContext::new(font_cache_thread.lock().clone())),
)
})
}