Rather than a more piecemeal approach at backend creation, explicitly track connectors and CRTCs we do not intend to use, so we can ensure they are disabled where appropriate.
Signed-off-by: Daniel Stone <dani...@collabora.com> --- libweston/compositor-drm.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c index 04d52f2c6..9c7564383 100644 --- a/libweston/compositor-drm.c +++ b/libweston/compositor-drm.c @@ -188,6 +188,9 @@ struct drm_backend { void *repaint_data; + struct wl_array unused_connectors; + struct wl_array unused_crtcs; + int cursors_are_broken; bool universal_planes; @@ -386,6 +389,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) { @@ -1327,6 +1350,7 @@ drm_output_assign_state(struct drm_output_state *state, enum drm_state_apply_mode mode) { struct drm_output *output = state->output; + struct drm_backend *b = to_drm_backend(output->base.compositor); struct drm_plane_state *plane_state; assert(!output->state_last); @@ -1363,6 +1387,12 @@ drm_output_assign_state(struct drm_output_state *state, else if (plane->type == WDRM_PLANE_TYPE_PRIMARY) output->page_flip_pending = 1; } + + if (output->dpms == WESTON_DPMS_ON) { + wl_array_remove_uint32(&b->unused_connectors, + output->connector_id); + wl_array_remove_uint32(&b->unused_crtcs, output->crtc_id); + } } @@ -3983,6 +4013,7 @@ drm_output_deinit(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 (b->use_pixman) drm_output_fini_pixman(output); @@ -4004,6 +4035,11 @@ drm_output_deinit(struct weston_output *base) drmModeSetCursor(b->drm.fd, output->crtc_id, 0, 0, 0); } } + + 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; } static void @@ -4099,6 +4135,47 @@ drm_output_disable(struct weston_output *base) return 0; } +/** + * Update the list of unused connectors and CRTCs + * + * This keeps the unused_connectors and unused_crtcs arrays up to date. + * + * @param b Weston backend structure + * @param resources DRM resources for this device + */ +static void +drm_backend_update_unused_outputs(struct drm_backend *b, drmModeRes *resources) +{ + int i; + + wl_array_release(&b->unused_connectors); + wl_array_init(&b->unused_connectors); + + for (i = 0; i < resources->count_connectors; i++) { + uint32_t *connector_id; + + if (drm_output_find_by_connector(b, resources->connectors[i])) + continue; + + connector_id = wl_array_add(&b->unused_connectors, + sizeof(*connector_id)); + *connector_id = resources->connectors[i]; + } + + wl_array_release(&b->unused_crtcs); + wl_array_init(&b->unused_crtcs); + + for (i = 0; i < resources->count_crtcs; i++) { + uint32_t *crtc_id; + + if (drm_output_find_by_crtc(b, resources->crtcs[i])) + continue; + + crtc_id = wl_array_add(&b->unused_crtcs, sizeof(*crtc_id)); + *crtc_id = resources->crtcs[i]; + } +} + /** * Create a Weston output structure * @@ -4259,6 +4336,8 @@ create_outputs(struct drm_backend *b, struct udev_device *drm_device) } } + drm_backend_update_unused_outputs(b, resources); + if (wl_list_empty(&b->compositor->output_list) && wl_list_empty(&b->compositor->pending_output_list)) weston_log("No currently active connector found.\n"); @@ -4350,6 +4429,8 @@ update_outputs(struct drm_backend *b, struct udev_device *drm_device) drm_output_destroy(&output->base); } + drm_backend_update_unused_outputs(b, resources); + free(connected); drmModeFreeResources(resources); } @@ -4416,6 +4497,9 @@ drm_destroy(struct weston_compositor *ec) weston_launcher_destroy(ec->launcher); + wl_array_release(&b->unused_crtcs); + wl_array_release(&b->unused_connectors); + close(b->drm.fd); free(b); } @@ -4848,6 +4932,8 @@ drm_backend_create(struct weston_compositor *compositor, return NULL; b->drm.fd = -1; + wl_array_init(&b->unused_crtcs); + wl_array_init(&b->unused_connectors); /* * KMS support for hardware planes cannot properly synchronize -- 2.14.3 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel