bevy
bevy copied to clipboard
Skip the UV calculations for untextured UI nodes
Objective
The UV calculations in prepare_uinodes can be skipped for nodes without images.
Solution
Skip the UV calculations if the image handle id is equal to DEFAULT_IMAGE_HANDLE.id().
Could you check perfs with example many_buttons? They are very slightly worse (by ~0.15ms) on my laptop with this PR. This example has no images at all, so it would be supposedly worse with many textures nodes.
many_buttons draws lots of text, and each glyph is an image. Text is a special case and I've got a separate idea on how to improve performance there, once I've finished with the text wrapping PR.
Try comparing with this example instead:
use bevy::{
diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
prelude::*,
window::{PresentMode, WindowPlugin},
};
fn main() {
App::new()
.add_plugins(DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window {
present_mode: PresentMode::Immediate,
..default()
}),
..default()
}))
.add_plugin(FrameTimeDiagnosticsPlugin::default())
.add_plugin(LogDiagnosticsPlugin::default())
.add_startup_system(setup)
.run();
}
fn setup(mut commands: Commands) {
commands.spawn(Camera2dBundle::default());
let parent = commands.spawn(NodeBundle {
style: Style {
flex_basis: Val::Percent(100.),
flex_wrap: FlexWrap::Wrap,
align_content: AlignContent::FlexStart,
align_items: AlignItems::FlexStart,
justify_content: JustifyContent::FlexStart,
..Default::default()
},
background_color: BackgroundColor(Color::BLACK),
..Default::default()
})
.id();
for _ in 0..100_000 {
let child = commands.spawn(NodeBundle {
style: Style {
size: Size::all(Val::Px(2.0)),
align_self: AlignSelf::FlexStart,
..Default::default()
},
background_color: BackgroundColor(Color::YELLOW),
..Default::default()
})
.id();
commands.entity(parent).add_child(child);
}
}
Right, forgot that this example has text as it's too small to read 😄
Removing the text, this PR improves perfs by a similar amount 👍
Adding to 0.10.1 as this is useful to anyone using UI and is non-breaking.
Some benches:
cargo run --example many_buttons --features trace_tracey --profile stress-test
A slight performance regression but many_buttons with text is about the worst possible case here.
cargo run --example many_buttons --no-default-features --features bevy_ui,bevy_sprite,bevy_render,bevy_core_pipeline,bevy_asset,bevy_winit,trace_tracy --profile stress-test
Got the #[cfg(not(feature = "bevy_text"))] many_buttons on a separate branch I'm going to PR in a moment.