compositor/shells: Require shells to flag outputs as ready to allow repaint

We've added a curtain to the shells so at startup we have something to
render, but this causes a flicker if someone is trying to have a seamless
transition from boot to weston.

Add a ready flag that allows the shell to indicate repaints are safe, so
we can remove the curtains and have no wasted frames at startup.

Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
This commit is contained in:
Derek Foreman 2025-10-16 14:59:35 -05:00 committed by Marius Vlad
parent 683d7df164
commit 0bfcb700b9
9 changed files with 61 additions and 0 deletions

View file

@ -2662,6 +2662,7 @@ background_committed(struct weston_surface *es,
sh_output->output->pos);
weston_view_move_to_layer(sh_output->background_view,
&shell->background_layer.view_list);
weston_output_set_ready(sh_output->output);
}
static void

View file

@ -353,6 +353,8 @@ fs_output_create(struct fullscreen_shell *shell, struct weston_output *output)
}
}
weston_output_set_ready(output);
return fsout;
}

View file

@ -541,6 +541,12 @@ struct weston_output {
enum weston_vrr_mode vrr_mode;
enum weston_color_format color_format;
/**
* Set by the shell to indicate there's some content for this
* output to display.
*/
bool ready;
};
enum weston_pointer_motion_mask {
@ -2715,6 +2721,9 @@ weston_output_set_color_format(struct weston_output *output,
uint32_t
weston_output_get_supported_color_formats(struct weston_output *output);
void
weston_output_set_ready(struct weston_output *output);
#ifdef __cplusplus
}
#endif

View file

@ -353,6 +353,7 @@ create_ivi_screen(struct ivi_layout *layout, struct weston_output *output)
&layout->layout_layer.view_list);
weston_view_set_output(iviscrn->temporary_curtain->view, output);
weston_output_set_ready(output);
}
static void

View file

@ -824,6 +824,7 @@ kiosk_shell_output_create(struct kiosk_shell *shell, struct weston_output *outpu
kiosk_shell_output_recreate_background(shoutput);
kiosk_shell_output_configure(shoutput);
weston_output_set_ready(output);
return shoutput;
}

View file

@ -3904,6 +3904,9 @@ output_repaint_timer_handler(void *data)
compositor->last_repaint_start = now;
wl_list_for_each(output, &compositor->output_list, link) {
if (!output->ready)
continue;
if (!weston_output_check_repaint(output, &now)) {
output->will_repaint = false;
continue;
@ -4336,6 +4339,9 @@ weston_output_schedule_repaint(struct weston_output *output)
struct weston_compositor *compositor = output->compositor;
struct wl_event_loop *loop;
if (!output->ready)
return;
if (compositor->state == WESTON_COMPOSITOR_SLEEPING ||
compositor->state == WESTON_COMPOSITOR_OFFSCREEN)
return;
@ -10495,3 +10501,30 @@ weston_get_backend_type(struct weston_backend *backend)
assert(backend);
return backend->backend_type;
}
/** Inform the compositor that an output is ready for its first repaint
*
* When a new output is added, it may not have any content to be
* displayed. This could lead to strange flickers or hangs at
* startup if uninitialized buffers become attached for
* scanout. To prevent this, we assert that the output has
* content to display.
*
* The shell must inform the compositor when content such as a
* background is in the scene graph and this output can safely
* be repainted.
*
* Only needs to be called once per output, and an output
* can never become unready.
*
* \param output the output that has become ready
* \ingroup output
*/
WL_EXPORT void
weston_output_set_ready(struct weston_output *output)
{
if (!output->ready) {
output->ready = true;
weston_output_schedule_repaint(output);
}
}

View file

@ -921,6 +921,15 @@ lua_shell_env_output_is_enabled(struct lua_State *lua)
return 1;
}
static int
lua_shell_env_output_set_ready(struct lua_State *lua)
{
struct lua_shell_output *shoutput = get_output_from_arg(lua, 1);
weston_output_set_ready(shoutput->output);
return 0;
}
static int
lua_shell_env_output_set_private(struct lua_State *lua)
{
@ -954,6 +963,7 @@ lua_shell_env_init_output(struct lua_shell *shell)
{ "is_enabled", lua_shell_env_output_is_enabled },
{ "set_private", lua_shell_env_output_set_private },
{ "get_private", lua_shell_env_output_get_private },
{ "set_ready", lua_shell_env_output_set_ready },
{ NULL, NULL }
};

View file

@ -95,6 +95,9 @@ function my_output_create(output)
pd.background_view = bv
output:set_private(pd)
-- Must set ready or no repaints will take place
output:set_ready()
end
function output_moved(output, move_x, move_y)

View file

@ -338,6 +338,7 @@ wet_shell_init(struct weston_compositor *ec,
screenshooter_create(ec);
desktest_shell_add_bindings(dts);
weston_output_set_ready(output);
return 0;