diff --git a/libweston/backend-drm/drm-internal.h b/libweston/backend-drm/drm-internal.h index b0c5af86..833cf6e1 100644 --- a/libweston/backend-drm/drm-internal.h +++ b/libweston/backend-drm/drm-internal.h @@ -278,9 +278,6 @@ struct drm_backend { /* drm_crtc::link */ struct wl_list crtc_list; - /* CRTC IDs not used by any enabled output. */ - struct wl_array unused_crtcs; - bool sprites_are_broken; bool cursors_are_broken; diff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c index cd4639e8..ff6e9903 100644 --- a/libweston/backend-drm/drm.c +++ b/libweston/backend-drm/drm.c @@ -123,26 +123,6 @@ drm_backend_create_faked_zpos(struct drm_backend *b) } } -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 int pageflip_timeout(void *data) { /* @@ -1714,7 +1694,6 @@ drm_output_attach_crtc(struct drm_output *output) /* Reserve the CRTC for the output */ output->crtc->output = output; - wl_array_remove_uint32(&b->unused_crtcs, output->crtc->crtc_id); return 0; } @@ -1730,7 +1709,6 @@ drm_output_detach_crtc(struct drm_output *output) { struct drm_backend *b = to_drm_backend(output->base.compositor); struct drm_crtc *crtc = output->crtc; - uint32_t *unused; /* If the compositor is already shutting down, the planes have already * been destroyed. */ @@ -1757,9 +1735,6 @@ drm_output_detach_crtc(struct drm_output *output) } } - unused = wl_array_add(&b->unused_crtcs, sizeof(*unused)); - *unused = crtc->crtc_id; - /* Force resetting unused CRTCs */ b->state_invalid = true; @@ -1915,39 +1890,6 @@ drm_output_disable(struct weston_output *base) return 0; } -/** - * Update the list of unused connectors and CRTCs - * - * This keeps the unused_crtc 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_crtcs); - wl_array_init(&b->unused_crtcs); - - for (i = 0; i < resources->count_crtcs; i++) { - struct drm_output *output = NULL; - struct drm_crtc *crtc; - uint32_t *crtc_id; - - crtc = drm_crtc_find(b, resources->crtcs[i]); - if (crtc) - output = crtc->output; - - if (output && output->base.enabled) - continue; - - crtc_id = wl_array_add(&b->unused_crtcs, sizeof(*crtc_id)); - *crtc_id = resources->crtcs[i]; - } -} - /* * This function converts the protection status from drm values to * weston_hdcp_protection status. The drm values as read from the connector @@ -2274,8 +2216,6 @@ drm_backend_create_heads(struct drm_backend *b, struct udev_device *drm_device) } } - drm_backend_update_unused_outputs(b, resources); - drmModeFreeResources(resources); return 0; @@ -2332,8 +2272,6 @@ drm_backend_update_heads(struct drm_backend *b, struct udev_device *drm_device) drm_head_destroy(head); } - drm_backend_update_unused_outputs(b, resources); - drmModeFreeResources(resources); } @@ -2488,8 +2426,6 @@ drm_destroy(struct weston_compositor *ec) weston_launcher_destroy(ec->launcher); - wl_array_release(&b->unused_crtcs); - close(b->drm.fd); free(b->drm.filename); free(b); @@ -2902,7 +2838,6 @@ drm_backend_create(struct weston_compositor *compositor, b->state_invalid = true; b->drm.fd = -1; - wl_array_init(&b->unused_crtcs); b->compositor = compositor; b->use_pixman = config->use_pixman; diff --git a/libweston/backend-drm/kms.c b/libweston/backend-drm/kms.c index 0d0fed61..0f6993fa 100644 --- a/libweston/backend-drm/kms.c +++ b/libweston/backend-drm/kms.c @@ -1080,7 +1080,7 @@ drm_pending_state_apply_atomic(struct drm_pending_state *pending_state, if (b->state_invalid) { struct weston_head *head_base; struct drm_head *head; - uint32_t *unused; + struct drm_crtc *crtc; int err; drm_debug(b, "\t\t[atomic] previous state invalid; " @@ -1112,59 +1112,38 @@ drm_pending_state_apply_atomic(struct drm_pending_state *pending_state, ret = -1; } - wl_array_for_each(unused, &b->unused_crtcs) { - struct drm_property_info infos[WDRM_CRTC__COUNT]; + wl_list_for_each(crtc, &b->crtc_list, link) { struct drm_property_info *info; drmModeObjectProperties *props; uint64_t active; - memset(infos, 0, sizeof(infos)); + /* Ignore CRTCs that are in use */ + if (crtc->output) + continue; /* We can't emit a disable on a CRTC that's already * off, as the kernel will refuse to generate an event * for an off->off state and fail the commit. */ props = drmModeObjectGetProperties(b->drm.fd, - *unused, + crtc->crtc_id, DRM_MODE_OBJECT_CRTC); if (!props) { ret = -1; continue; } - drm_property_info_populate(b, crtc_props, infos, - WDRM_CRTC__COUNT, - props); - - info = &infos[WDRM_CRTC_ACTIVE]; + info = &crtc->props_crtc[WDRM_CRTC_ACTIVE]; active = drm_property_get_value(info, props, 0); drmModeFreeObjectProperties(props); - if (active == 0) { - drm_property_info_free(infos, WDRM_CRTC__COUNT); + if (active == 0) continue; - } drm_debug(b, "\t\t[atomic] disabling unused CRTC %lu\n", - (unsigned long) *unused); + (unsigned long) crtc->crtc_id); - drm_debug(b, "\t\t\t[CRTC:%lu] %lu (%s) -> 0\n", - (unsigned long) *unused, - (unsigned long) info->prop_id, info->name); - err = drmModeAtomicAddProperty(req, *unused, - info->prop_id, 0); - if (err <= 0) - ret = -1; - - info = &infos[WDRM_CRTC_MODE_ID]; - drm_debug(b, "\t\t\t[CRTC:%lu] %lu (%s) -> 0\n", - (unsigned long) *unused, - (unsigned long) info->prop_id, info->name); - err = drmModeAtomicAddProperty(req, *unused, - info->prop_id, 0); - if (err <= 0) - ret = -1; - - drm_property_info_free(infos, WDRM_CRTC__COUNT); + ret |= crtc_add_prop(req, crtc, WDRM_CRTC_ACTIVE, 0); + ret |= crtc_add_prop(req, crtc, WDRM_CRTC_MODE_ID, 0); } /* Disable all the planes; planes which are being used will @@ -1266,7 +1245,7 @@ drm_pending_state_apply(struct drm_pending_state *pending_state) { struct drm_backend *b = pending_state->backend; struct drm_output_state *output_state, *tmp; - uint32_t *unused; + struct drm_crtc *crtc; if (b->atomic_modeset) return drm_pending_state_apply_atomic(pending_state, @@ -1278,9 +1257,12 @@ drm_pending_state_apply(struct drm_pending_state *pending_state) * 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(crtc, &b->crtc_list, link) { + if (crtc->output) + continue; + drmModeSetCrtc(b->drm.fd, crtc->crtc_id, 0, 0, 0, + NULL, 0, NULL); + } } wl_list_for_each_safe(output_state, tmp, &pending_state->output_list, @@ -1322,7 +1304,7 @@ drm_pending_state_apply_sync(struct drm_pending_state *pending_state) { struct drm_backend *b = pending_state->backend; struct drm_output_state *output_state, *tmp; - uint32_t *unused; + struct drm_crtc *crtc; if (b->atomic_modeset) return drm_pending_state_apply_atomic(pending_state, @@ -1334,9 +1316,12 @@ drm_pending_state_apply_sync(struct drm_pending_state *pending_state) * 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(crtc, &b->crtc_list, link) { + if (crtc->output) + continue; + drmModeSetCrtc(b->drm.fd, crtc->crtc_id, 0, 0, 0, + NULL, 0, NULL); + } } wl_list_for_each_safe(output_state, tmp, &pending_state->output_list,