Reuse TextLayoutInfo in queue_text (#14997)

# Objective

Don't reallocate `TextLayoutInfo` every time it needs to be updated.

## Solution

Reuse existing allocation.
This commit is contained in:
UkoeHB 2024-09-02 12:01:56 -05:00 committed by GitHub
parent f02d76a44d
commit 2b94a108ae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 29 additions and 21 deletions

View File

@ -145,6 +145,7 @@ impl TextPipeline {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn queue_text( pub fn queue_text(
&mut self, &mut self,
layout_info: &mut TextLayoutInfo,
fonts: &Assets<Font>, fonts: &Assets<Font>,
sections: &[TextSection], sections: &[TextSection],
scale_factor: f64, scale_factor: f64,
@ -156,9 +157,12 @@ impl TextPipeline {
textures: &mut Assets<Image>, textures: &mut Assets<Image>,
y_axis_orientation: YAxisOrientation, y_axis_orientation: YAxisOrientation,
buffer: &mut CosmicBuffer, buffer: &mut CosmicBuffer,
) -> Result<TextLayoutInfo, TextError> { ) -> Result<(), TextError> {
layout_info.glyphs.clear();
layout_info.size = Default::default();
if sections.is_empty() { if sections.is_empty() {
return Ok(TextLayoutInfo::default()); return Ok(());
} }
self.update_buffer( self.update_buffer(
@ -175,14 +179,14 @@ impl TextPipeline {
let font_system = &mut self.font_system.0; let font_system = &mut self.font_system.0;
let swash_cache = &mut self.swash_cache.0; let swash_cache = &mut self.swash_cache.0;
let glyphs = buffer buffer
.layout_runs() .layout_runs()
.flat_map(|run| { .flat_map(|run| {
run.glyphs run.glyphs
.iter() .iter()
.map(move |layout_glyph| (layout_glyph, run.line_y)) .map(move |layout_glyph| (layout_glyph, run.line_y))
}) })
.map(|(layout_glyph, line_y)| { .try_for_each(|(layout_glyph, line_y)| {
let section_index = layout_glyph.metadata; let section_index = layout_glyph.metadata;
let font_handle = sections[section_index].style.font.clone_weak(); let font_handle = sections[section_index].style.font.clone_weak();
@ -224,14 +228,12 @@ impl TextPipeline {
// when glyphs are not limited to single byte representation, relevant for #1319 // when glyphs are not limited to single byte representation, relevant for #1319
let pos_glyph = let pos_glyph =
PositionedGlyph::new(position, glyph_size.as_vec2(), atlas_info, section_index); PositionedGlyph::new(position, glyph_size.as_vec2(), atlas_info, section_index);
Ok(pos_glyph) layout_info.glyphs.push(pos_glyph);
}) Ok(())
.collect::<Result<Vec<_>, _>>()?; })?;
Ok(TextLayoutInfo { layout_info.size = box_size;
glyphs, Ok(())
size: box_size,
})
} }
/// Queues text for measurement /// Queues text for measurement

View File

@ -170,7 +170,7 @@ pub fn update_text2d_layout(
let inverse_scale_factor = scale_factor.recip(); let inverse_scale_factor = scale_factor.recip();
for (entity, text, bounds, mut text_layout_info, mut buffer) in &mut text_query { for (entity, text, bounds, text_layout_info, mut buffer) in &mut text_query {
if factor_changed || text.is_changed() || bounds.is_changed() || queue.remove(&entity) { if factor_changed || text.is_changed() || bounds.is_changed() || queue.remove(&entity) {
let text_bounds = TextBounds { let text_bounds = TextBounds {
width: if text.linebreak_behavior == BreakLineOn::NoWrap { width: if text.linebreak_behavior == BreakLineOn::NoWrap {
@ -183,7 +183,9 @@ pub fn update_text2d_layout(
.map(|height| scale_value(height, scale_factor)), .map(|height| scale_value(height, scale_factor)),
}; };
let text_layout_info = text_layout_info.into_inner();
match text_pipeline.queue_text( match text_pipeline.queue_text(
text_layout_info,
&fonts, &fonts,
&text.sections, &text.sections,
scale_factor.into(), scale_factor.into(),
@ -204,10 +206,11 @@ pub fn update_text2d_layout(
Err(e @ (TextError::FailedToAddGlyph(_) | TextError::FailedToGetGlyphImage(_))) => { Err(e @ (TextError::FailedToAddGlyph(_) | TextError::FailedToGetGlyphImage(_))) => {
panic!("Fatal error when processing text: {e}."); panic!("Fatal error when processing text: {e}.");
} }
Ok(mut info) => { Ok(()) => {
info.size.x = scale_value(info.size.x, inverse_scale_factor); text_layout_info.size.x =
info.size.y = scale_value(info.size.y, inverse_scale_factor); scale_value(text_layout_info.size.x, inverse_scale_factor);
*text_layout_info = info; text_layout_info.size.y =
scale_value(text_layout_info.size.y, inverse_scale_factor);
} }
} }
} }

View File

@ -224,7 +224,7 @@ fn queue_text(
text: &Text, text: &Text,
node: Ref<Node>, node: Ref<Node>,
mut text_flags: Mut<TextFlags>, mut text_flags: Mut<TextFlags>,
mut text_layout_info: Mut<TextLayoutInfo>, text_layout_info: Mut<TextLayoutInfo>,
buffer: &mut CosmicBuffer, buffer: &mut CosmicBuffer,
) { ) {
// Skip the text node if it is waiting for a new measure func // Skip the text node if it is waiting for a new measure func
@ -240,7 +240,9 @@ fn queue_text(
) )
}; };
let text_layout_info = text_layout_info.into_inner();
match text_pipeline.queue_text( match text_pipeline.queue_text(
text_layout_info,
fonts, fonts,
&text.sections, &text.sections,
scale_factor.into(), scale_factor.into(),
@ -260,10 +262,11 @@ fn queue_text(
Err(e @ (TextError::FailedToAddGlyph(_) | TextError::FailedToGetGlyphImage(_))) => { Err(e @ (TextError::FailedToAddGlyph(_) | TextError::FailedToGetGlyphImage(_))) => {
panic!("Fatal error when processing text: {e}."); panic!("Fatal error when processing text: {e}.");
} }
Ok(mut info) => { Ok(()) => {
info.size.x = scale_value(info.size.x, inverse_scale_factor); text_layout_info.size.x =
info.size.y = scale_value(info.size.y, inverse_scale_factor); scale_value(text_layout_info.size.x, inverse_scale_factor);
*text_layout_info = info; text_layout_info.size.y =
scale_value(text_layout_info.size.y, inverse_scale_factor);
text_flags.needs_recompute = false; text_flags.needs_recompute = false;
} }
} }