If we don't cancel the repaint, we end up pointlessly redrawing the output. What's worse is that pageflipping to the new buffer eventually fails and we miss the finish_frame callback, leaving the compositor stuck when we re-enter the vt.
@ -835,10 +835,21 @@ vt_func(struct weston_compositor *compositor, int event)
ec->prev_state = compositor->state;
compositor->state = WESTON_COMPOSITOR_SLEEPING;
/* If we have a repaint scheduled (either from a
* pending pageflip or the idle handler), make sure we
* cancel that so we don't try to pageflip when we're
* vt switched away. The SLEEPING state will prevent
* further attemps at repainting. When we switch
* back, we schedule a repaint, which will process
* pending frame callbacks. */
wl_list_for_each(output, &ec->base.output_list, link) {
output->repaint_needed = 0;
drm_output_set_cursor(output, NULL);
}
wl_list_for_each(input, &compositor->input_device_list, link)
evdev_remove_devices(input);
wl_list_for_each(output, &ec->base.output_list, link)
if (drmDropMaster(ec->drm.fd) < 0)
fprintf(stderr, "failed to drop master: %m\n");
@ -840,9 +840,8 @@ struct weston_frame_callback {
};
static void
repaint(void *data, int msecs)
repaint(struct weston_output *output, int msecs)
{
struct weston_output *output = data;
struct weston_compositor *compositor = output->compositor;
struct weston_animation *animation, *next;
struct weston_frame_callback *cb, *cnext;
@ -865,7 +864,11 @@ repaint(void *data, int msecs)
idle_repaint(void *data)
repaint(data, weston_compositor_get_time());
/* An idle repaint may have been cancelled by vt switching away. */
if (output->repaint_needed)
repaint(output, weston_compositor_get_time());
WL_EXPORT void