If we have an unused CRTC or connector, explicitly disable it during the end of the repaint cycle, or when we get VT-switched back in.
Signed-off-by: Daniel Stone <dani...@collabora.com> --- libweston/compositor-drm.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) v9: New. See changelog in atomic modesetting patch. diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c index a487bb6..92ed199 100644 --- a/libweston/compositor-drm.c +++ b/libweston/compositor-drm.c @@ -192,6 +192,7 @@ struct drm_backend { void *repaint_data; + bool state_invalid; struct wl_array unused_connectors; struct wl_array unused_crtcs; @@ -383,6 +384,26 @@ static struct gl_renderer_interface *gl_renderer; static const char default_seat[] = "seat0"; +static void +wl_array_remove_uint32(struct wl_array *array, uint32_t elm) +{ + uint32_t *pos, *end; + + end = (uint32_t *) ((char *) array->data + array->size); + + wl_array_for_each(pos, array) { + if (*pos != elm) + continue; + + array->size -= sizeof(*pos); + if (pos + 1 == end) + break; + + memmove(pos, pos + 1, (char *) end - (char *) (pos + 1)); + break; + } +} + static inline struct drm_output * to_drm_output(struct weston_output *base) { @@ -1938,6 +1959,18 @@ drm_repaint_flush(struct weston_compositor *compositor, void *repaint_data) struct drm_backend *b = to_drm_backend(compositor); struct drm_pending_state *pending_state = repaint_data; struct drm_output_state *output_state, *tmp; + uint32_t *unused; + + if (b->state_invalid) { + /* If we need to reset all our state (e.g. because we've + * just started, or just been VT-switched in), explicitly + * disable all the CRTCs we aren't using. This also disables + * all connectors on these CRTCs, so we don't need to do that + * separately with the pre-atomic API. */ + wl_array_for_each(unused, &b->unused_crtcs) + drmModeSetCrtc(b->drm.fd, *unused, 0, 0, 0, NULL, 0, + NULL); + } wl_list_for_each_safe(output_state, tmp, &pending_state->output_list, link) { @@ -1945,6 +1978,8 @@ drm_repaint_flush(struct weston_compositor *compositor, void *repaint_data) DRM_OUTPUT_STATE_UPDATE_ASYNCHRONOUS); } + b->state_invalid = false; + drm_pending_state_free(pending_state); b->repaint_data = NULL; } @@ -3838,6 +3873,9 @@ drm_output_enable(struct weston_output *base) output->connector->count_modes == 0 ? ", built-in" : ""); + wl_array_remove_uint32(&b->unused_crtcs, output->crtc_id); + wl_array_remove_uint32(&b->unused_connectors, output->connector_id); + return 0; err: @@ -3910,6 +3948,7 @@ drm_output_disable(struct weston_output *base) { struct drm_output *output = to_drm_output(base); struct drm_backend *b = to_drm_backend(base->compositor); + uint32_t *unused; if (output->page_flip_pending || output->vblank_pending) { output->disable_pending = 1; @@ -3927,6 +3966,11 @@ drm_output_disable(struct weston_output *base) drm_output_state_free(output->state_cur); output->state_cur = NULL; + unused = wl_array_add(&b->unused_connectors, sizeof(*unused)); + *unused = output->connector_id; + unused = wl_array_add(&b->unused_crtcs, sizeof(*unused)); + *unused = output->crtc_id; + return 0; } @@ -4307,6 +4351,7 @@ session_notify(struct wl_listener *listener, void *data) weston_log("activating session\n"); weston_compositor_wake(compositor); weston_compositor_damage_all(compositor); + b->state_invalid = true; udev_input_enable(&b->input); } else { weston_log("deactivating session\n"); @@ -4692,6 +4737,7 @@ drm_backend_create(struct weston_compositor *compositor, if (b == NULL) return NULL; + b->state_invalid = true; b->drm.fd = -1; wl_array_init(&b->unused_crtcs); wl_array_init(&b->unused_connectors); -- 2.9.3 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel