Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace the local text queues in the text systems with flags stored in a component #8549

Merged
merged 22 commits into from
May 8, 2023

Conversation

ickshonpe
Copy link
Contributor

@ickshonpe ickshonpe commented May 5, 2023

Objective

text_system and measure_text_system both keep local queues to keep track of text node entities that need recomputations/remeasurement, which scales very badly with large numbers of text entities (O(n^2)) and makes the code quite difficult to understand.

Also text_system filters for Changed<Text>, this isn't something that it should do. When a text node entity fails to be processed by measure_text_system because a font can't be found, the text node will still be added to text_system's local queue for recomputation. Text should only ever be queued by text_system when a text node's geometry is modified or a new measure is added.

Solution

Remove the local text queues and use a component TextFlags to schedule remeasurements and recomputations.

Changelog

  • Created a component TextFlags with fields remeasure and recompute, which can be used to schedule a text remeasure or recomputation respectively and added it to TextBundle.
  • Removed the local text queues from measure_text_system and text_system and instead use the TextFlags component to schedule remeasurements and recomputations.

Migration Guide

The component TextFlags has been added to TextBundle.

@ickshonpe
Copy link
Contributor Author

ickshonpe commented May 5, 2023

Big gains with lots of text nodes:

cargo run --example many_buttons --profile stress-test --features trace_tracy -- recompute-text

many_buttons_recompute-text_measure_text_system_remove_text_queue_90427f27ff83a6_vs_main_a616fa8f70054d1c

many_buttons_recompute-text_text_system_remove_text_queue_90427f27ff83a6_vs_main_a616fa8f70054d1c

@alice-i-cecile alice-i-cecile added C-Performance A change motivated by improving speed, memory usage or compile times A-UI Graphical user interfaces, styles, layouts, and widgets C-Code-Quality A section of code that is hard to understand or change C-Bug An unexpected or incorrect behavior labels May 5, 2023
Copy link
Member

@alice-i-cecile alice-i-cecile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a much nicer implementation, and the performance benefits are non-trivial.

@alice-i-cecile alice-i-cecile added this to the 0.11 milestone May 5, 2023
@ickshonpe
Copy link
Contributor Author

This is a much nicer implementation, and the performance benefits are non-trivial.

Yep, really pleased with how this PR turned out. I'd rather not have added yet another UI component but there isn't really anywhere to put the flag variables that makes sense and doesn't get filtered for changes.

Copy link
Contributor

@nicoburns nicoburns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One comment on terminology. Otherwise looks good to me.

Comment on lines 30 to 35
pub struct TextFlags {
/// create a new measure for the text
remeasure: bool,
/// recompute the text
recompute: bool,
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like remeasure should be called regenerate_measure_function or similar. "measuring" is when you call the measure function not when you generate it. recompute could then be called remeasure, but I think recompute is also fine.

Copy link
Contributor Author

@ickshonpe ickshonpe May 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah the terminology everywhere needs to be tightened up. I've been loose with it because I'm not really
clear on what's going to be intuitive for users etc, so just used short easy names. Even regenerate_measure_function is a bit misleading, since the flag is most commonly going to be used when a new text node entity is spawned but its fonts haven't loaded, so it is rescheduling the initial creation of a measure function until the next frame, not regenerating an existing measure function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed it to generate_measure_function, seems okay.

Copy link
Contributor Author

@ickshonpe ickshonpe May 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thought about this again, and I think these renamings are better as they capture the correct semantics:

  • generate_measure_func -> needs_new_measure_func
  • recompute -> needs_recompute

@alice-i-cecile alice-i-cecile added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label May 7, 2023
* `generate_measure_func` -> `needs_new_measure_func`
* `recompute` -> `needs_recompute`
@ickshonpe
Copy link
Contributor Author

ickshonpe commented May 8, 2023

It's outside of the scope of this PR and I don't want to add any more changes, but it seems like it should be impossible for queue_text to return a NoSuchFont error since the fonts need to be already loaded to create a measure func. It should probably panic on this error, and there might be room for some other simplifications somewhere.

@alice-i-cecile alice-i-cecile added this pull request to the merge queue May 8, 2023
Merged via the queue into bevyengine:main with commit e0a94ab May 8, 2023
@Selene-Amanita Selene-Amanita added the C-Breaking-Change A breaking change to Bevy's public API that needs to be noted in a migration guide label Jul 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-UI Graphical user interfaces, styles, layouts, and widgets C-Breaking-Change A breaking change to Bevy's public API that needs to be noted in a migration guide C-Bug An unexpected or incorrect behavior C-Code-Quality A section of code that is hard to understand or change C-Performance A change motivated by improving speed, memory usage or compile times S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants