delayed rendering: ignore frame callback if delayed rendering is active

Before, we applied delayed rendering (that is, we gave the client a
chance to do more writes before we scheduled a render refresh) only
when the renderer were idle.

However, with e.g. a high keyboard repeat rate, it is very much
possible to start the render loop and then never break out of it while
receiving keyboard input.

This causes screen flickering, as we're no longer even trying to
detect the clients transaction boundaries.

So, let's rewrite how this is done.

First, we give the user the ability to disable delayed rendering
altogether, by setting either the lower or upper timeout to 0.

Second, when delayed rendering is enabled, we ignore the frame
callback. That is, when receiving input, we *always* reschedule the
lower timeout timer, regardless of whether the render is idle or not.

The render's frame callback handler will *not* render the grid if the
delayed render timers are armed.

This means for longer client data bursts, we may now skip frames. That
is, we're trading screen flicker for the occasional frame hickup.

For short client data bursts we should behave roughly as before.

This greatly improves the behavior of fullscreen, or near fullscreen,
updates of large grids (example, scrolling in emacs in fullscreen,
with a vertical buffer split).
This commit is contained in:
Daniel Eklöf 2020-03-23 19:21:41 +01:00
parent ba0d0e8bbb
commit 5a972cb98e
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 10 additions and 8 deletions

View file

@ -1474,7 +1474,10 @@ frame_callback(void *data, struct wl_callback *wl_callback, uint32_t callback_da
if (term->render.pending.grid) {
term->render.pending.grid = false;
grid_render(term);
/* TODO: need to check if this breaks GNOME/weston */
if (!term->delayed_render_timer.is_armed)
grid_render(term);
}
}