mirror of
https://github.com/slint-ui/slint.git
synced 2025-11-03 05:12:55 +00:00
Speed up SDF generation
Using Rayon shaves off ~10% off of gallery.slint on my M3.
This commit is contained in:
parent
d8ab4e4600
commit
0ebcbbecbe
4 changed files with 35 additions and 32 deletions
|
|
@ -159,7 +159,7 @@ ttf-parser = { version = "0.21" }
|
||||||
# web-sys needs to be >= 0.3.72 for set_fill_style_str
|
# web-sys needs to be >= 0.3.72 for set_fill_style_str
|
||||||
web-sys = { version = "0.3.72", default-features = false }
|
web-sys = { version = "0.3.72", default-features = false }
|
||||||
smol_str = { version = "0.3.1" }
|
smol_str = { version = "0.3.1" }
|
||||||
|
rayon = { version = "1.10.0", default-features = false }
|
||||||
raw-window-handle-06 = { package = "raw-window-handle", version = "0.6", features = ["alloc"] }
|
raw-window-handle-06 = { package = "raw-window-handle", version = "0.6", features = ["alloc"] }
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ display-diagnostics = ["codemap", "codemap-diagnostic"]
|
||||||
# Enabled the support to render images and font in the binary
|
# Enabled the support to render images and font in the binary
|
||||||
software-renderer = ["image", "dep:resvg", "fontdue", "i-slint-common/shared-fontdb"]
|
software-renderer = ["image", "dep:resvg", "fontdue", "i-slint-common/shared-fontdb"]
|
||||||
|
|
||||||
embed-glyphs-as-sdf = ["dep:fdsm", "dep:ttf-parser-fdsm", "dep:nalgebra", "dep:image-fdsm"]
|
embed-glyphs-as-sdf = ["dep:fdsm", "dep:ttf-parser-fdsm", "dep:nalgebra", "dep:image-fdsm", "dep:rayon"]
|
||||||
|
|
||||||
default = []
|
default = []
|
||||||
|
|
||||||
|
|
@ -64,10 +64,11 @@ fdsm = { version = "0.6.0", optional = true, features = ["ttf-parser"]}
|
||||||
ttf-parser-fdsm = { package = "ttf-parser", version = "0.24.1", optional = true }
|
ttf-parser-fdsm = { package = "ttf-parser", version = "0.24.1", optional = true }
|
||||||
image-fdsm = { package = "image", version = "0.25", optional = true, default-features = false }
|
image-fdsm = { package = "image", version = "0.25", optional = true, default-features = false }
|
||||||
nalgebra = { version = "0.33.0", optional = true }
|
nalgebra = { version = "0.33.0", optional = true }
|
||||||
|
rayon = { workspace = true, optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
i-slint-parser-test-macro = { path = "./parser-test-macro" }
|
i-slint-parser-test-macro = { path = "./parser-test-macro" }
|
||||||
|
|
||||||
regex = "1.3.7"
|
regex = "1.3.7"
|
||||||
spin_on = { workspace = true }
|
spin_on = { workspace = true }
|
||||||
rayon = "1.5.3"
|
rayon = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ pub type FontCache = Rc<
|
||||||
RefCell<
|
RefCell<
|
||||||
std::collections::HashMap<
|
std::collections::HashMap<
|
||||||
i_slint_common::sharedfontdb::fontdb::ID,
|
i_slint_common::sharedfontdb::fontdb::ID,
|
||||||
fontdue::FontResult<(Rc<fontdue::Font>, Arc<dyn AsRef<[u8]> + Send + Sync>, u32)>,
|
fontdue::FontResult<(Arc<fontdue::Font>, Arc<dyn AsRef<[u8]> + Send + Sync>, u32)>,
|
||||||
>,
|
>,
|
||||||
>,
|
>,
|
||||||
>;
|
>;
|
||||||
|
|
@ -227,7 +227,7 @@ impl CompilerConfiguration {
|
||||||
fn load_font_by_id(
|
fn load_font_by_id(
|
||||||
&self,
|
&self,
|
||||||
face_id: i_slint_common::sharedfontdb::fontdb::ID,
|
face_id: i_slint_common::sharedfontdb::fontdb::ID,
|
||||||
) -> fontdue::FontResult<(Rc<fontdue::Font>, Arc<dyn AsRef<[u8]> + Send + Sync>, u32)> {
|
) -> fontdue::FontResult<(Arc<fontdue::Font>, Arc<dyn AsRef<[u8]> + Send + Sync>, u32)> {
|
||||||
self.font_cache
|
self.font_cache
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.entry(face_id)
|
.entry(face_id)
|
||||||
|
|
@ -246,7 +246,7 @@ impl CompilerConfiguration {
|
||||||
)
|
)
|
||||||
.map(|fontdue_font| {
|
.map(|fontdue_font| {
|
||||||
(
|
(
|
||||||
Rc::new(fontdue_font),
|
Arc::new(fontdue_font),
|
||||||
Arc::new(font_data.to_vec())
|
Arc::new(font_data.to_vec())
|
||||||
as Arc<dyn AsRef<[u8]> + Send + Sync>,
|
as Arc<dyn AsRef<[u8]> + Send + Sync>,
|
||||||
face_index,
|
face_index,
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ use i_slint_common::sharedfontdb::{self, fontdb};
|
||||||
struct Font {
|
struct Font {
|
||||||
id: fontdb::ID,
|
id: fontdb::ID,
|
||||||
#[deref]
|
#[deref]
|
||||||
fontdue_font: Rc<fontdue::Font>,
|
fontdue_font: Arc<fontdue::Font>,
|
||||||
face_data: Arc<dyn AsRef<[u8]> + Send + Sync>,
|
face_data: Arc<dyn AsRef<[u8]> + Send + Sync>,
|
||||||
face_index: u32,
|
face_index: u32,
|
||||||
}
|
}
|
||||||
|
|
@ -442,6 +442,8 @@ fn embed_sdf_glyphs(
|
||||||
font: &Font,
|
font: &Font,
|
||||||
fallback_fonts: &[Font],
|
fallback_fonts: &[Font],
|
||||||
) -> Vec<BitmapGlyphs> {
|
) -> Vec<BitmapGlyphs> {
|
||||||
|
use rayon::prelude::*;
|
||||||
|
|
||||||
const RANGE: f64 = 6.;
|
const RANGE: f64 = 6.;
|
||||||
|
|
||||||
let Some(max_size) = pixel_sizes.iter().max() else {
|
let Some(max_size) = pixel_sizes.iter().max() else {
|
||||||
|
|
@ -450,31 +452,31 @@ fn embed_sdf_glyphs(
|
||||||
let min_size = pixel_sizes.iter().min().expect("we have a 'max' so the vector is not empty");
|
let min_size = pixel_sizes.iter().min().expect("we have a 'max' so the vector is not empty");
|
||||||
let target_pixel_size = (max_size * 2 / 3).max(12).min(RANGE as i16 * min_size);
|
let target_pixel_size = (max_size * 2 / 3).max(12).min(RANGE as i16 * min_size);
|
||||||
|
|
||||||
let mut glyph_data = Vec::new();
|
let glyph_data = character_map
|
||||||
|
.par_iter()
|
||||||
glyph_data.resize(character_map.len(), Default::default());
|
.map(|CharacterMapEntry { code_point, .. }| {
|
||||||
|
core::iter::once(font)
|
||||||
for CharacterMapEntry { code_point, glyph_index } in character_map {
|
.chain(fallback_fonts.iter())
|
||||||
let glyph = core::iter::once(font)
|
.find_map(|font| {
|
||||||
.chain(fallback_fonts.iter())
|
(font.lookup_glyph_index(*code_point) != 0).then(|| {
|
||||||
.find_map(|font| {
|
generate_sdf_for_glyph(font, *code_point, target_pixel_size, RANGE)
|
||||||
(font.lookup_glyph_index(*code_point) != 0)
|
})
|
||||||
.then(|| generate_sdf_for_glyph(font, *code_point, target_pixel_size, RANGE))
|
})
|
||||||
})
|
.unwrap_or_else(|| {
|
||||||
.unwrap_or_else(|| generate_sdf_for_glyph(font, *code_point, target_pixel_size, RANGE))
|
generate_sdf_for_glyph(font, *code_point, target_pixel_size, RANGE)
|
||||||
.map(|(metrics, bitmap)| BitmapGlyph {
|
})
|
||||||
x: i16::try_from(metrics.xmin).expect("large glyph x coordinate"),
|
.map(|(metrics, bitmap)| BitmapGlyph {
|
||||||
y: i16::try_from(metrics.ymin).expect("large glyph y coordinate"),
|
x: i16::try_from(metrics.xmin).expect("large glyph x coordinate"),
|
||||||
width: i16::try_from(metrics.width).expect("large width"),
|
y: i16::try_from(metrics.ymin).expect("large glyph y coordinate"),
|
||||||
height: i16::try_from(metrics.height).expect("large height"),
|
width: i16::try_from(metrics.width).expect("large width"),
|
||||||
x_advance: i16::try_from(metrics.advance_width as i64)
|
height: i16::try_from(metrics.height).expect("large height"),
|
||||||
.expect("large advance width"),
|
x_advance: i16::try_from(metrics.advance_width as i64)
|
||||||
data: bitmap,
|
.expect("large advance width"),
|
||||||
})
|
data: bitmap,
|
||||||
.unwrap_or_default();
|
})
|
||||||
|
.unwrap_or_default()
|
||||||
glyph_data[*glyph_index as usize] = glyph;
|
})
|
||||||
}
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
vec![BitmapGlyphs { pixel_size: target_pixel_size, glyph_data }]
|
vec![BitmapGlyphs { pixel_size: target_pixel_size, glyph_data }]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue