[PATCH weston] compositor-drm: reset KMS state on VT-switch in

Pekka Paalanen ppaalanen at gmail.com
Thu Jul 27 10:51:20 UTC 2017


From: Pekka Paalanen <pekka.paalanen at collabora.co.uk>

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
47224cc9312fef05c1a523ea0da0a1aae66f100d:

	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 at collabora.com>
Signed-off-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
---
 libweston/compositor-drm.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index c51d24b6..ed397dc1 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -220,6 +220,8 @@ struct drm_output {
 	enum dpms_enum dpms;
 	struct backlight *backlight;
 
+	bool state_invalid;
+
 	int vblank_pending;
 	int page_flip_pending;
 	int destroy_pending;
@@ -880,7 +882,7 @@ drm_output_repaint(struct weston_output *output_base,
 		return -1;
 
 	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) {
 		ret = drmModeSetCrtc(backend->drm.fd, output->crtc_id,
 				     output->fb_pending->fb_id, 0, 0,
@@ -891,6 +893,8 @@ drm_output_repaint(struct weston_output *output_base,
 			goto err_pageflip;
 		}
 		output_base->set_dpms(output_base, WESTON_DPMS_ON);
+
+		output->state_invalid = false;
 	}
 
 	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;
 	}
 
+	/* 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 */
 	vbl.request.type |= drm_waitvblank_pipe(output);
 	ret = drmWaitVBlank(backend->drm.fd, &vbl);
@@ -2810,6 +2820,7 @@ create_output_for_connector(struct drm_backend *b,
 	if (output == NULL)
 		goto err;
 
+	output->state_invalid = true;
 	output->connector = connector;
 	output->crtc_id = resources->crtcs[i];
 	output->pipe = i;
@@ -3130,6 +3141,10 @@ session_notify(struct wl_listener *listener, void *data)
 		weston_log("activating session\n");
 		weston_compositor_wake(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);
 	} else {
 		weston_log("deactivating session\n");
-- 
2.13.0



More information about the wayland-devel mailing list