drm-backend: drop unused_crtcs from struct drm_backend

Now that we have a CRTC list in the DRM-backend, we can
iterate through it and look for the CRTCs that do not have
assigned outputs in order to find unused CRTCS.

So we can drop unused_crtcs from struct drm_backend and also
drop the functions drm_backend_update_unused_outputs() and
wl_array_remove_uint32().

Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
dev
Leandro Ribeiro 4 years ago
parent b00d1a2efb
commit 744c0cbb32
  1. 3
      libweston/backend-drm/drm-internal.h
  2. 65
      libweston/backend-drm/drm.c
  3. 65
      libweston/backend-drm/kms.c

@ -278,9 +278,6 @@ struct drm_backend {
/* drm_crtc::link */ /* drm_crtc::link */
struct wl_list crtc_list; struct wl_list crtc_list;
/* CRTC IDs not used by any enabled output. */
struct wl_array unused_crtcs;
bool sprites_are_broken; bool sprites_are_broken;
bool cursors_are_broken; bool cursors_are_broken;

@ -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 static int
pageflip_timeout(void *data) { pageflip_timeout(void *data) {
/* /*
@ -1714,7 +1694,6 @@ drm_output_attach_crtc(struct drm_output *output)
/* Reserve the CRTC for the output */ /* Reserve the CRTC for the output */
output->crtc->output = output; output->crtc->output = output;
wl_array_remove_uint32(&b->unused_crtcs, output->crtc->crtc_id);
return 0; 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_backend *b = to_drm_backend(output->base.compositor);
struct drm_crtc *crtc = output->crtc; struct drm_crtc *crtc = output->crtc;
uint32_t *unused;
/* If the compositor is already shutting down, the planes have already /* If the compositor is already shutting down, the planes have already
* been destroyed. */ * 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 */ /* Force resetting unused CRTCs */
b->state_invalid = true; b->state_invalid = true;
@ -1915,39 +1890,6 @@ drm_output_disable(struct weston_output *base)
return 0; 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 * This function converts the protection status from drm values to
* weston_hdcp_protection status. The drm values as read from the connector * 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); drmModeFreeResources(resources);
return 0; return 0;
@ -2332,8 +2272,6 @@ drm_backend_update_heads(struct drm_backend *b, struct udev_device *drm_device)
drm_head_destroy(head); drm_head_destroy(head);
} }
drm_backend_update_unused_outputs(b, resources);
drmModeFreeResources(resources); drmModeFreeResources(resources);
} }
@ -2488,8 +2426,6 @@ drm_destroy(struct weston_compositor *ec)
weston_launcher_destroy(ec->launcher); weston_launcher_destroy(ec->launcher);
wl_array_release(&b->unused_crtcs);
close(b->drm.fd); close(b->drm.fd);
free(b->drm.filename); free(b->drm.filename);
free(b); free(b);
@ -2902,7 +2838,6 @@ drm_backend_create(struct weston_compositor *compositor,
b->state_invalid = true; b->state_invalid = true;
b->drm.fd = -1; b->drm.fd = -1;
wl_array_init(&b->unused_crtcs);
b->compositor = compositor; b->compositor = compositor;
b->use_pixman = config->use_pixman; b->use_pixman = config->use_pixman;

@ -1080,7 +1080,7 @@ drm_pending_state_apply_atomic(struct drm_pending_state *pending_state,
if (b->state_invalid) { if (b->state_invalid) {
struct weston_head *head_base; struct weston_head *head_base;
struct drm_head *head; struct drm_head *head;
uint32_t *unused; struct drm_crtc *crtc;
int err; int err;
drm_debug(b, "\t\t[atomic] previous state invalid; " 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; ret = -1;
} }
wl_array_for_each(unused, &b->unused_crtcs) { wl_list_for_each(crtc, &b->crtc_list, link) {
struct drm_property_info infos[WDRM_CRTC__COUNT];
struct drm_property_info *info; struct drm_property_info *info;
drmModeObjectProperties *props; drmModeObjectProperties *props;
uint64_t active; 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 /* We can't emit a disable on a CRTC that's already
* off, as the kernel will refuse to generate an event * off, as the kernel will refuse to generate an event
* for an off->off state and fail the commit. * for an off->off state and fail the commit.
*/ */
props = drmModeObjectGetProperties(b->drm.fd, props = drmModeObjectGetProperties(b->drm.fd,
*unused, crtc->crtc_id,
DRM_MODE_OBJECT_CRTC); DRM_MODE_OBJECT_CRTC);
if (!props) { if (!props) {
ret = -1; ret = -1;
continue; continue;
} }
drm_property_info_populate(b, crtc_props, infos, info = &crtc->props_crtc[WDRM_CRTC_ACTIVE];
WDRM_CRTC__COUNT,
props);
info = &infos[WDRM_CRTC_ACTIVE];
active = drm_property_get_value(info, props, 0); active = drm_property_get_value(info, props, 0);
drmModeFreeObjectProperties(props); drmModeFreeObjectProperties(props);
if (active == 0) { if (active == 0)
drm_property_info_free(infos, WDRM_CRTC__COUNT);
continue; continue;
}
drm_debug(b, "\t\t[atomic] disabling unused CRTC %lu\n", 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", ret |= crtc_add_prop(req, crtc, WDRM_CRTC_ACTIVE, 0);
(unsigned long) *unused, ret |= crtc_add_prop(req, crtc, WDRM_CRTC_MODE_ID, 0);
(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);
} }
/* Disable all the planes; planes which are being used will /* 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_backend *b = pending_state->backend;
struct drm_output_state *output_state, *tmp; struct drm_output_state *output_state, *tmp;
uint32_t *unused; struct drm_crtc *crtc;
if (b->atomic_modeset) if (b->atomic_modeset)
return drm_pending_state_apply_atomic(pending_state, 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 * disable all the CRTCs we aren't using. This also disables
* all connectors on these CRTCs, so we don't need to do that * all connectors on these CRTCs, so we don't need to do that
* separately with the pre-atomic API. */ * separately with the pre-atomic API. */
wl_array_for_each(unused, &b->unused_crtcs) wl_list_for_each(crtc, &b->crtc_list, link) {
drmModeSetCrtc(b->drm.fd, *unused, 0, 0, 0, NULL, 0, if (crtc->output)
NULL); 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, 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_backend *b = pending_state->backend;
struct drm_output_state *output_state, *tmp; struct drm_output_state *output_state, *tmp;
uint32_t *unused; struct drm_crtc *crtc;
if (b->atomic_modeset) if (b->atomic_modeset)
return drm_pending_state_apply_atomic(pending_state, 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 * disable all the CRTCs we aren't using. This also disables
* all connectors on these CRTCs, so we don't need to do that * all connectors on these CRTCs, so we don't need to do that
* separately with the pre-atomic API. */ * separately with the pre-atomic API. */
wl_array_for_each(unused, &b->unused_crtcs) wl_list_for_each(crtc, &b->crtc_list, link) {
drmModeSetCrtc(b->drm.fd, *unused, 0, 0, 0, NULL, 0, if (crtc->output)
NULL); 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, wl_list_for_each_safe(output_state, tmp, &pending_state->output_list,

Loading…
Cancel
Save