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

UI extraction improvements v2 #9668

Closed
wants to merge 68 commits into from

Conversation

ickshonpe
Copy link
Contributor

Objective

Reimplements #9212 with the recent rendering changes.

Solution

The design is mostly the same as #9212.

Benchmarks

cargo run --example run --profile stress-test --features trace_tracy --example many_buttons
ui-extraction-2-fps ui-extraction-2-uipassnode ui-extraction-2-prepare ui-extraction-2-queue ui-extraction-2-sort ui-extraction-2-text ui-extraction-2-borders ui-extraction-2-uinodes

(Yellow is this PR, Red is main)

These look good but it still seems to be around 10% to 25% worse than #9212 overall depending on the UI layout.
Not clear why, tried a lot of different ideas but they all made things worse. Merging with the latest visibility changes seemed to cost another 5% or so as well.


Changelog

  • Changed ExtractedUiNodes to use a Vec instead of a SparseSet to store the ExtractedUiNodes
  • Changed to using an unstable sort for the extracted items by enumerating the extraction functions and combining it with the stack index to create a sort key. Doesn't seem to make much of a difference though.

Migration Guide

ickshonpe added 30 commits July 19, 2023 13:55
Instead of a single list of `ExtractedUiNodes`, we have a separate list for each extraction function.
Then we don't need to sort `ExtractedUiNodes` in `prepare_uinodes` as each sublist is already ordered.
Instead of sorting `ExtractedUiNodes`, add a lookup index. Then in prepare_uinodes sort the indices by `stack_index` then use the sorted indices to retrieve each `ExtractedUiNode` in the correct order.

* Added a field `indices` to `ExtractedUiNodes`.
* Added `ExtractedIndex` type.
* New component, holds the uinode entity's stack index. Updated in `ui_stack_system after the `UiStack` is generated.

`bevy_ui::node_bundles`
* Added the `UiStackIndex` to all UI node bundles.

`bevy_ui::render`
* Extract stack indices from the `UiNode` component.
* Made `ExtractedIndex` and the fields of `ExtractedUiNodes` private.
* Added a `clear` method to `ExtractedUiNodes`.
`ExtractedIndex` holds a range of indices instead of a single index.  The `ExtractedUiNodes::push_multiple` method is used to push multiple nodes and store them contiguously.
Renamed `ExtractedUiNodes::push` and `ExtractedUiNodes::push_multiple`  to `ExtractedUiNodes::push_node` and `ExtractedUiNodes::push_nodes`  respectively.
Renamed `ExtractedIndex` to `ExtractedSpan`.
* Changed inner value to `pub(crate)` and added an accessor method.
* Added derive `Reflect` and reflect `Component`, `Default` attributes
* Added a `register_type` to UIPlugin.

`bevy_ui_node::ExtractedRange`:
* Renamed from `ExtractedSpan`, `spans` field of `ExtractedUiNode` also renamed to `ranges`.
pub fn queue_uinodes(mut extracted_uinodes: ResMut<ExtractedUiNodes>) {
extracted_uinodes
.ranges
.sort_unstable_by_key(|extracted_range| extracted_range.sort_key);
Copy link
Contributor

Choose a reason for hiding this comment

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

Did you try radsort?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll try it out.

I made an alternative implementation as well that doesn't require a sort. Instead of storing the layout geometry in components on the uinode entities it has a single layout entity that has a list of all the uinode rects in a vector. It might be a better approach and the prototype seems quite promising but I don't have most of the systems like clipping, interaction, etc working yet. Everything needs to be rewritten to support it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

With rad sort:
queue-rad-sort

Copy link
Contributor

Choose a reason for hiding this comment

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

Which is which? What is being compared?

) {
let draw_function = draw_functions.read().id::<DrawUi>();

for (view, mut transparent_phase) in &mut render_phases.p1() {
Copy link
Contributor

Choose a reason for hiding this comment

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

This approach goes against the design of the renderer. How come you didn't do the queuing of phase items to phases based on the ranges in queue and then let the phase sort them? This is necessary for flexibility to allow plugins to also queue items to the phase.

@alice-i-cecile alice-i-cecile added this to the 0.12 milestone Sep 2, 2023
@alice-i-cecile alice-i-cecile added A-Rendering Drawing game state to the screen C-Performance A change motivated by improving speed, memory usage or compile times A-UI Graphical user interfaces, styles, layouts, and widgets labels Sep 2, 2023
@ickshonpe ickshonpe mentioned this pull request Sep 4, 2023
@alice-i-cecile
Copy link
Member

@ickshonpe I want to keep this in the release milestone; can your resolve conflicts?

@alice-i-cecile alice-i-cecile modified the milestones: 0.12, 0.13 Oct 24, 2023
@alice-i-cecile alice-i-cecile added the X-Controversial There is active debate or serious implications around merging this PR label Oct 24, 2023
@alice-i-cecile
Copy link
Member

This approach goes against the design of the renderer. How come you didn't do the queuing of phase items to phases based on the ranges in queue and then let the phase sort them? This is necessary for flexibility to allow plugins to also queue items to the phase.

This was called out as a blocking architectural decision. Once that's resolved, we can remove the Controversial label.

@alice-i-cecile alice-i-cecile removed this from the 0.13 milestone Jan 24, 2024
@alice-i-cecile alice-i-cecile added X-Contentious There are nontrivial implications that should be thought through and removed X-Controversial There is active debate or serious implications around merging this PR labels Aug 16, 2024
@ickshonpe
Copy link
Contributor Author

Closed, superseded by the extract to a vec PR

@ickshonpe ickshonpe closed this Feb 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Drawing game state to the screen A-UI Graphical user interfaces, styles, layouts, and widgets C-Performance A change motivated by improving speed, memory usage or compile times X-Contentious There are nontrivial implications that should be thought through
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants