From 60d33f28471d4fb247ebe8f8205211240b7c4382 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 28 Jun 2022 11:29:57 +0530 Subject: [PATCH] Wayland: Reduce flicker at startup by not using render frames immediately after a resize Fixes #5235 --- docs/changelog.rst | 2 ++ kitty/child-monitor.c | 6 ++++-- kitty/glfw.c | 4 +++- kitty/state.h | 1 + 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index b715fac0d..33d854b30 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -54,6 +54,8 @@ Detailed list of changes - macOS: Fix a regression that caused switching keyboard input using Eisu and Kana keys not working (:iss:`5232`) +- Wayland: Reduce flicker at startup by not using render frames immediately after a resize (:iss:`5235`) + 0.25.2 [2022-06-07] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/kitty/child-monitor.c b/kitty/child-monitor.c index 771e98547..de884346c 100644 --- a/kitty/child-monitor.c +++ b/kitty/child-monitor.c @@ -758,7 +758,6 @@ render(monotonic_t now, bool input_read) { for (size_t i = 0; i < global_state.num_os_windows; i++) { OSWindow *w = global_state.os_windows + i; - w->render_calls++; if (!w->num_tabs) continue; if (!should_os_window_be_rendered(w)) { update_os_window_title(w); @@ -767,8 +766,11 @@ render(monotonic_t now, bool input_read) { } if (USE_RENDER_FRAMES && w->render_state != RENDER_FRAME_READY) { if (w->render_state == RENDER_FRAME_NOT_REQUESTED || no_render_frame_received_recently(w, now, ms_to_monotonic_t(250ll))) request_frame_render(w); - continue; + // dont respect render frames soon after a resize on Wayland as they cause flicker because + // we want to fill the newly resized buffer ASAP, not at compositors convenience + if (global_state.is_wayland && (monotonic() - w->viewport_resized_at) > s_double_to_monotonic_t(1)) continue; } + w->render_calls++; make_os_window_context_current(w); if (w->live_resize.in_progress && OPT(resize_draw_strategy) >= RESIZE_DRAW_BLANK) { blank_os_window(w); diff --git a/kitty/glfw.c b/kitty/glfw.c index d5e40fe2d..cbe543480 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -108,6 +108,7 @@ update_os_window_viewport(OSWindow *window, bool notify_boss) { return; // no change, ignore } int min_width, min_height; min_size_for_os_window(window, &min_width, &min_height); + window->viewport_resized_at = monotonic(); if (w <= 0 || h <= 0 || fw < min_width || fh < min_height || fw < w || fh < h) { log_error("Invalid geometry ignored: framebuffer: %dx%d window: %dx%d\n", fw, fh, w, h); if (!window->viewport_updated_at_least_once) { @@ -1356,7 +1357,8 @@ should_os_window_be_rendered(OSWindow* w) { return ( glfwGetWindowAttrib(w->handle, GLFW_ICONIFIED) || !glfwGetWindowAttrib(w->handle, GLFW_VISIBLE) || - glfwGetWindowAttrib(w->handle, GLFW_OCCLUDED) + glfwGetWindowAttrib(w->handle, GLFW_OCCLUDED) || + !glfwAreSwapsAllowed(w->handle) ) ? false : true; } diff --git a/kitty/state.h b/kitty/state.h index 21f42a019..ee38bfb4e 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -201,6 +201,7 @@ typedef struct { PyObject *window_title; bool disallow_title_changes, title_is_overriden; bool viewport_size_dirty, viewport_updated_at_least_once; + monotonic_t viewport_resized_at; LiveResizeInfo live_resize; bool has_pending_resizes, is_semi_transparent, shown_once, is_damaged; uint32_t offscreen_texture_id;