-
-
Notifications
You must be signed in to change notification settings - Fork 21.6k
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
CodeEdit: Improve render time by 2x #92865
CodeEdit: Improve render time by 2x #92865
Conversation
Drawing is already limited to once per frame. It's called |
it very much does draw multiple times per process loop (maybe different meaning than frame) bc queue_redraw adds a message to the MessageQueue which gets flushed multiple times per iteration |
How godot/scene/main/canvas_item.cpp Lines 427 to 433 in e96ad5a
|
How does |
it does get called in multiple stages, specifically in i can recreate the test if you want |
Ah yeah, the queue is flushed multiple times per iteration. So it could happen e.g. if you queue redraw in both process frame and physics frame. Weird that it happens tho. |
CodeEdit should not be using physics process, it's a temporary ugly solution to get smooth scrolling that causes bugs, but no one has managed to solve this yet. |
i see.. i.. assumed it was simply copied over from |
What I'm saying about the scrollbar is on the side - no need to address it here, but in general, we really need a GUI wizard to implement smooth scroll properly without using physics process. Our editor shouldn't be using physics process. |
a1c4076
to
e296343
Compare
sorry for not being clear about how it draws multiple times every frame but i didn't expect it to be unbelievable i tested it just now on master on a debug linux build and it seems to draw 8! times per process iteration when scrolling vigarously and @MewPurPur, i asked about the smooth scrolling bug bc in this PR ive changed the TextEdit to use |
Some options off top of my head:
I've used the latter multiple times, notably for the physics interpolation. An advantage here is you'd have tighter control of the timing of the calls. Frame specific Another potential snag in either case is if the update caused side effects, like queuing the update of another e.g.
Depending on what is done in these updates, UI code is typically full of recursive stuff for layouts. |
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.
Tested locally (rebased on top of master
5833f59), it works as expected. I've tested the script editor and didn't notice any regressions to common behavior (code folding, autocompletion, multiple carets).
Benchmark
On average, this PR is 2.16× faster than master
with an optimized editor build (optimize=speed lto=full
) on the MRP linked in the PR.
However, I get a reproducible slowdown in terms of editor FPS when opening the Platformer 2D's player.gd
script in the editor with the following editor settings:
- Script is scrolled to its first line, with the caret on the first line and first character (no text is selected).
- Output panel is cleared and collapsed.
- Window is maximized on a 4K display at 100% scaling.
- Editor started with the
--print-fps
command line argument. - V-Sync Mode: Disabled.
- Update Continuously checked.
Before this PR, I get 861 FPS (1.16 mspf) in a maximized editor window on average, while after this PR, I get 758 FPS (1.31 mspf) on average.
I've made sure I'm CPU-bottlenecked in this situation (GPU utilization does not exceed 40% in this scenario). This issue does not occur at lower resolutions (where less of the script is visible), such as a 1920x1080 window of the editor. In this case, I'm even more CPU-bottlenecked but this PR wins out over master
.
Either way, I figure I'd point this out as this may point out at some scalability issues in the new code (e.g. methods that have O(N²)
scaling has replaced methods that were previously O(N)
).
PC specifications
- CPU: Intel Core i9-13900K
- GPU: NVIDIA GeForce RTX 4090
- RAM: 64 GB (2×32 GB DDR5-5800 C30)
- SSD: Solidigm P44 Pro 2 TB
- OS: Linux (Fedora 39)
Before
10.0878296476422ms avg draw time (99 samples)
10.0065517907191ms avg draw time (198 samples)
9.94229878640737ms avg draw time (297 samples)
9.96660463737719ms avg draw time (396 samples)
9.95996937607274ms avg draw time (495 samples)
9.95242515396992ms avg draw time (594 samples)
9.94330463987408ms avg draw time (693 samples)
9.93462313305248ms avg draw time (792 samples)
9.93317573025037ms avg draw time (891 samples)
9.9287399137863ms avg draw time (990 samples)
9.92602815969588ms avg draw time (1089 samples)
After
4.75202184734922ms avg draw time (99 samples)
4.6268870132138ms avg draw time (198 samples)
4.60077375675291ms avg draw time (297 samples)
4.57970060483374ms avg draw time (396 samples)
4.56591904765428ms avg draw time (495 samples)
4.56037465169374ms avg draw time (594 samples)
4.5561594364447ms avg draw time (693 samples)
4.55680308919964ms avg draw time (792 samples)
4.55250055032681ms avg draw time (891 samples)
4.55153975823913ms avg draw time (990 samples)
4.55042635004273ms avg draw time (1089 samples)
I'm finding a lot of instances where _draw() is called twice in 4.3 when it was only called once in 4.2.2, could that be related? I haven't set on to make a MRP yet, but someone else encountered the same:
|
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.
- fixes Toggling breakpoints break when line spacing is high #93036 (after its fixed)
It looks like queue_redraw
has an issue that lets it be called multiple times in a frame, and it is not specifically related to TextEdit or CodeEdit. It should be fixed elsewhere and queue_redraw
should continue to be used in these files instead of this set_process_internal
workaround.
When trying your example (#92865 (comment)) I could only rarely get it to draw 2-3 times per frame.
Also, when there are many lines in a script (over 1000) the line numbers jitter left and right when adding/removing a line.
Here I'm hitting backspace and enter, though the jittering doesn't look exactly the same in gif:
a54bd43
to
4512487
Compare
reverted back to using queue redraw and edit: although its reverted, some of the changes prevent calling
i also removed the change that caused this and tested it no longer happens, i would appreciate u confirming also @kitbdev
it was probably bc i was using the debug build of the editor, and it was hitting all 8 max physics frames per process frame, it makes the debug version of the editor alot harder to use edit: i also don't see that its fixing #93036, but that issue also isn't so descriptive .. so idk |
@Calinou im quite sure theres only one place this happened (replacing a hashmap lookup with when i tested this i didnt get any meaningful slowdown, (probly bc i dont have a 4k monitor, only a 1440p) |
4512487
to
7120253
Compare
f6eb6a9
to
1cca4a0
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.
The line number jitter when there are too many lines issues is fixed.
There is an issue when deleting the longest line, the width doesn't go to the second longest line:
Screen.Recording.2024-08-01.153242.mp4
Also there is an issue with the height when there is lots of wrapped text, the scrollbar doesn't show or is too small:
fb5b2b9
to
5aa62bb
Compare
@kitbdev thank you for reviewing and finding these bugs!!! everything u mentioned should be fixed now, seems the max line height/width being invalidated by setting it to -1 was not a good idea,, lol |
Needs rebase. |
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.
Previous issues fixed.
For #93036 it is fixed, See my comment here #93036 (comment).
Hovering below the last line in the breakpoint gutter will now show the hovered breakpoint on the last line. This now matches the click behavior, since clicking there will add a breakpoint to the last line. If it isn't wanted it can be fixed in another PR.
Just a couple of minor things:
ba18c8e
to
791e2ae
Compare
791e2ae
to
60fa3ec
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.
Haven't tested the performance, but the functionality looks good to me.
Thanks! |
I have tested speed improvement by changing zoom inside script editor using mouse wheel and difference is really noticeable🚀 |
with gdscript syntax highlighting:
before: 30.0385588566243ms avg draw time (1089 samples)
after: 13.0933055755083ms avg draw time (1089 samples)
without syntax highlighting:
before: 17.9521260292186ms avg draw time (1089 samples)
after: 12.9270402524754ms avg draw time (1089 samples)
many improvements to do with:
avoiding redraw:
set_process_internal(true)
instead of queue_redraw to avoid drawing 2-3 times in the same frame whengui_input()
is calledset_code_hint
andset_code_hint_draw_below
avoid redrawing when the values dont changeimproving render speed:
TextLine
_main_gutter_draw_callback
: useget_hovered_gutter()
instead of multiple calls to the more expensiveget_local_mouse_pos()
total_visible_line_count
andLine::line_count
GutterInfo
, which contains a custom callable in both of godots script editor gutters, was getting copied once per gutter per line per frame,some less impactful (more code style) things ..
its obvious that most of the problem was the line syntax highlighting being called every frame
but whats not obvious is that searching through the dictionary and converting to and from variants was a very significant part of it
the performance improvements are especially noticeable on debug builds, as there arent any 'double draws' making the editor lag when scrolling
benchmark: CodeEditText.zip
tested with godot compiled using:
production=yes optimize=size tests=yes deprecated=no scu_build=yes
bc it uses the GDScriptSyntaxHighlighter, to benchmark you have open the project in the editor