raster_bench/
raster_bench.rs1use std::time::Instant;
8
9use valo_text::{FaceSet, FontId, Rasterizer};
10
11const SIZES: [f32; 6] = [16.0, 32.0, 72.0, 162.0, 256.0, 324.0];
12const LATIN: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn";
13const CJK: &str =
14 "春夏秋冬风花雪月山水天地日出而作息万物生长设计海报标题正文字体渲染引擎性能测试基准数据";
15
16fn main() {
17 let dir = concat!(env!("CARGO_MANIFEST_DIR"), "/../../assets/fonts");
18 let cjk_file = std::env::var("VALO_CJK_FONT").unwrap_or_default();
21 let mut fonts = FaceSet::default();
22 let latin = fonts
23 .register(
24 "Latin",
25 std::fs::read(format!("{dir}/fira_sans.ttf")).unwrap(),
26 )
27 .unwrap();
28 let cjk = std::fs::read(cjk_file)
29 .ok()
30 .and_then(|bytes| fonts.register("CJK", bytes));
31
32 let mut sets = vec![("latin", latin, glyphs(&fonts, latin, LATIN))];
33 if let Some(id) = cjk {
34 sets.push(("cjk", id, glyphs(&fonts, id, CJK)));
35 }
36
37 println!(
38 "{:>6} {:>6} {:>12} {:>12} (µs/glyph, n={})",
39 "set",
40 "px",
41 "alpha",
42 "sdf",
43 LATIN.len()
44 );
45 let mut raster = Rasterizer::new();
46 for (label, font, ids) in &sets {
47 for px in SIZES {
48 let alpha = time_per_glyph(ids, |g| {
49 raster.alpha(fonts.get(*font), g, px, 0.0);
50 });
51 let mut raster2 = Rasterizer::new();
52 let sdf = time_per_glyph(ids, |g| {
53 raster2.sdf(fonts.get(*font), g, px);
54 });
55 println!("{label:>6} {px:>6.0} {alpha:>10.1}µs {sdf:>10.1}µs");
56 }
57 }
58}
59
60fn glyphs(fonts: &FaceSet, id: FontId, text: &str) -> Vec<u32> {
61 let font = fonts.get(id);
62 text.chars().filter_map(|ch| font.glyph_for(ch)).collect()
63}
64
65fn time_per_glyph(ids: &[u32], mut raster: impl FnMut(u32)) -> f64 {
66 let t0 = Instant::now();
67 for &g in ids {
68 raster(g);
69 }
70 t0.elapsed().as_secs_f64() * 1e6 / ids.len() as f64
71}