From 5e43ef81ae8b8d435023f7d84192d136a05e7d85 Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Mon, 8 Apr 2024 14:18:31 +0200 Subject: [PATCH] backend-wayland: don't wait for one frame when starting the repaint loop The repaint loop is started when a client provides a new frame while the compositor is idle. This frame should be shown as soon as possible. So it makes no sense to commit the previous frame one more time before rendering the next frame. Just call weston_output_finish_frame() directly to start repainting immediately. As a side effect, this fixes an issue when the output is resized when no fullscreen shell is involved: At that point, parent.draw_initial_frame is already false, so draw_initial_frame() is not called. But when resizing, the old buffers are removed so the commit happens without a buffer attached to the surface. So the surface is invisible for one frame until the next one is rendered. draw_initial_frame() is not removed here, because it is still needed for the synchronous resize that happens with the fullscreen shell. Signed-off-by: Michael Olbrich --- libweston/backend-wayland/wayland.c | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/libweston/backend-wayland/wayland.c b/libweston/backend-wayland/wayland.c index 245dd8ef..0f57c9e4 100644 --- a/libweston/backend-wayland/wayland.c +++ b/libweston/backend-wayland/wayland.c @@ -117,7 +117,6 @@ struct wayland_output { struct wayland_backend *backend; struct { - bool draw_initial_frame; struct wl_surface *surface; struct wl_output *output; @@ -472,26 +471,14 @@ wayland_output_start_repaint_loop(struct weston_output *output_base) { struct wayland_output *output = to_wayland_output(output_base); struct wayland_backend *wb; + struct timespec ts; assert(output); wb = output->backend; - /* If this is the initial frame, we need to attach a buffer so that - * the compositor can map the surface and include it in its render - * loop. If the surface doesn't end up in the render loop, the frame - * callback won't be invoked. The buffer is transparent and of the - * same size as the future real output buffer. */ - if (output->parent.draw_initial_frame) { - output->parent.draw_initial_frame = false; - - draw_initial_frame(output); - } - - output->frame_cb = wl_surface_frame(output->parent.surface); - wl_callback_add_listener(output->frame_cb, &frame_listener, output); - wl_surface_commit(output->parent.surface); - wl_display_flush(wb->parent.wl_display); + weston_compositor_read_presentation_clock(wb->compositor, &ts); + weston_output_finish_frame(output_base, &ts, WP_PRESENTATION_FEEDBACK_INVALID); return 0; } @@ -1016,7 +1003,6 @@ wayland_output_fullscreen_shell_mode_feedback(struct wayland_output *output, &mode_feedback_listener, &mode_status); - output->parent.draw_initial_frame = false; draw_initial_frame(output); wl_surface_commit(output->parent.surface); @@ -1238,8 +1224,6 @@ wayland_backend_create_output_surface(struct wayland_output *output) wl_surface_set_user_data(output->parent.surface, output); - output->parent.draw_initial_frame = true; - if (b->parent.xdg_wm_base) { output->parent.xdg_surface = xdg_wm_base_get_xdg_surface(b->parent.xdg_wm_base, @@ -1326,14 +1310,12 @@ wayland_output_enable(struct weston_output *base) mode_status = wayland_output_fullscreen_shell_mode_feedback(output, &output->mode); - if (mode_status == MODE_STATUS_FAIL) { + if (mode_status == MODE_STATUS_FAIL) zwp_fullscreen_shell_v1_present_surface(b->parent.fshell, output->parent.surface, ZWP_FULLSCREEN_SHELL_V1_PRESENT_METHOD_CENTER, output->parent.output); - output->parent.draw_initial_frame = true; - } } } else if (b->fullscreen) { wayland_output_set_fullscreen(output, 0, NULL);