-
-
Notifications
You must be signed in to change notification settings - Fork 21.3k
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
Improve Scene Tree editor performance #99700
base: master
Are you sure you want to change the base?
Conversation
Before: (this scene has about 15,000 nodes) Screencast.From.2024-11-26.02-11-22.mp4After: Screencast.From.2024-11-26.02-10-35.mp4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stealing @AThousandShips 's job 🤣
6aefc0b
to
9a25be0
Compare
431094f
to
05519d4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I confirm that birdies are in the nest (dots at the end of the comments)😃
05519d4
to
d4d55d0
Compare
Changing valid types does not update the nodes (they stay disabled/enabled). Can be tested with this simple EditorScript: extends EditorScript
func _run() -> void:
EditorInterface.popup_node_selector(func(n): print(n), ["Node2D"]) Run it, then remove "Node2D" and run again. Nodes that didn't match originally will stay disabled. |
c5fca34
to
e076f60
Compare
This comment was marked as outdated.
This comment was marked as outdated.
e076f60
to
8851ae1
Compare
The buttons don't get updated on various actions, including toggling unique name, making instance local, changing configuration warnings, adding node to group, connecting etc. The tooltip also doesn't update. |
8851ae1
to
e113a71
Compare
@KoBeWi okay I changed the design entirely. The cache now uses a custom hashing function to keep track of changes, this should be easier to keep consistent. This is a smidge slower than the previous way of doing it but still way faster than what we had. I have tested the following:
|
e113a71
to
1df8248
Compare
godot.windows.editor.dev.x86_64_HHOrYYEJ18.mp4
godot.windows.editor.dev.x86_64_2lyvNQzXzb.mp4
godot.windows.editor.dev.x86_64_5cxcUDaMEk.mp4
|
9a856ff
to
8d7b5eb
Compare
@KoBeWi I think I addressed your issues. Part of the reason I didn't figure it out was that there's a bug in master already whereby in the reparent node dialog nodes with disabled processing wouldn't show up as red. This is also fixed in this PR now. The following things were tested: old tests:
new tests:
|
Found another bug with node selector. |
I checked the implementation and looks like the main idea is hashing everything relevant for node appearance and using it to update only when needed. This means that every time we add something new that can affect anything about TreeItems we need to add it to the hash; rather error-prone, but the improved performance makes this compromise reasonable. There are still a couple of bugged cases, but other than that I think the PR is fine overall. |
As for changing the hash, I agree that it is a bit more work but on the other hand, for new things added it not showing up in the editor should be immediately apparent, unlike now where we are adding it now. The things checked outside of the hash are things that are related to the editor state, not the node state. I didn't want to have to pass variables into the _hash_node() method. I could make it work that way if you'd like? It'd be pretty much the same amount of code. For the pre_filter_color, that cannot be part of the hash as it is something that happens after nodes are updated and is also purely editor state.
I think that is all you found this round, right? |
Yes, last time I just checked all code that sets custom color or adds buttons, but there are other ways how TreeItems can be changed. There might be some tooltip changes I missed.
If you need to pass more than TreeItem then it's not worth it. |
I'll go through _update_tooltip with a fine-tooth comb to make sure I have indeed caught everything.
I would have to, yes. I'll leave it as-is then. |
c3a3a60
to
3c006fe
Compare
@KoBeWi I think I addressed your concerns and fixed the remaining bugs. I've also made the hash function smaller by relying on signals to update some aspects of the editor. These signals get emitted by Node itself, they must also be emitted if a script changes them. This claws back quite a lot of performance compared to the original non-hash based version. Please be aware that quite a bit changed compared to last time! The following things were tested:
new tests:
|
We now cache the Node*<>TreeItem* mapping in the SceneTreeEditor. This allows us to make targeted updates to the Tree used to display the scene tree in the editor. Previously on almost all changes to the scene tree the editor would rebuild the entire widget, causing a large number of deallocations an allocations. We now carefully manipulate the Tree widget in-situ saving a large number of these allocations. There is definitely more that could be done, but this is already a massive improvement. This fixes godotengine#83460
Since this function now exists there seems to be little reason not to expose it. Discussed with @bruvzg.
3c006fe
to
3dc7dea
Compare
I think I see a couple more ways to optimize things a bit further. I'll make more changes, sorry for the extra noise. |
We now cache the Node*<>TreeItem* mapping in the SceneTreeEditor. This allows us to make targeted updates to the Tree used to display the scene tree in the editor.
Previously on almost all changes to the scene tree the editor would rebuild the entire widget, causing a large number of deallocations an allocations. We now carefully manipulate the Tree widget in-situ saving a large number of these allocations.
There is definitely more that could be done, but this is already a massive improvement.
This fixes #83460