Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepare benchmarks + ~1.7x prepare perf improvement #121

Merged
merged 6 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,8 @@ winit = "0.30.3"
wgpu = "23"
resvg = { version = "0.44", default-features = false }
pollster = "0.4.0"
criterion = { version = "0.5", features = ["html_reports"] }

[[bench]]
name = "prepare"
harness = false
121 changes: 121 additions & 0 deletions benches/prepare.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 35 additions & 0 deletions benches/state.rs
Original file line number Diff line number Diff line change
@@ -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 }
}
}
8 changes: 8 additions & 0 deletions samples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Sample Attribution

The sample sources with accompanying attributions and licenses are as follows:

| Sample | Title | Amendments | Source | License |
| -------------- | --------------------------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `./arabic.txt` | Al-Kindi - First Philosophy | None | [Wiki Source](<https://en.wikisource.org/wiki/Moby-Dick_(1851)_US_edition/Chapter_1>) | [Creative Commons Attribution-ShareAlike License](https://creativecommons.org/licenses/by-sa/4.0/) |
| `./latin.txt` | Moby Dick - First Chapter | None | [Wiki Source](https://ar.wikisource.org/wiki/%D8%A7%D9%84%D9%83%D9%86%D8%AF%D9%8A_-_%D8%A7%D9%84%D9%81%D9%84%D8%B3%D9%81%D8%A9_%D8%A7%D9%84%D8%A3%D9%88%D9%84%D9%89) | [Creative Commons Attribution-ShareAlike License](https://creativecommons.org/licenses/by-sa/4.0/) |
Loading