1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-23 13:21:38 +03:00

wezterm-font: move caching of freetype font size into Face

Profiling showed that set_font_size was a hotspot.  While there was
caching of the size info at the shaper layer, it was also needed in
the raster layer, so move it into the raster layer from the shaper
layer.

refs: #353
This commit is contained in:
Wez Furlong 2020-11-25 09:20:14 -08:00
parent c7dc44a538
commit 58eb8e3614
4 changed files with 31 additions and 23 deletions

1
.gitignore vendored
View File

@ -25,3 +25,4 @@
/wezterm*-src.tar.gz /wezterm*-src.tar.gz
/wezterm-linuxbrew.rb /wezterm-linuxbrew.rb
/wezterm.rb /wezterm.rb
/perf.data*

View File

@ -3,3 +3,4 @@ members = ["wezterm-mux-server", "wezterm", "wezterm-gui", "strip-ansi-escapes"]
[profile.release] [profile.release]
opt-level = 3 opt-level = 3
# debug = 1

View File

@ -63,6 +63,7 @@ pub fn compute_load_flags_from_config() -> (i32, FT_Render_Mode) {
pub struct Face { pub struct Face {
pub face: FT_Face, pub face: FT_Face,
_bytes: Vec<u8>, _bytes: Vec<u8>,
size: Option<FaceSize>,
} }
impl Drop for Face { impl Drop for Face {
@ -73,14 +74,27 @@ impl Drop for Face {
} }
} }
struct FaceSize {
size: f64,
dpi: u32,
cell_width: f64,
cell_height: f64,
}
impl Face { impl Face {
/// This is a wrapper around set_char_size and select_size /// This is a wrapper around set_char_size and select_size
/// that accounts for some weirdness with eg: color emoji /// that accounts for some weirdness with eg: color emoji
pub fn set_font_size(&mut self, size: f64, dpi: u32) -> anyhow::Result<(f64, f64)> { pub fn set_font_size(&mut self, point_size: f64, dpi: u32) -> anyhow::Result<(f64, f64)> {
log::debug!("set_char_size {} dpi={}", size, dpi); if let Some(face_size) = self.size.as_ref() {
if face_size.size == point_size && face_size.dpi == dpi {
return Ok((face_size.cell_width, face_size.cell_height));
}
}
log::debug!("set_char_size computing {} dpi={}", point_size, dpi);
// Scaling before truncating to integer minimizes the chances of hitting // Scaling before truncating to integer minimizes the chances of hitting
// the fallback code for set_pixel_sizes below. // the fallback code for set_pixel_sizes below.
let size = (size * 64.0) as FT_F26Dot6; let size = (point_size * 64.0) as FT_F26Dot6;
let (cell_width, cell_height) = match self.set_char_size(size, size, dpi, dpi) { let (cell_width, cell_height) = match self.set_char_size(size, size, dpi, dpi) {
Ok(_) => { Ok(_) => {
@ -116,6 +130,13 @@ impl Face {
} }
}; };
self.size.replace(FaceSize {
size: point_size,
dpi,
cell_width,
cell_height,
});
Ok((cell_width, cell_height)) Ok((cell_width, cell_height))
} }
@ -263,6 +284,7 @@ impl Library {
) )
})?, })?,
_bytes: data, _bytes: data,
size: None,
}) })
} }
@ -283,6 +305,7 @@ impl Library {
face: ft_result(res, face) face: ft_result(res, face)
.with_context(|| format!("FT_New_Memory_Face for index {}", face_index))?, .with_context(|| format!("FT_New_Memory_Face for index {}", face_index))?,
_bytes: data, _bytes: data,
size: None,
}) })
} }

View File

@ -50,10 +50,6 @@ fn make_glyphinfo(text: &str, font_idx: usize, info: &Info) -> GlyphInfo {
struct FontPair { struct FontPair {
face: ftwrap::Face, face: ftwrap::Face,
font: harfbuzz::Font, font: harfbuzz::Font,
size: f64,
dpi: u32,
cell_width: f64,
cell_height: f64,
} }
#[derive(Debug, Hash, PartialEq, Eq, Clone)] #[derive(Debug, Hash, PartialEq, Eq, Clone)]
@ -133,14 +129,7 @@ impl HarfbuzzShaper {
let mut font = harfbuzz::Font::new(face.face); let mut font = harfbuzz::Font::new(face.face);
let (load_flags, _) = ftwrap::compute_load_flags_from_config(); let (load_flags, _) = ftwrap::compute_load_flags_from_config();
font.set_load_flags(load_flags); font.set_load_flags(load_flags);
*opt_pair = Some(FontPair { *opt_pair = Some(FontPair { face, font });
face,
font,
size: 0.,
dpi: 0,
cell_width: 0.,
cell_height: 0.,
});
} }
Ok(Some(RefMut::map(opt_pair, |opt_pair| { Ok(Some(RefMut::map(opt_pair, |opt_pair| {
@ -180,14 +169,8 @@ impl HarfbuzzShaper {
match self.load_fallback(font_idx)? { match self.load_fallback(font_idx)? {
#[allow(clippy::float_cmp)] #[allow(clippy::float_cmp)]
Some(mut pair) => { Some(mut pair) => {
if pair.size != font_size || pair.dpi != dpi { let (width, _height) = pair.face.set_font_size(font_size, dpi)?;
let (width, height) = pair.face.set_font_size(font_size, dpi)?; cell_width = width;
pair.size = font_size;
pair.dpi = dpi;
pair.cell_width = width;
pair.cell_height = height;
}
cell_width = pair.cell_width;
pair.font.shape(&mut buf, Some(features.as_slice())); pair.font.shape(&mut buf, Some(features.as_slice()));
} }
None => { None => {