aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout_2020/flow/inline/text_run.rs
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2024-09-26 15:44:23 +0200
committerMartin Robinson <mrobinson@igalia.com>2024-10-01 16:25:51 +0200
commitd521f5724cbaab420eba78732b8dab486c45a75a (patch)
tree4ab3ff8a4a40c095af7bdf44b6da2b85fa44dcd7 /components/layout_2020/flow/inline/text_run.rs
parent5ee8e2e55b9726015b0cd3d21f4f4f9b084a5b67 (diff)
downloadservo-fonts-fast-ipc-turnaround.tar.gz
servo-fonts-fast-ipc-turnaround.zip
fonts: Make `FontKey` and `FontInstanceKey` generation asynchronousfonts-fast-ipc-turnaround
Instead of a blocking a layout thread on the generation of WebRender `FontKey`s and `FontInstanceKey`s, generate the keys ahead of time and send the font data to WebRender asynchronously. This has the benefit of allowing use of the font much more quickly in layout, though blocking display list sending itself on the font data upload. In order to make this work for web fonts, `FontContext` now asks the `SystemFontService` for a `FontKey`s and `FontInstanceKey`s for new web fonts. This should happen much more quickly as the `SystemFontService` is only blocking in order to load system fonts into memory now. In practice this still drops layout thread blocking to fractions of a millisecond instead of multiple milliseconds as before. In addition, ensure that we don't send font data or generate keys for fonts that are used in layout but never added to display lists. This should help to reduce memory usage and increase performance. Performance of this change was verified by putting a microbenchmark around `FontContext::create_font` which is what triggered font key generation. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Diffstat (limited to 'components/layout_2020/flow/inline/text_run.rs')
-rw-r--r--components/layout_2020/flow/inline/text_run.rs31
1 files changed, 21 insertions, 10 deletions
diff --git a/components/layout_2020/flow/inline/text_run.rs b/components/layout_2020/flow/inline/text_run.rs
index d5438a103e1..76ec3032d0e 100644
--- a/components/layout_2020/flow/inline/text_run.rs
+++ b/components/layout_2020/flow/inline/text_run.rs
@@ -109,6 +109,7 @@ impl TextRunSegment {
script: Script,
bidi_level: Level,
fonts: &[FontKeyAndMetrics],
+ font_context: &FontContext,
) -> bool {
fn is_specific(script: Script) -> bool {
script != Script::Common && script != Script::Inherited
@@ -119,7 +120,7 @@ impl TextRunSegment {
}
let current_font_key_and_metrics = &fonts[self.font_index];
- if new_font.font_key != current_font_key_and_metrics.key ||
+ if new_font.key(font_context) != current_font_key_and_metrics.key ||
new_font.descriptor.pt_size != current_font_key_and_metrics.pt_size
{
return false;
@@ -440,15 +441,18 @@ impl TextRun {
let script = Script::from(character);
let bidi_level = bidi_info.levels[current_byte_index];
if let Some(current) = current.as_mut() {
- if current
- .0
- .update_if_compatible(&font, script, bidi_level, font_cache)
- {
+ if current.0.update_if_compatible(
+ &font,
+ script,
+ bidi_level,
+ font_cache,
+ font_context,
+ ) {
continue;
}
}
- let font_index = add_or_get_font(&font, font_cache);
+ let font_index = add_or_get_font(&font, font_cache, font_context);
// Add the new segment and finish the existing one, if we had one. If the first
// characters in the run were control characters we may be creating the first
@@ -473,7 +477,7 @@ impl TextRun {
// of those cases, just use the first font.
if current.is_none() {
current = font_group.write().first(font_context).map(|font| {
- let font_index = add_or_get_font(&font, font_cache);
+ let font_index = add_or_get_font(&font, font_cache, font_context);
(
TextRunSegment::new(
font_index,
@@ -539,15 +543,22 @@ fn char_does_not_change_font(character: char) -> bool {
class == XI_LINE_BREAKING_CLASS_ZWJ
}
-pub(super) fn add_or_get_font(font: &FontRef, ifc_fonts: &mut Vec<FontKeyAndMetrics>) -> usize {
+pub(super) fn add_or_get_font(
+ font: &FontRef,
+ ifc_fonts: &mut Vec<FontKeyAndMetrics>,
+ font_context: &FontContext,
+) -> usize {
+ let font_instance_key = font.key(font_context);
for (index, ifc_font_info) in ifc_fonts.iter().enumerate() {
- if ifc_font_info.key == font.font_key && ifc_font_info.pt_size == font.descriptor.pt_size {
+ if ifc_font_info.key == font_instance_key &&
+ ifc_font_info.pt_size == font.descriptor.pt_size
+ {
return index;
}
}
ifc_fonts.push(FontKeyAndMetrics {
metrics: font.metrics.clone(),
- key: font.font_key,
+ key: font_instance_key,
pt_size: font.descriptor.pt_size,
});
ifc_fonts.len() - 1