-
-
Notifications
You must be signed in to change notification settings - Fork 21.8k
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
GUI: Fix Tree
performance regression by using cache
#79325
GUI: Fix Tree
performance regression by using cache
#79325
Conversation
Note that this behavior is still present, albeit to a lesser extent. Some changes are needed in the algorithm for skipping previous rows, but their height must still be taken into account. Perhaps the problem is that the previous rows are being drawn, although they are invisible. See |
I haven't checked the code, but indeed, we don't need to draw them and I think previously we didn't do that. Can you make the necessary changes so that the previous rows are only used to compute the offset? |
9da327e
to
c7a4691
Compare
@YuriSizov Done! Regression caused by this, fixed by this. But I think that caching the minimum width still makes sense. |
@@ -2449,7 +2452,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 | |||
int child_h = -1; | |||
int child_self_height = 0; | |||
if (htotal >= 0) { | |||
child_h = draw_item(children_pos, p_draw_ofs, p_draw_size, c, &child_self_height); | |||
child_h = draw_item(children_pos, p_draw_ofs, p_draw_size, c, child_self_height); | |||
child_self_height += theme_cache.v_separation; |
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.
This seems to be the only place where we care for the returned self height value. So I think this line adding vertical separation can be removed and instead we can assign r_self_height
after we add this value to label_h
.
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'm not sure about whether to include the separator's height in the item's self_height
. But I replaced the code with the following:
r_self_height = compute_item_height(p_item);
label_h = r_self_height + theme_cache.v_separation;
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.
It just seems redundant to add it in two places if these are the only two places that use this value. The name may be not the best, so I understand your hesitation. But I'd say this is pretty minor as far as semantics go.
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.
That said, I'm not insisting. We can merge it as is.
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've tested it, and I can confirm that it doesn't fully solve the slowdown when you scroll all the way down on larger trees, but it does significantly improve the experience. So I think we should go with this, at least for now.
One curiosity that I noticed was that I could clearly experience a slowdown in the editor, but not in a test scene. The scene is just a tree and I fill it up as follows:
extends Tree
const ICON = preload("res://icon.svg")
func _init():
var root := create_item()
for i in range(0, 10000):
var item := create_item(root)
item.set_text(0, str(i))
item.set_icon_max_width(0, 16)
item.set_icon(0, ICON)
This works much smoother than the scene tree in the editor with 5.8k items in it (which I think I took from the linked issue). I suspect it may be something to do with buttons. I think if I add buttons to each row with item.add_button(0, ICON, -1, false, "Hello")
, it does get slightly slower at the bottom.
That's the only difference that I can think of between my test scene and the scene tree view in the editor, as in the editor every node has a visibility toggle in my case.
There are several things to improve about buttons in trees, however, as I outlined in #79792 (comment). So this is something that can be done in a separate PR (I can take a look but I'm giving a chance to the author of the linked PR to work a bit more on their contribution, if they want to).
c7a4691
to
5fb975e
Compare
After rebasing, I noticed crashes. They look unrelated to this PR, but they didn't exist before.
|
Might be related to / fixed by #80187? CC @Sauermann |
Yes, that crash gets fixed by #80187. I was previously unable to cause this crash on X11, so I will take a look at the Test Project to see, where in the X11-platform-code this problem appears. |
Thanks! |
Cherry-picked for 4.1.2. |
On @YuriSizov's advice, I used cache to optimize the bottleneck. This made
Tree
responsive again for 10,000 rows, butTree
is still slower than in 4.0.3. My guess is that further optimizations (and possible refactoring) ofdraw_item()
are desirable.Please test this PR carefully to make sure the cache is invalidated when needed!
Test project: GUITree.zip
Before
After