1
1
mirror of https://github.com/wez/wezterm.git synced 2024-09-20 11:17:15 +03:00

fonts: avoid making an in-memory copy of OnDisk font handles

In an earlier incarnation of both wezterm and freetype, FT_New_Face
would lead file descriptors into child processes because it didn't
set O_CLOEXEC.  That led to the slightly pessimistic approach of
loading the font into memory for the lifetime of the wezterm process.

With the improved fallback handling on macos, this can result in
hundreds of MB of font data being loaded, in some cases multiple
times.

Since those days, freetype now sets O_CLOEXEC and wezterm has some
logic to close other random fds, so the descriptor leaking problem
is gone and we can now let freetype manage a file handle instead
of a memory-baked font.

This reduces the memory utilization by at least 1GB in the case
that a glyphs need to be resolved from the system fallback fonts.

refs: https://github.com/wez/wezterm/issues/559
This commit is contained in:
Wez Furlong 2021-03-20 23:00:53 -07:00
parent 72f2ff850f
commit eafe01e946

View File

@ -323,11 +323,33 @@ impl Library {
P: AsRef<std::path::Path>,
{
let mut face = ptr::null_mut();
if let Some(path_str) = path.as_ref().to_str() {
if let Ok(path_cstr) = std::ffi::CString::new(path_str) {
let res = unsafe {
FT_New_Face(
self.lib,
path_cstr.as_ptr(),
face_index,
&mut face as *mut _,
)
};
return Ok(Face {
face: ft_result(res, face).with_context(|| {
format!(
"FT_New_Face for {} index {}",
path.as_ref().display(),
face_index
)
})?,
_bytes: vec![],
size: None,
});
}
}
let path = path.as_ref();
// We open the file for ourselves and treat it as a memory based
// face because freetype doesn't use O_CLOEXEC and keeps the fd
// floating around for a long time!
let data = std::fs::read(path)?;
log::trace!(
"Loading {} ({} bytes) for freetype!",