compositor-drm: reset KMS state on VT-switch in
Fix a regression with VT-switching away from Weston and then back
causing drmModePageFlip() to fail with ENOSPC or EINVAL, leaving one or
more outputs not updated. The regression appeared in
47224cc931:
compositor-drm: Delete drm_backend_set_modes
Fix it by forcing a drmModeSetCrtc() on all outputs both initially
created and after VT-switch in.
Cc: Daniel Stone <daniels@collabora.com>
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
v2: moved state_invalid=true from create_output_for_connector() to
drm_output_enable()
Reviewed-by: Daniel Stone <daniels@collabora.com>
This commit is contained in:
@@ -220,6 +220,8 @@ struct drm_output {
|
|||||||
enum dpms_enum dpms;
|
enum dpms_enum dpms;
|
||||||
struct backlight *backlight;
|
struct backlight *backlight;
|
||||||
|
|
||||||
|
bool state_invalid;
|
||||||
|
|
||||||
int vblank_pending;
|
int vblank_pending;
|
||||||
int page_flip_pending;
|
int page_flip_pending;
|
||||||
int destroy_pending;
|
int destroy_pending;
|
||||||
@@ -880,7 +882,7 @@ drm_output_repaint(struct weston_output *output_base,
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
mode = container_of(output->base.current_mode, struct drm_mode, base);
|
mode = container_of(output->base.current_mode, struct drm_mode, base);
|
||||||
if (!output->fb_current ||
|
if (output->state_invalid || !output->fb_current ||
|
||||||
output->fb_current->stride != output->fb_pending->stride) {
|
output->fb_current->stride != output->fb_pending->stride) {
|
||||||
ret = drmModeSetCrtc(backend->drm.fd, output->crtc_id,
|
ret = drmModeSetCrtc(backend->drm.fd, output->crtc_id,
|
||||||
output->fb_pending->fb_id, 0, 0,
|
output->fb_pending->fb_id, 0, 0,
|
||||||
@@ -891,6 +893,8 @@ drm_output_repaint(struct weston_output *output_base,
|
|||||||
goto err_pageflip;
|
goto err_pageflip;
|
||||||
}
|
}
|
||||||
output_base->set_dpms(output_base, WESTON_DPMS_ON);
|
output_base->set_dpms(output_base, WESTON_DPMS_ON);
|
||||||
|
|
||||||
|
output->state_invalid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drmModePageFlip(backend->drm.fd, output->crtc_id,
|
if (drmModePageFlip(backend->drm.fd, output->crtc_id,
|
||||||
@@ -999,6 +1003,12 @@ drm_output_start_repaint_loop(struct weston_output *output_base)
|
|||||||
goto finish_frame;
|
goto finish_frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Need to smash all state in from scratch; current timings might not
|
||||||
|
* be what we want, page flip might not work, etc.
|
||||||
|
*/
|
||||||
|
if (output->state_invalid)
|
||||||
|
goto finish_frame;
|
||||||
|
|
||||||
/* Try to get current msc and timestamp via instant query */
|
/* Try to get current msc and timestamp via instant query */
|
||||||
vbl.request.type |= drm_waitvblank_pipe(output);
|
vbl.request.type |= drm_waitvblank_pipe(output);
|
||||||
ret = drmWaitVBlank(backend->drm.fd, &vbl);
|
ret = drmWaitVBlank(backend->drm.fd, &vbl);
|
||||||
@@ -2675,6 +2685,8 @@ drm_output_enable(struct weston_output *base)
|
|||||||
output->connector->count_modes == 0 ?
|
output->connector->count_modes == 0 ?
|
||||||
", built-in" : "");
|
", built-in" : "");
|
||||||
|
|
||||||
|
output->state_invalid = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_free:
|
err_free:
|
||||||
@@ -3130,6 +3142,10 @@ session_notify(struct wl_listener *listener, void *data)
|
|||||||
weston_log("activating session\n");
|
weston_log("activating session\n");
|
||||||
weston_compositor_wake(compositor);
|
weston_compositor_wake(compositor);
|
||||||
weston_compositor_damage_all(compositor);
|
weston_compositor_damage_all(compositor);
|
||||||
|
|
||||||
|
wl_list_for_each(output, &compositor->output_list, base.link)
|
||||||
|
output->state_invalid = true;
|
||||||
|
|
||||||
udev_input_enable(&b->input);
|
udev_input_enable(&b->input);
|
||||||
} else {
|
} else {
|
||||||
weston_log("deactivating session\n");
|
weston_log("deactivating session\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user