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>`.  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:
parent
1614b213f1
commit
150eec7535
@ -36,7 +36,6 @@ pub mod prelude {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
|
|
||||||
pub use bundle::*;
|
pub use bundle::*;
|
||||||
pub use dynamic_texture_atlas_builder::*;
|
pub use dynamic_texture_atlas_builder::*;
|
||||||
pub use mesh2d::*;
|
pub use mesh2d::*;
|
||||||
@ -51,15 +50,14 @@ pub use texture_slice::*;
|
|||||||
use bevy_app::prelude::*;
|
use bevy_app::prelude::*;
|
||||||
use bevy_asset::{load_internal_asset, AssetApp, Assets, Handle};
|
use bevy_asset::{load_internal_asset, AssetApp, Assets, Handle};
|
||||||
use bevy_core_pipeline::core_2d::Transparent2d;
|
use bevy_core_pipeline::core_2d::Transparent2d;
|
||||||
use bevy_ecs::{prelude::*, query::QueryItem};
|
use bevy_ecs::prelude::*;
|
||||||
use bevy_image::Image;
|
use bevy_image::Image;
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
extract_component::{ExtractComponent, ExtractComponentPlugin},
|
|
||||||
mesh::{Mesh, Mesh2d, MeshAabb},
|
mesh::{Mesh, Mesh2d, MeshAabb},
|
||||||
primitives::Aabb,
|
primitives::Aabb,
|
||||||
render_phase::AddRenderCommand,
|
render_phase::AddRenderCommand,
|
||||||
render_resource::{Shader, SpecializedRenderPipelines},
|
render_resource::{Shader, SpecializedRenderPipelines},
|
||||||
view::{self, NoFrustumCulling, VisibilityClass, VisibilitySystems},
|
view::{NoFrustumCulling, VisibilitySystems},
|
||||||
ExtractSchedule, Render, RenderApp, RenderSet,
|
ExtractSchedule, Render, RenderApp, RenderSet,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -90,16 +88,6 @@ pub enum SpriteSystem {
|
|||||||
ComputeSlices,
|
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 {
|
impl Plugin for SpritePlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
load_internal_asset!(
|
load_internal_asset!(
|
||||||
@ -122,12 +110,7 @@ impl Plugin for SpritePlugin {
|
|||||||
.register_type::<Anchor>()
|
.register_type::<Anchor>()
|
||||||
.register_type::<TextureAtlas>()
|
.register_type::<TextureAtlas>()
|
||||||
.register_type::<Mesh2d>()
|
.register_type::<Mesh2d>()
|
||||||
.register_type::<SpriteSource>()
|
.add_plugins((Mesh2dRenderPlugin, ColorMaterialPlugin))
|
||||||
.add_plugins((
|
|
||||||
Mesh2dRenderPlugin,
|
|
||||||
ColorMaterialPlugin,
|
|
||||||
ExtractComponentPlugin::<SpriteSource>::default(),
|
|
||||||
))
|
|
||||||
.add_systems(
|
.add_systems(
|
||||||
PostUpdate,
|
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)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ use crate::{
|
|||||||
use bevy_asset::Assets;
|
use bevy_asset::Assets;
|
||||||
use bevy_color::LinearRgba;
|
use bevy_color::LinearRgba;
|
||||||
use bevy_derive::{Deref, DerefMut};
|
use bevy_derive::{Deref, DerefMut};
|
||||||
|
use bevy_ecs::entity::EntityHashSet;
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
change_detection::{DetectChanges, Ref},
|
change_detection::{DetectChanges, Ref},
|
||||||
component::{require, Component},
|
component::{require, Component},
|
||||||
@ -19,16 +20,15 @@ use bevy_image::Image;
|
|||||||
use bevy_math::Vec2;
|
use bevy_math::Vec2;
|
||||||
use bevy_reflect::{prelude::ReflectDefault, Reflect};
|
use bevy_reflect::{prelude::ReflectDefault, Reflect};
|
||||||
use bevy_render::sync_world::TemporaryRenderEntity;
|
use bevy_render::sync_world::TemporaryRenderEntity;
|
||||||
use bevy_render::view::Visibility;
|
use bevy_render::view::{self, Visibility, VisibilityClass};
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
primitives::Aabb,
|
primitives::Aabb,
|
||||||
view::{NoFrustumCulling, ViewVisibility},
|
view::{NoFrustumCulling, ViewVisibility},
|
||||||
Extract,
|
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::components::Transform;
|
||||||
use bevy_transform::prelude::GlobalTransform;
|
use bevy_transform::prelude::GlobalTransform;
|
||||||
use bevy_utils::HashSet;
|
|
||||||
use bevy_window::{PrimaryWindow, Window};
|
use bevy_window::{PrimaryWindow, Window};
|
||||||
|
|
||||||
/// [`Text2dBundle`] was removed in favor of required components.
|
/// [`Text2dBundle`] was removed in favor of required components.
|
||||||
@ -94,10 +94,11 @@ pub struct Text2dBundle {}
|
|||||||
TextColor,
|
TextColor,
|
||||||
TextBounds,
|
TextBounds,
|
||||||
Anchor,
|
Anchor,
|
||||||
SpriteSource,
|
|
||||||
Visibility,
|
Visibility,
|
||||||
|
VisibilityClass,
|
||||||
Transform
|
Transform
|
||||||
)]
|
)]
|
||||||
|
#[component(on_add = view::add_visibility_class::<Sprite>)]
|
||||||
pub struct Text2d(pub String);
|
pub struct Text2d(pub String);
|
||||||
|
|
||||||
impl Text2d {
|
impl Text2d {
|
||||||
@ -236,7 +237,7 @@ pub fn extract_text2d_sprite(
|
|||||||
pub fn update_text2d_layout(
|
pub fn update_text2d_layout(
|
||||||
mut last_scale_factor: Local<f32>,
|
mut last_scale_factor: Local<f32>,
|
||||||
// Text items which should be reprocessed again, generally when the font hasn't loaded yet.
|
// 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>>,
|
mut textures: ResMut<Assets<Image>>,
|
||||||
fonts: Res<Assets<Font>>,
|
fonts: Res<Assets<Font>>,
|
||||||
windows: Query<&Window, With<PrimaryWindow>>,
|
windows: Query<&Window, With<PrimaryWindow>>,
|
||||||
@ -269,7 +270,7 @@ pub fn update_text2d_layout(
|
|||||||
if factor_changed
|
if factor_changed
|
||||||
|| computed.needs_rerender()
|
|| computed.needs_rerender()
|
||||||
|| bounds.is_changed()
|
|| bounds.is_changed()
|
||||||
|| queue.remove(&entity)
|
|| (!queue.is_empty() && queue.remove(&entity))
|
||||||
{
|
{
|
||||||
let text_bounds = TextBounds {
|
let text_bounds = TextBounds {
|
||||||
width: if block.linebreak == LineBreak::NoWrap {
|
width: if block.linebreak == LineBreak::NoWrap {
|
||||||
|
Loading…
Reference in New Issue
Block a user