Fix Text2d performance regression (#16991)

# Objective

Probably fixes #16972

## Solution

With 100k text2d, tracy was showing most time being spent in
`extract_components<bevy_sprite::SpriteSource>`.


![image](https://github.com/user-attachments/assets/e82d5d4e-bb39-4d7e-ab7f-47a5466cb74f)

Browsing Bevy's code, this `SpriteSource` component is seemingly not
even used in the render world. So I just ~~deleted the code that was
extracting it~~ it.

## Testing

`cargo run --example text2d` still seems to work.

The example from [my
comment](https://github.com/bevyengine/bevy/issues/16972#issuecomment-2562680876)
in the linked issue shows a ~50x speedup.
This commit is contained in:
Rob Parrett 2024-12-29 15:14:33 -08:00 committed by GitHub
parent 1614b213f1
commit 150eec7535
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 10 additions and 38 deletions

View File

@ -36,7 +36,6 @@ pub mod prelude {
};
}
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
pub use bundle::*;
pub use dynamic_texture_atlas_builder::*;
pub use mesh2d::*;
@ -51,15 +50,14 @@ pub use texture_slice::*;
use bevy_app::prelude::*;
use bevy_asset::{load_internal_asset, AssetApp, Assets, Handle};
use bevy_core_pipeline::core_2d::Transparent2d;
use bevy_ecs::{prelude::*, query::QueryItem};
use bevy_ecs::prelude::*;
use bevy_image::Image;
use bevy_render::{
extract_component::{ExtractComponent, ExtractComponentPlugin},
mesh::{Mesh, Mesh2d, MeshAabb},
primitives::Aabb,
render_phase::AddRenderCommand,
render_resource::{Shader, SpecializedRenderPipelines},
view::{self, NoFrustumCulling, VisibilityClass, VisibilitySystems},
view::{NoFrustumCulling, VisibilitySystems},
ExtractSchedule, Render, RenderApp, RenderSet,
};
@ -90,16 +88,6 @@ pub enum SpriteSystem {
ComputeSlices,
}
/// A component that marks entities that aren't themselves sprites but become
/// sprites during rendering.
///
/// Right now, this is used for `Text`.
#[derive(Component, Reflect, Clone, Copy, Debug, Default)]
#[reflect(Component, Default, Debug)]
#[require(VisibilityClass)]
#[component(on_add = view::add_visibility_class::<Sprite>)]
pub struct SpriteSource;
impl Plugin for SpritePlugin {
fn build(&self, app: &mut App) {
load_internal_asset!(
@ -122,12 +110,7 @@ impl Plugin for SpritePlugin {
.register_type::<Anchor>()
.register_type::<TextureAtlas>()
.register_type::<Mesh2d>()
.register_type::<SpriteSource>()
.add_plugins((
Mesh2dRenderPlugin,
ColorMaterialPlugin,
ExtractComponentPlugin::<SpriteSource>::default(),
))
.add_plugins((Mesh2dRenderPlugin, ColorMaterialPlugin))
.add_systems(
PostUpdate,
(
@ -229,18 +212,6 @@ pub fn calculate_bounds_2d(
}
}
impl ExtractComponent for SpriteSource {
type QueryData = ();
type QueryFilter = With<SpriteSource>;
type Out = SpriteSource;
fn extract_component(_: QueryItem<'_, Self::QueryData>) -> Option<Self::Out> {
Some(SpriteSource)
}
}
#[cfg(test)]
mod test {

View File

@ -7,6 +7,7 @@ use crate::{
use bevy_asset::Assets;
use bevy_color::LinearRgba;
use bevy_derive::{Deref, DerefMut};
use bevy_ecs::entity::EntityHashSet;
use bevy_ecs::{
change_detection::{DetectChanges, Ref},
component::{require, Component},
@ -19,16 +20,15 @@ use bevy_image::Image;
use bevy_math::Vec2;
use bevy_reflect::{prelude::ReflectDefault, Reflect};
use bevy_render::sync_world::TemporaryRenderEntity;
use bevy_render::view::Visibility;
use bevy_render::view::{self, Visibility, VisibilityClass};
use bevy_render::{
primitives::Aabb,
view::{NoFrustumCulling, ViewVisibility},
Extract,
};
use bevy_sprite::{Anchor, ExtractedSprite, ExtractedSprites, SpriteSource, TextureAtlasLayout};
use bevy_sprite::{Anchor, ExtractedSprite, ExtractedSprites, Sprite, TextureAtlasLayout};
use bevy_transform::components::Transform;
use bevy_transform::prelude::GlobalTransform;
use bevy_utils::HashSet;
use bevy_window::{PrimaryWindow, Window};
/// [`Text2dBundle`] was removed in favor of required components.
@ -94,10 +94,11 @@ pub struct Text2dBundle {}
TextColor,
TextBounds,
Anchor,
SpriteSource,
Visibility,
VisibilityClass,
Transform
)]
#[component(on_add = view::add_visibility_class::<Sprite>)]
pub struct Text2d(pub String);
impl Text2d {
@ -236,7 +237,7 @@ pub fn extract_text2d_sprite(
pub fn update_text2d_layout(
mut last_scale_factor: Local<f32>,
// Text items which should be reprocessed again, generally when the font hasn't loaded yet.
mut queue: Local<HashSet<Entity>>,
mut queue: Local<EntityHashSet>,
mut textures: ResMut<Assets<Image>>,
fonts: Res<Assets<Font>>,
windows: Query<&Window, With<PrimaryWindow>>,
@ -269,7 +270,7 @@ pub fn update_text2d_layout(
if factor_changed
|| computed.needs_rerender()
|| bounds.is_changed()
|| queue.remove(&entity)
|| (!queue.is_empty() && queue.remove(&entity))
{
let text_bounds = TextBounds {
width: if block.linebreak == LineBreak::NoWrap {