Prepare benchmarks + ~1.7x prepare perf improvement (#121)

* Add prepare benchmarks

* Skip unnecessary peaks

* Cite sample sources
This commit is contained in:
Taj Pereira 2024-11-28 22:36:23 +09:00 committed by GitHub
parent 87f959dfdb
commit 1055c2e534
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 960 additions and 35 deletions

121
benches/prepare.rs Normal file
View file

@ -0,0 +1,121 @@
use cosmic_text::{Attrs, Buffer, Color, Family, FontSystem, Metrics, Shaping, SwashCache};
use criterion::{criterion_group, criterion_main, Criterion};
use glyphon::{
Cache, ColorMode, Resolution, TextArea, TextAtlas, TextBounds, TextRenderer, Viewport, Weight,
};
use wgpu::{MultisampleState, TextureFormat};
mod state;
fn run_bench(ctx: &mut Criterion) {
let mut group = ctx.benchmark_group("Prepare");
group.noise_threshold(0.02);
let state = state::State::new();
// Set up text renderer
let mut font_system = FontSystem::new();
let mut swash_cache = SwashCache::new();
let cache = Cache::new(&state.device);
let mut viewport = Viewport::new(&state.device, &cache);
let mut atlas = TextAtlas::with_color_mode(
&state.device,
&state.queue,
&cache,
TextureFormat::Bgra8Unorm,
ColorMode::Web,
);
let mut text_renderer =
TextRenderer::new(&mut atlas, &state.device, MultisampleState::default(), None);
let attrs = Attrs::new()
.family(Family::SansSerif)
.weight(Weight::NORMAL);
let shaping = Shaping::Advanced;
viewport.update(
&state.queue,
Resolution {
width: 1000,
height: 1000,
},
);
for (test_name, text_areas) in &[
(
"Latin - Single Text Area",
vec![include_str!("../samples/latin.txt")],
),
(
"Arabic - Single Text Area",
vec![include_str!("../samples/arabic.txt")],
),
(
"Latin - Many Text Areas",
include_str!("../samples/latin.txt")
.repeat(100)
.split('\n')
.collect(),
),
(
"Arabic - Many Text Areas",
include_str!("../samples/arabic.txt")
.repeat(20)
.split('\n')
.collect(),
),
] {
let buffers: Vec<glyphon::Buffer> = text_areas
.iter()
.copied()
.map(|s| {
let mut text_buffer = Buffer::new(&mut font_system, Metrics::relative(1.0, 10.0));
text_buffer.set_size(&mut font_system, Some(20.0), None);
text_buffer.set_text(&mut font_system, s, attrs, shaping);
text_buffer.shape_until_scroll(&mut font_system, false);
text_buffer
})
.collect();
group.bench_function(*test_name, |b| {
b.iter(|| {
let text_areas: Vec<TextArea> = buffers
.iter()
.map(|b| TextArea {
buffer: b,
left: 0.0,
top: 0.0,
scale: 1.0,
bounds: TextBounds {
left: 0,
top: 0,
right: 0,
bottom: 1000,
},
default_color: Color::rgb(0, 0, 0),
custom_glyphs: &[],
})
.collect();
criterion::black_box(
text_renderer
.prepare(
&state.device,
&state.queue,
&mut font_system,
&mut atlas,
&viewport,
text_areas,
&mut swash_cache,
)
.unwrap(),
);
atlas.trim();
})
});
}
group.finish();
}
criterion_group!(benches, run_bench);
criterion_main!(benches);

35
benches/state.rs Normal file
View file

@ -0,0 +1,35 @@
use pollster::block_on;
pub struct State {
pub device: wgpu::Device,
pub queue: wgpu::Queue,
}
impl State {
pub fn new() -> Self {
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
backends: wgpu::Backends::all(),
flags: wgpu::InstanceFlags::empty(),
dx12_shader_compiler: wgpu::Dx12Compiler::Fxc,
gles_minor_version: wgpu::Gles3MinorVersion::Automatic,
});
let adapter = block_on(wgpu::util::initialize_adapter_from_env_or_default(
&instance, None,
))
.unwrap();
let (device, queue) = block_on(adapter.request_device(
&wgpu::DeviceDescriptor {
label: Some("Benchmark Device"),
required_features: adapter.features(),
required_limits: adapter.limits(),
memory_hints: wgpu::MemoryHints::Performance,
},
None,
))
.unwrap();
Self { device, queue }
}
}