Put FontsImpl and GalleyCache behind the same Mutex
This commit is contained in:
parent
93d5e222db
commit
67c58ace27
4 changed files with 48 additions and 44 deletions
|
@ -93,7 +93,7 @@ impl ContextImpl {
|
|||
new_font_definitions.unwrap_or_else(|| {
|
||||
self.fonts
|
||||
.as_ref()
|
||||
.map(|font| font.lock().definitions().clone())
|
||||
.map(|font| font.lock().fonts.definitions().clone())
|
||||
.unwrap_or_default()
|
||||
}),
|
||||
));
|
||||
|
@ -521,7 +521,7 @@ impl Context {
|
|||
pub fn set_fonts(&self, font_definitions: FontDefinitions) {
|
||||
if let Some(current_fonts) = &*self.fonts_mut() {
|
||||
// NOTE: this comparison is expensive since it checks TTF data for equality
|
||||
if current_fonts.lock().definitions() == &font_definitions {
|
||||
if current_fonts.lock().fonts.definitions() == &font_definitions {
|
||||
return; // no change - save us from reloading font textures
|
||||
}
|
||||
}
|
||||
|
@ -708,7 +708,7 @@ impl Context {
|
|||
.memory
|
||||
.end_frame(&ctx_impl.input, &ctx_impl.frame_state.used_ids);
|
||||
|
||||
let font_image_delta = ctx_impl.fonts.as_ref().unwrap().lock().font_image_delta();
|
||||
let font_image_delta = ctx_impl.fonts.as_ref().unwrap().font_image_delta();
|
||||
if let Some(font_image_delta) = font_image_delta {
|
||||
ctx_impl
|
||||
.tex_manager
|
||||
|
@ -754,7 +754,7 @@ impl Context {
|
|||
let clipped_meshes = tessellator::tessellate_shapes(
|
||||
shapes,
|
||||
tessellation_options,
|
||||
self.fonts().lock().font_image_size(),
|
||||
self.fonts().font_image_size(),
|
||||
);
|
||||
self.write().paint_stats = paint_stats.with_clipped_meshes(&clipped_meshes);
|
||||
clipped_meshes
|
||||
|
@ -956,9 +956,9 @@ impl Context {
|
|||
CollapsingHeader::new("🔠 Fonts")
|
||||
.default_open(false)
|
||||
.show(ui, |ui| {
|
||||
let mut font_definitions = self.fonts().lock().definitions().clone();
|
||||
let mut font_definitions = self.fonts().lock().fonts.definitions().clone();
|
||||
font_definitions.ui(ui);
|
||||
let font_image_size = self.fonts().lock().font_image_size();
|
||||
let font_image_size = self.fonts().font_image_size();
|
||||
crate::introspection::font_texture_ui(ui, font_image_size);
|
||||
self.set_fonts(font_definitions);
|
||||
});
|
||||
|
|
|
@ -92,7 +92,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
|||
let fonts =
|
||||
egui::epaint::text::Fonts::new(pixels_per_point, egui::FontDefinitions::default());
|
||||
{
|
||||
let mut fonts_impl = fonts.lock();
|
||||
let mut locked_fonts = fonts.lock();
|
||||
c.bench_function("text_layout_uncached", |b| {
|
||||
b.iter(|| {
|
||||
use egui::epaint::text::{layout, LayoutJob};
|
||||
|
@ -103,7 +103,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
|||
color,
|
||||
wrap_width,
|
||||
);
|
||||
layout(&mut fonts_impl, job.into())
|
||||
layout(&mut locked_fonts.fonts, job.into())
|
||||
})
|
||||
});
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
|||
let mut tessellator = egui::epaint::Tessellator::from_options(Default::default());
|
||||
let mut mesh = egui::epaint::Mesh::default();
|
||||
let text_shape = TextShape::new(egui::Pos2::ZERO, galley);
|
||||
let font_image_size = fonts.lock().font_image_size();
|
||||
let font_image_size = fonts.font_image_size();
|
||||
c.bench_function("tessellate_text", |b| {
|
||||
b.iter(|| {
|
||||
tessellator.tessellate_text(font_image_size, text_shape.clone(), &mut mesh);
|
||||
|
|
|
@ -73,6 +73,7 @@ impl super::View for FontBook {
|
|||
let named_chars = self.named_chars.entry(text_style).or_insert_with(|| {
|
||||
ui.fonts()
|
||||
.lock()
|
||||
.fonts
|
||||
.font_mut(text_style)
|
||||
.characters()
|
||||
.iter()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::collections::BTreeMap;
|
||||
|
||||
use crate::{
|
||||
mutex::{Arc, Mutex},
|
||||
mutex::{Arc, Mutex, MutexGuard},
|
||||
text::{
|
||||
font::{Font, FontImpl},
|
||||
Galley, LayoutJob,
|
||||
|
@ -232,45 +232,52 @@ impl Default for FontDefinitions {
|
|||
/// Required in order to paint text.
|
||||
/// Create one and reuse. Cheap to clone.
|
||||
///
|
||||
/// Wrapper for `Arc<Mutex<FontsImpl>>`.
|
||||
pub struct Fonts {
|
||||
fonts: Arc<Mutex<FontsImpl>>,
|
||||
galley_cache: Arc<Mutex<GalleyCache>>,
|
||||
}
|
||||
/// Wrapper for `Arc<Mutex<FontsAndCache>>`.
|
||||
pub struct Fonts(Arc<Mutex<FontsAndCache>>);
|
||||
|
||||
impl Fonts {
|
||||
/// Create a new [`Fonts`] for text layout.
|
||||
/// This call is expensive, so only create one [`Fonts`] and then reuse it.
|
||||
pub fn new(pixels_per_point: f32, definitions: FontDefinitions) -> Self {
|
||||
let fonts = Arc::new(Mutex::new(FontsImpl::new(pixels_per_point, definitions)));
|
||||
Self {
|
||||
fonts,
|
||||
let fonts_and_cache = FontsAndCache {
|
||||
fonts: FontsImpl::new(pixels_per_point, definitions),
|
||||
galley_cache: Default::default(),
|
||||
}
|
||||
};
|
||||
Self(Arc::new(Mutex::new(fonts_and_cache)))
|
||||
}
|
||||
|
||||
/// Access the underlying [`FontsImpl`].
|
||||
/// Access the underlying [`FontsAndCache`].
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
pub fn lock(&self) -> crate::mutex::MutexGuard<'_, FontsImpl> {
|
||||
self.fonts.lock()
|
||||
pub fn lock(&self) -> MutexGuard<'_, FontsAndCache> {
|
||||
self.0.lock()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn pixels_per_point(&self) -> f32 {
|
||||
self.lock().pixels_per_point
|
||||
self.lock().fonts.pixels_per_point
|
||||
}
|
||||
|
||||
/// Call each frame to get the change to the font texture since last call.
|
||||
pub fn font_image_delta(&self) -> Option<crate::ImageDelta> {
|
||||
self.lock().fonts.atlas.lock().take_delta()
|
||||
}
|
||||
|
||||
/// Current size of the font image
|
||||
pub fn font_image_size(&self) -> [usize; 2] {
|
||||
self.lock().fonts.atlas.lock().size()
|
||||
}
|
||||
|
||||
/// Width of this character in points.
|
||||
#[inline]
|
||||
pub fn glyph_width(&self, text_style: TextStyle, c: char) -> f32 {
|
||||
self.lock().glyph_width(text_style, c)
|
||||
self.lock().fonts.glyph_width(text_style, c)
|
||||
}
|
||||
|
||||
/// Height of one row of text. In points
|
||||
#[inline]
|
||||
pub fn row_height(&self, text_style: TextStyle) -> f32 {
|
||||
self.lock().row_height(text_style)
|
||||
self.lock().fonts.row_height(text_style)
|
||||
}
|
||||
|
||||
/// Layout some text.
|
||||
|
@ -281,16 +288,16 @@ impl Fonts {
|
|||
/// The implementation uses memoization so repeated calls are cheap.
|
||||
/// #[inline]
|
||||
pub fn layout_job(&self, job: LayoutJob) -> Arc<Galley> {
|
||||
self.galley_cache.lock().layout(&mut self.fonts.lock(), job)
|
||||
self.lock().layout_job(job)
|
||||
}
|
||||
|
||||
pub fn num_galleys_in_cache(&self) -> usize {
|
||||
self.galley_cache.lock().num_galleys_in_cache()
|
||||
self.lock().galley_cache.num_galleys_in_cache()
|
||||
}
|
||||
|
||||
/// Must be called once per frame to clear the [`Galley`] cache.
|
||||
pub fn end_frame(&self) {
|
||||
self.galley_cache.lock().end_frame();
|
||||
self.lock().galley_cache.end_frame();
|
||||
}
|
||||
|
||||
/// Will wrap text at the given width and line break at `\n`.
|
||||
|
@ -340,10 +347,16 @@ impl Fonts {
|
|||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// pub struct CachedFonts {
|
||||
// fonts: Arc<Mutex<FontsImpl>>,
|
||||
// galley_cache: Arc<Mutex<GalleyCache>>,
|
||||
// }
|
||||
pub struct FontsAndCache {
|
||||
pub fonts: FontsImpl,
|
||||
galley_cache: GalleyCache,
|
||||
}
|
||||
|
||||
impl FontsAndCache {
|
||||
fn layout_job(&mut self, job: LayoutJob) -> Arc<Galley> {
|
||||
self.galley_cache.layout(&mut self.fonts, job)
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
@ -421,23 +434,13 @@ impl FontsImpl {
|
|||
self.fonts.get_mut(&text_style).unwrap()
|
||||
}
|
||||
|
||||
/// Call each frame to get the change to the font texture since last call.
|
||||
pub fn font_image_delta(&self) -> Option<crate::ImageDelta> {
|
||||
self.atlas.lock().take_delta()
|
||||
}
|
||||
|
||||
/// Current size of the font image
|
||||
pub fn font_image_size(&self) -> [usize; 2] {
|
||||
self.atlas.lock().size()
|
||||
}
|
||||
|
||||
/// Width of this character in points.
|
||||
pub fn glyph_width(&mut self, text_style: TextStyle, c: char) -> f32 {
|
||||
fn glyph_width(&mut self, text_style: TextStyle, c: char) -> f32 {
|
||||
self.font_mut(text_style).glyph_width(c)
|
||||
}
|
||||
|
||||
/// Height of one row of text. In points
|
||||
pub fn row_height(&self, text_style: TextStyle) -> f32 {
|
||||
fn row_height(&self, text_style: TextStyle) -> f32 {
|
||||
self.fonts[&text_style].row_height()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue