{{ message }}
perf(gtk3-wayland): deferred dirty redraw#20528
Open
dezza wants to merge 8 commits into
Open
Conversation
Contributor
Author
c976f90 to
c6c5cc6
Compare
Contributor
Author
Member
Contributor
Author
Thanks! This was news to me too when I read the help - I know some have it permanently enabled, I'll just revert it. Still haven't found issues. |
Implements a dirty rect box for gtk3 with wayland backend. Instead of constantly pumping gtk3 loop between keypress, which *almost always* have a queued draw due to especially * `gui_gtk_draw_string_ext` * `gui_mch_clear_block` .. or `gui_mch_delete_lines`, `gui_mch_insert_lines` when scrolling. Instead we re-use `gui_mch_update`, which before pumped redraws during key-repeat like `pgup` for scrolling, this caused tearing, partial redraws. In `gui_mch_update` we now explicitly call `gui_mch_flush` for wayland, where a `wl_flush` function flushes the dirty rect. We gate that flush checking for a queued redraw in gdk/gtk3. This prepares a redraw for `g_main_context_iteration` below. The result is, that scrolling is fast, mostly smooth and cpu usage lowered significantly; because key input, especially with continous- key repeat with a scroll key such as `pgup`/`c-b` does not- simultaneously pump excessive redraws from the micro-redraws queued by `gui_gtk_draw_string_ext` etc. This aligns with intended use of `gui_mch_update` on x11, but is mostly a symptom of wayland being asynchronous, whereas x11 and vim is largely stateful, imperative and immediate. Inside `gui_mch_wait_for_chars` it triggers `g_main_context_iteration` constantly *both at idle or with key input.* and finally reaches `gui_mch_update`, even if a key is held.
gdk_display_flush is noop on wayland anyways.
If `set lazyredraw` is on holding pgup to scroll will not redraw until the key is released.
This reverts commit 9d7b53f.
Contributor
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Implements a dirty rect box for gtk3 with wayland backend.
Instead of constantly pumping gtk3 loop between keypress, which almost always have a queued draw due to especially
gui_gtk_draw_string_extgui_mch_clear_block.. or
gui_mch_delete_lines,gui_mch_insert_lineswhen scrolling.Instead we re-use
gui_mch_update, which before pumped redraws during key-repeat likepgupfor scrolling. This caused tearing, partial redraws.In
gui_mch_updatecallgui_mch_flushfor wayland, where awl_flushfunction flushes the dirty rect.We gate that flush checking for a queued redraw in gdk/gtk3.
This prepares a redraw for
g_main_context_iterationbelow.The result is that scrolling is fast, mostly smooth and cpu usage lowered significantly; because key input, especially with continous key-repeat and scroll key such as
pgup/c-bdoes not simultaneously pump excessive redraws from the micro-redraws queued bygui_gtk_draw_string_extetc.Inside
gui_mch_wait_for_charsit triggersg_main_context_iterationconstantly both at idle or with key input. and finally reachesgui_mch_update, even if a key is held.^ This aligns with intended use of
gui_mch_updateon x11, but is mostly a symptom of wayland being asynchronous, whereas x11 and vim is largely stateful, imperative and immediate. x11 handles the continous drawing efficiently, but wayland redraws fully + gtk3 has fractional/hidpi perf issues itself.The constant pump of the
g_mainloop has side-effects on wayland, as there is almost always a small redraw queued, or it will simply render too early (midscroll) and cause tearing, choking performance.Therefore there aren't many good solutions to an architectural issue of both gtk3+vim. No better solutions other than reducing load (raise font size, lower res etc) or throttling (non-trivial and not proper) - while gtk4 still matures.
.. Thats why the:
if (prio == GDK_PRIORITY_REDRAW)gate - as it seems to work, is a very neat discovery, because even if if misses a single event, it comes around faster again than without. Fast enough, to not notice within a monitor 60hz refresh rate (higher refresh rate forget about it 😄 testing is welcome).More importantly it is unbiased, no compromises, its not a "lazy redraw" as redraws seemingly work normal everywhere (but faster, non-tearing). Its not waiting for key release or frame skipping - every single scroll is still displayed. Looking really closely, it seems gtk3 is avoiding redraw storms this way, as it does skip some redraws, but only those skipped due to more queued redraws invalidating the previous one.
96e30bc
Closes: #18002