Skip to content

Commit

Permalink
Reduce the amount of FontDefinitions cloning
Browse files Browse the repository at this point in the history
  • Loading branch information
StarStarJ committed Oct 26, 2024
1 parent 5b846b4 commit e624075
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 29 deletions.
23 changes: 11 additions & 12 deletions crates/egui/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ struct ContextImpl {
/// This is because the `Fonts` depend on `pixels_per_point` for the font atlas
/// as well as kerning, font sizes, etc.
fonts: std::collections::BTreeMap<OrderedFloat<f32>, Fonts>,
font_definitions: FontDefinitions,
font_definitions: Arc<FontDefinitions>,

memory: Memory,
animation_manager: AnimationManager,
Expand Down Expand Up @@ -583,22 +583,21 @@ impl ContextImpl {
}

if !self.memory.add_fonts.is_empty() {
// Recreate all the fonts
self.fonts.clear();
let mut font_definitions = self.font_definitions.as_ref().clone();
let fonts = self.memory.add_fonts.drain(..);
for font in fonts {
self.fonts.clear(); // recreate all the fonts
for family in font.families {
let fam = self
.font_definitions
.families
.entry(family.family)
.or_default();
let fam = font_definitions.families.entry(family.family).or_default();
match family.priority {
FontPriority::Highest => fam.insert(0, font.name.clone()),
FontPriority::Lowest => fam.push(font.name.clone()),
}
}
self.font_definitions.font_data.insert(font.name, font.data);
font_definitions.font_data.insert(font.name, font.data);
}
self.font_definitions = Arc::new(font_definitions);

#[cfg(feature = "log")]
log::trace!("Adding new fonts");
Expand Down Expand Up @@ -1750,7 +1749,7 @@ impl Context {
///
/// The new fonts will become active at the start of the next pass.
/// This will overwrite the existing fonts.
pub fn set_fonts(&self, font_definitions: FontDefinitions) {
pub fn set_fonts(&self, font_definitions: Arc<FontDefinitions>) {
crate::profile_function!();

let pixels_per_point = self.pixels_per_point();
Expand All @@ -1760,7 +1759,7 @@ impl Context {
self.read(|ctx| {
if let Some(current_fonts) = ctx.fonts.get(&pixels_per_point.into()) {
// NOTE: this comparison is expensive since it checks TTF data for equality
if current_fonts.lock().fonts.definitions() == &font_definitions {
if current_fonts.lock().fonts.definitions() == font_definitions.as_ref() {
update_fonts = false; // no need to update
}
}
Expand Down Expand Up @@ -2935,7 +2934,7 @@ impl Context {
}

fn fonts_tweak_ui(&self, ui: &mut Ui) {
let mut font_definitions = self.write(|ctx| ctx.font_definitions.clone());
let mut font_definitions = self.write(|ctx| ctx.font_definitions.as_ref().clone());
let mut changed = false;

for (name, data) in &mut font_definitions.font_data {
Expand All @@ -2947,7 +2946,7 @@ impl Context {
}

if changed {
self.set_fonts(font_definitions);
self.set_fonts(Arc::new(font_definitions));
}
}

Expand Down
4 changes: 2 additions & 2 deletions crates/egui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ pub enum WidgetType {
/// For use in tests; especially doctests.
pub fn __run_test_ctx(mut run_ui: impl FnMut(&Context)) {
let ctx = Context::default();
ctx.set_fonts(FontDefinitions::empty()); // prevent fonts from being loaded (save CPU time)
ctx.set_fonts(std::sync::Arc::new(FontDefinitions::empty())); // prevent fonts from being loaded (save CPU time)
let _ = ctx.run(Default::default(), |ctx| {
run_ui(ctx);
});
Expand All @@ -676,7 +676,7 @@ pub fn __run_test_ctx(mut run_ui: impl FnMut(&Context)) {
/// For use in tests; especially doctests.
pub fn __run_test_ui(add_contents: impl Fn(&mut Ui)) {
let ctx = Context::default();
ctx.set_fonts(FontDefinitions::empty()); // prevent fonts from being loaded (save CPU time)
ctx.set_fonts(std::sync::Arc::new(FontDefinitions::empty())); // prevent fonts from being loaded (save CPU time)
let _ = ctx.run(Default::default(), |ctx| {
crate::CentralPanel::default().show(ctx, |ui| {
add_contents(ui);
Expand Down
2 changes: 1 addition & 1 deletion crates/egui/src/memory/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ pub struct Memory {
// ------------------------------------------
/// new fonts that will be applied at the start of the next frame
#[cfg_attr(feature = "persistence", serde(skip))]
pub(crate) new_font_definitions: Option<epaint::text::FontDefinitions>,
pub(crate) new_font_definitions: Option<std::sync::Arc<epaint::text::FontDefinitions>>,

/// add new font that will be applied at the start of the next frame
#[cfg_attr(feature = "persistence", serde(skip))]
Expand Down
7 changes: 2 additions & 5 deletions crates/egui_demo_lib/benches/benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,8 @@ pub fn criterion_benchmark(c: &mut Criterion) {
let wrap_width = 512.0;
let font_id = egui::FontId::default();
let text_color = egui::Color32::WHITE;
let fonts = egui::epaint::text::Fonts::new(
pixels_per_point,
max_texture_side,
egui::FontDefinitions::default(),
);
let fonts =
egui::epaint::text::Fonts::new(pixels_per_point, max_texture_side, Default::default());
{
let mut locked_fonts = fonts.lock();
c.bench_function("text_layout_uncached", |b| {
Expand Down
6 changes: 3 additions & 3 deletions crates/epaint/src/text/fonts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ impl Fonts {
pub fn new(
pixels_per_point: f32,
max_texture_side: usize,
definitions: FontDefinitions,
definitions: Arc<FontDefinitions>,
) -> Self {
let fonts_and_cache = FontsAndCache {
fonts: FontsImpl::new(pixels_per_point, max_texture_side, definitions),
Expand Down Expand Up @@ -614,7 +614,7 @@ impl FontsAndCache {
pub struct FontsImpl {
pixels_per_point: f32,
max_texture_side: usize,
definitions: FontDefinitions,
definitions: Arc<FontDefinitions>,
atlas: Arc<Mutex<TextureAtlas>>,
font_impl_cache: FontImplCache,
sized_family: ahash::HashMap<(OrderedFloat<f32>, FontFamily), Font>,
Expand All @@ -626,7 +626,7 @@ impl FontsImpl {
pub fn new(
pixels_per_point: f32,
max_texture_side: usize,
definitions: FontDefinitions,
definitions: Arc<FontDefinitions>,
) -> Self {
assert!(
0.0 < pixels_per_point && pixels_per_point < 100.0,
Expand Down
10 changes: 5 additions & 5 deletions crates/epaint/src/text/text_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1042,7 +1042,7 @@ mod tests {

#[test]
fn test_zero_max_width() {
let mut fonts = FontsImpl::new(1.0, 1024, FontDefinitions::default());
let mut fonts = FontsImpl::new(1.0, 1024, Default::default());
let mut layout_job = LayoutJob::single_section("W".into(), TextFormat::default());
layout_job.wrap.max_width = 0.0;
let galley = layout(&mut fonts, layout_job.into());
Expand All @@ -1053,7 +1053,7 @@ mod tests {
fn test_truncate_with_newline() {
// No matter where we wrap, we should be appending the newline character.

let mut fonts = FontsImpl::new(1.0, 1024, FontDefinitions::default());
let mut fonts = FontsImpl::new(1.0, 1024, Default::default());
let text_format = TextFormat {
font_id: FontId::monospace(12.0),
..Default::default()
Expand Down Expand Up @@ -1098,7 +1098,7 @@ mod tests {

#[test]
fn test_cjk() {
let mut fonts = FontsImpl::new(1.0, 1024, FontDefinitions::default());
let mut fonts = FontsImpl::new(1.0, 1024, Default::default());
let mut layout_job = LayoutJob::single_section(
"日本語とEnglishの混在した文章".into(),
TextFormat::default(),
Expand All @@ -1113,7 +1113,7 @@ mod tests {

#[test]
fn test_pre_cjk() {
let mut fonts = FontsImpl::new(1.0, 1024, FontDefinitions::default());
let mut fonts = FontsImpl::new(1.0, 1024, Default::default());
let mut layout_job = LayoutJob::single_section(
"日本語とEnglishの混在した文章".into(),
TextFormat::default(),
Expand All @@ -1128,7 +1128,7 @@ mod tests {

#[test]
fn test_truncate_width() {
let mut fonts = FontsImpl::new(1.0, 1024, FontDefinitions::default());
let mut fonts = FontsImpl::new(1.0, 1024, Default::default());
let mut layout_job =
LayoutJob::single_section("# DNA\nMore text".into(), TextFormat::default());
layout_job.wrap.max_width = f32::INFINITY;
Expand Down
3 changes: 2 additions & 1 deletion examples/custom_font/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use eframe::{
egui,
epaint::text::{FontInsert, InsertFontFamily},
};
use std::sync::Arc;

fn main() -> eframe::Result {
env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`).
Expand Down Expand Up @@ -68,7 +69,7 @@ fn replace_fonts(ctx: &egui::Context) {
.push("my_font".to_owned());

// Tell egui to use these fonts:
ctx.set_fonts(fonts);
ctx.set_fonts(Arc::new(fonts));
}

struct MyApp {
Expand Down

0 comments on commit e624075

Please sign in to comment.