backend-drm: check that outputs and heads are in fact ours

As a first step towards heterogeneous outputs, ignore other backends'
heads and outputs. This is done by checking the destroy callbacks for
heads and outputs.

See: https://gitlab.freedesktop.org/wayland/weston/-/issues/268

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
dev
Philipp Zabel 4 years ago committed by Pekka Paalanen
parent aab722bb17
commit ffc011d6a3
  1. 16
      libweston/backend-drm/drm-internal.h
  2. 2
      libweston/backend-drm/drm-virtual.c
  3. 42
      libweston/backend-drm/drm.c
  4. 2
      libweston/backend-drm/kms.c
  5. 2
      libweston/backend-drm/state-propose.c

@ -584,15 +584,31 @@ struct drm_output {
submit_frame_cb virtual_submit_frame; submit_frame_cb virtual_submit_frame;
}; };
void
drm_head_destroy(struct weston_head *head_base);
static inline struct drm_head * static inline struct drm_head *
to_drm_head(struct weston_head *base) to_drm_head(struct weston_head *base)
{ {
if (base->backend_id != drm_head_destroy)
return NULL;
return container_of(base, struct drm_head, base); return container_of(base, struct drm_head, base);
} }
void
drm_output_destroy(struct weston_output *output_base);
void
drm_virtual_output_destroy(struct weston_output *output_base);
static inline struct drm_output * static inline struct drm_output *
to_drm_output(struct weston_output *base) to_drm_output(struct weston_output *base)
{ {
if (
#ifdef BUILD_DRM_VIRTUAL
base->destroy != drm_virtual_output_destroy &&
#endif
base->destroy != drm_output_destroy)
return NULL;
return container_of(base, struct drm_output, base); return container_of(base, struct drm_output, base);
} }

@ -245,7 +245,7 @@ drm_virtual_output_deinit(struct weston_output *base)
drm_virtual_crtc_destroy(output->crtc); drm_virtual_crtc_destroy(output->crtc);
} }
static void void
drm_virtual_output_destroy(struct weston_output *base) drm_virtual_output_destroy(struct weston_output *base)
{ {
struct drm_output *output = to_drm_output(base); struct drm_output *output = to_drm_output(base);

@ -164,9 +164,6 @@ drm_output_pageflip_timer_create(struct drm_output *output)
return 0; return 0;
} }
static void
drm_output_destroy(struct weston_output *output_base);
/** /**
* Returns true if the plane can be used on the given output for its current * Returns true if the plane can be used on the given output for its current
* repaint cycle. * repaint cycle.
@ -214,6 +211,8 @@ drm_head_find_by_connector(struct drm_backend *backend, uint32_t connector_id)
wl_list_for_each(base, wl_list_for_each(base,
&backend->compositor->head_list, compositor_link) { &backend->compositor->head_list, compositor_link) {
head = to_drm_head(base); head = to_drm_head(base);
if (!head)
continue;
if (head->connector.connector_id == connector_id) if (head->connector.connector_id == connector_id)
return head; return head;
} }
@ -451,6 +450,7 @@ drm_output_repaint(struct weston_output *output_base, pixman_region32_t *damage)
struct drm_pending_state *pending_state; struct drm_pending_state *pending_state;
struct drm_device *device; struct drm_device *device;
assert(output);
assert(!output->virtual); assert(!output->virtual);
device = output->device; device = output->device;
@ -689,8 +689,11 @@ drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo
struct drm_output *output = to_drm_output(output_base); struct drm_output *output = to_drm_output(output_base);
struct drm_device *device = output->device; struct drm_device *device = output->device;
struct drm_backend *b = device->backend; struct drm_backend *b = device->backend;
struct drm_mode *drm_mode = drm_output_choose_mode(output, mode); struct drm_mode *drm_mode;
assert(output);
drm_mode = drm_output_choose_mode(output, mode);
if (!drm_mode) { if (!drm_mode) {
weston_log("%s: invalid resolution %dx%d\n", weston_log("%s: invalid resolution %dx%d\n",
output_base->name, mode->width, mode->height); output_base->name, mode->width, mode->height);
@ -1053,6 +1056,7 @@ drm_set_dpms(struct weston_output *output_base, enum dpms_enum level)
struct drm_output_state *state; struct drm_output_state *state;
int ret; int ret;
assert(output);
assert(!output->virtual); assert(!output->virtual);
if (output->state_cur->dpms == level) if (output->state_cur->dpms == level)
@ -1491,6 +1495,8 @@ drm_output_pick_crtc(struct drm_output *output)
match = false; match = false;
wl_list_for_each(base, &compositor->head_list, compositor_link) { wl_list_for_each(base, &compositor->head_list, compositor_link) {
head = to_drm_head(base); head = to_drm_head(base);
if (!head)
continue;
if (head->base.output == &output->base) if (head->base.output == &output->base)
continue; continue;
@ -1808,6 +1814,7 @@ drm_output_enable(struct weston_output *base)
struct drm_backend *b = device->backend; struct drm_backend *b = device->backend;
int ret; int ret;
assert(output);
assert(!output->virtual); assert(!output->virtual);
if (output->gbm_format == DRM_FORMAT_INVALID) { if (output->gbm_format == DRM_FORMAT_INVALID) {
@ -1885,15 +1892,13 @@ drm_output_deinit(struct weston_output *base)
} }
} }
static void void
drm_head_destroy(struct drm_head *head);
static void
drm_output_destroy(struct weston_output *base) drm_output_destroy(struct weston_output *base)
{ {
struct drm_output *output = to_drm_output(base); struct drm_output *output = to_drm_output(base);
struct drm_device *device = output->device; struct drm_device *device = output->device;
assert(output);
assert(!output->virtual); assert(!output->virtual);
if (output->page_flip_pending || output->atomic_complete_pending) { if (output->page_flip_pending || output->atomic_complete_pending) {
@ -1927,6 +1932,7 @@ drm_output_disable(struct weston_output *base)
{ {
struct drm_output *output = to_drm_output(base); struct drm_output *output = to_drm_output(base);
assert(output);
assert(!output->virtual); assert(!output->virtual);
if (output->page_flip_pending || output->atomic_complete_pending) { if (output->page_flip_pending || output->atomic_complete_pending) {
@ -2197,6 +2203,8 @@ drm_head_create(struct drm_device *device, drmModeConnector *conn,
weston_head_init(&head->base, name); weston_head_init(&head->base, name);
free(name); free(name);
head->base.backend_id = drm_head_destroy;
ret = drm_head_update_info(head, conn); ret = drm_head_update_info(head, conn);
if (ret < 0) if (ret < 0)
goto err_update; goto err_update;
@ -2226,9 +2234,13 @@ err:
return -1; return -1;
} }
static void void
drm_head_destroy(struct drm_head *head) drm_head_destroy(struct weston_head *base)
{ {
struct drm_head *head = to_drm_head(base);
assert(head);
weston_head_release(&head->base); weston_head_release(&head->base);
drm_connector_fini(&head->connector); drm_connector_fini(&head->connector);
@ -2466,6 +2478,8 @@ drm_backend_update_connectors(struct drm_device *device,
wl_list_for_each_safe(base, base_next, wl_list_for_each_safe(base, base_next,
&b->compositor->head_list, compositor_link) { &b->compositor->head_list, compositor_link) {
head = to_drm_head(base); head = to_drm_head(base);
if (!head)
continue;
connector_id = head->connector.connector_id; connector_id = head->connector.connector_id;
if (head->connector.device != device) if (head->connector.device != device)
@ -2476,7 +2490,7 @@ drm_backend_update_connectors(struct drm_device *device,
weston_log("DRM: head '%s' (connector %d) disappeared.\n", weston_log("DRM: head '%s' (connector %d) disappeared.\n",
head->base.name, connector_id); head->base.name, connector_id);
drm_head_destroy(head); drm_head_destroy(base);
} }
/* Destroy writeback objects of writeback connectors that have /* Destroy writeback objects of writeback connectors that have
@ -2630,8 +2644,10 @@ drm_destroy(struct weston_compositor *ec)
wl_list_for_each_safe(crtc, crtc_tmp, &b->drm->crtc_list, link) wl_list_for_each_safe(crtc, crtc_tmp, &b->drm->crtc_list, link)
drm_crtc_destroy(crtc); drm_crtc_destroy(crtc);
wl_list_for_each_safe(base, next, &ec->head_list, compositor_link) wl_list_for_each_safe(base, next, &ec->head_list, compositor_link) {
drm_head_destroy(to_drm_head(base)); if (to_drm_head(base))
drm_head_destroy(base);
}
wl_list_for_each_safe(writeback, writeback_tmp, wl_list_for_each_safe(writeback, writeback_tmp,
&b->drm->writeback_connector_list, link) &b->drm->writeback_connector_list, link)

@ -487,6 +487,8 @@ drm_output_set_gamma(struct weston_output *output_base,
struct drm_output *output = to_drm_output(output_base); struct drm_output *output = to_drm_output(output_base);
struct drm_device *device = output->device; struct drm_device *device = output->device;
assert(output);
/* check */ /* check */
if (output_base->gamma_size != size) if (output_base->gamma_size != size)
return; return;

@ -926,6 +926,8 @@ drm_assign_planes(struct weston_output *output_base)
struct weston_plane *primary = &output_base->compositor->primary_plane; struct weston_plane *primary = &output_base->compositor->primary_plane;
enum drm_output_propose_state_mode mode = DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY; enum drm_output_propose_state_mode mode = DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY;
assert(output);
drm_debug(b, "\t[repaint] preparing state for output %s (%lu)\n", drm_debug(b, "\t[repaint] preparing state for output %s (%lu)\n",
output_base->name, (unsigned long) output_base->id); output_base->name, (unsigned long) output_base->id);

Loading…
Cancel
Save