many_glyphs/
many_glyphs.rs

1//! Simple text rendering benchmark.
2//!
3//! Creates a text block with a single span containing `100_000` glyphs,
4//! and renders it with the UI in a white color and with Text2d in a red color.
5//!
6//! To recompute all text each frame run
7//! `cargo run --example many_glyphs --release recompute-text`
8use bevy::{
9    color::palettes::basic::RED,
10    diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
11    prelude::*,
12    text::{LineBreak, TextBounds},
13    window::{PresentMode, WindowResolution},
14    winit::{UpdateMode, WinitSettings},
15};
16
17fn main() {
18    let mut app = App::new();
19    app.add_plugins((
20        DefaultPlugins.set(WindowPlugin {
21            primary_window: Some(Window {
22                present_mode: PresentMode::AutoNoVsync,
23                resolution: WindowResolution::new(1920.0, 1080.0).with_scale_factor_override(1.0),
24                ..default()
25            }),
26            ..default()
27        }),
28        FrameTimeDiagnosticsPlugin,
29        LogDiagnosticsPlugin::default(),
30    ))
31    .insert_resource(WinitSettings {
32        focused_mode: UpdateMode::Continuous,
33        unfocused_mode: UpdateMode::Continuous,
34    })
35    .add_systems(Startup, setup);
36
37    if std::env::args().any(|arg| arg == "recompute-text") {
38        app.add_systems(Update, force_text_recomputation);
39    }
40
41    app.run();
42}
43
44fn setup(mut commands: Commands) {
45    warn!(include_str!("warning_string.txt"));
46
47    commands.spawn(Camera2d);
48    let text_string = "0123456789".repeat(10_000);
49    let text_font = TextFont {
50        font_size: 4.,
51        ..Default::default()
52    };
53    let text_block = TextLayout {
54        justify: JustifyText::Left,
55        linebreak: LineBreak::AnyCharacter,
56    };
57
58    commands
59        .spawn(Node {
60            width: Val::Percent(100.),
61            align_items: AlignItems::Center,
62            justify_content: JustifyContent::Center,
63            ..default()
64        })
65        .with_children(|commands| {
66            commands
67                .spawn(Node {
68                    width: Val::Px(1000.),
69                    ..Default::default()
70                })
71                .with_child((Text(text_string.clone()), text_font.clone(), text_block));
72        });
73
74    commands.spawn((
75        Text2d::new(text_string),
76        TextColor(RED.into()),
77        bevy::sprite::Anchor::Center,
78        TextBounds::new_horizontal(1000.),
79        text_block,
80    ));
81}
82
83fn force_text_recomputation(mut text_query: Query<&mut TextLayout>) {
84    for mut block in &mut text_query {
85        block.set_changed();
86    }
87}