mirror of
https://gitlab.freedesktop.org/wayland/weston
synced 2024-10-15 19:43:38 +00:00
compositor-drm: start migration to head-based output API
Hook up the libweston facing head-based output API by introducing struct drm_head, but leave it as a fake so that members can be migrated in pieces in follow-up patches. The DRM backend continues to create an output for each connected connector only, and during output creation it also creates a drm_head for it. This allows it to pretend it supports the head-based output API as long as there is only one head per output ever attached. create_output callback is fake, it will only look up the existing drm_output by the head name. Clones are not yet supported, hence max is defined to 1. This unfortunately introduces some temporary code that will be revomed later, but seems to be necessary to avoid a single big patch. v6: - add missing drm_head_destroy() call Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
This commit is contained in:
parent
c80e954123
commit
c112f00bd1
|
@ -83,6 +83,8 @@
|
|||
#define GBM_BO_USE_CURSOR GBM_BO_USE_CURSOR_64X64
|
||||
#endif
|
||||
|
||||
#define MAX_CLONED_CONNECTORS 1
|
||||
|
||||
/**
|
||||
* Represents the values of an enum-type KMS property
|
||||
*/
|
||||
|
@ -400,6 +402,13 @@ struct drm_plane {
|
|||
uint32_t formats[];
|
||||
};
|
||||
|
||||
struct drm_head {
|
||||
struct weston_head base;
|
||||
struct drm_backend *backend;
|
||||
|
||||
struct drm_output *output; /* XXX: temporary */
|
||||
};
|
||||
|
||||
struct drm_output {
|
||||
struct weston_output base;
|
||||
drmModeConnector *connector;
|
||||
|
@ -475,6 +484,12 @@ wl_array_remove_uint32(struct wl_array *array, uint32_t elm)
|
|||
}
|
||||
}
|
||||
|
||||
static inline struct drm_head *
|
||||
to_drm_head(struct weston_head *base)
|
||||
{
|
||||
return container_of(base, struct drm_head, base);
|
||||
}
|
||||
|
||||
static inline struct drm_output *
|
||||
to_drm_output(struct weston_output *base)
|
||||
{
|
||||
|
@ -4393,6 +4408,16 @@ setup_output_seat_constraint(struct drm_backend *b,
|
|||
}
|
||||
}
|
||||
|
||||
static int
|
||||
drm_output_attach_head(struct weston_output *output_base,
|
||||
struct weston_head *head_base)
|
||||
{
|
||||
if (wl_list_length(&output_base->head_list) >= MAX_CLONED_CONNECTORS)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_gbm_format(const char *s, uint32_t default_value, uint32_t *gbm_format)
|
||||
{
|
||||
|
@ -4810,11 +4835,15 @@ drm_output_deinit(struct weston_output *base)
|
|||
b->state_invalid = true;
|
||||
}
|
||||
|
||||
static void
|
||||
drm_head_destroy(struct drm_head *head);
|
||||
|
||||
static void
|
||||
drm_output_destroy(struct weston_output *base)
|
||||
{
|
||||
struct drm_output *output = to_drm_output(base);
|
||||
struct drm_backend *b = to_drm_backend(base->compositor);
|
||||
struct weston_head *head = weston_output_get_first_head(base);
|
||||
|
||||
if (output->page_flip_pending || output->vblank_pending ||
|
||||
output->atomic_complete_pending) {
|
||||
|
@ -4845,6 +4874,10 @@ drm_output_destroy(struct weston_output *base)
|
|||
drm_output_state_free(output->state_cur);
|
||||
|
||||
free(output);
|
||||
|
||||
/* XXX: temporary */
|
||||
if (head)
|
||||
drm_head_destroy(to_drm_head(head));
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -4868,6 +4901,19 @@ drm_output_disable(struct weston_output *base)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct weston_output *
|
||||
drm_output_create(struct weston_compositor *compositor, const char *name)
|
||||
{
|
||||
struct drm_head *head;
|
||||
|
||||
/* XXX: Temporary until we can have heads without an output */
|
||||
wl_list_for_each(head, &compositor->head_list, base.compositor_link)
|
||||
if (strcmp(name, head->base.name) == 0)
|
||||
return &head->output->base;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the list of unused connectors and CRTCs
|
||||
*
|
||||
|
@ -4913,6 +4959,71 @@ drm_backend_update_unused_outputs(struct drm_backend *b, drmModeRes *resources)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Weston head for a connector
|
||||
*
|
||||
* Given a DRM connector, create a matching drm_head structure and add it
|
||||
* to Weston's head list.
|
||||
*
|
||||
* @param b Weston backend structure
|
||||
* @param connector_id DRM connector ID for the head
|
||||
* @param drm_device udev device pointer
|
||||
* @returns The new head, or NULL on failure.
|
||||
*/
|
||||
static struct drm_head *
|
||||
drm_head_create(struct drm_backend *backend, uint32_t connector_id,
|
||||
struct udev_device *drm_device)
|
||||
{
|
||||
struct drm_head *head;
|
||||
drmModeConnector *connector;
|
||||
char *name;
|
||||
|
||||
head = zalloc(sizeof *head);
|
||||
if (!head)
|
||||
return NULL;
|
||||
|
||||
connector = drmModeGetConnector(backend->drm.fd, connector_id);
|
||||
if (!connector)
|
||||
goto err_alloc;
|
||||
|
||||
name = make_connector_name(connector);
|
||||
if (!name)
|
||||
goto err_alloc;
|
||||
|
||||
weston_head_init(&head->base, name);
|
||||
free(name);
|
||||
|
||||
head->backend = backend;
|
||||
|
||||
/* Unknown connection status is assumed disconnected. */
|
||||
weston_head_set_connection_status(&head->base,
|
||||
connector->connection == DRM_MODE_CONNECTED);
|
||||
|
||||
weston_compositor_add_head(backend->compositor, &head->base);
|
||||
drmModeFreeConnector(connector);
|
||||
|
||||
weston_log("DRM: found head '%s', connector %d %s.\n",
|
||||
head->base.name, connector_id,
|
||||
head->base.connected ? "connected" : "disconnected");
|
||||
|
||||
return head;
|
||||
|
||||
err_alloc:
|
||||
if (connector)
|
||||
drmModeFreeConnector(connector);
|
||||
|
||||
free(head);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
drm_head_destroy(struct drm_head *head)
|
||||
{
|
||||
weston_head_release(&head->base);
|
||||
free(head);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Weston output structure
|
||||
*
|
||||
|
@ -4933,7 +5044,7 @@ create_output_for_connector(struct drm_backend *b,
|
|||
struct udev_device *drm_device)
|
||||
{
|
||||
struct drm_output *output;
|
||||
struct weston_head *head;
|
||||
struct drm_head *head;
|
||||
drmModeObjectPropertiesPtr props;
|
||||
struct drm_mode *drm_mode;
|
||||
char *name;
|
||||
|
@ -4956,9 +5067,16 @@ create_output_for_connector(struct drm_backend *b,
|
|||
weston_output_init(&output->base, b->compositor, name);
|
||||
free(name);
|
||||
|
||||
/* XXX: temporary */
|
||||
head = drm_head_create(b, connector->connector_id, drm_device);
|
||||
if (!head)
|
||||
abort();
|
||||
head->output = output;
|
||||
|
||||
output->base.enable = drm_output_enable;
|
||||
output->base.destroy = drm_output_destroy;
|
||||
output->base.disable = drm_output_disable;
|
||||
output->base.attach_head = drm_output_attach_head;
|
||||
|
||||
output->destroy_pending = 0;
|
||||
output->disable_pending = 0;
|
||||
|
@ -4974,23 +5092,22 @@ create_output_for_connector(struct drm_backend *b,
|
|||
}
|
||||
drm_property_info_populate(b, connector_props, output->props_conn,
|
||||
WDRM_CONNECTOR__COUNT, props);
|
||||
head = &output->base.head;
|
||||
find_and_parse_output_edid(b, output, props,
|
||||
&make, &model, &serial_number);
|
||||
weston_head_set_monitor_strings(head, make, model, serial_number);
|
||||
weston_head_set_subpixel(head,
|
||||
weston_head_set_monitor_strings(&head->base, make, model, serial_number);
|
||||
weston_head_set_subpixel(&head->base,
|
||||
drm_subpixel_to_wayland(output->connector->subpixel));
|
||||
|
||||
drmModeFreeObjectProperties(props);
|
||||
|
||||
if (output->connector->connector_type == DRM_MODE_CONNECTOR_LVDS ||
|
||||
output->connector->connector_type == DRM_MODE_CONNECTOR_eDP)
|
||||
weston_head_set_internal(head);
|
||||
weston_head_set_internal(&head->base);
|
||||
|
||||
if (drm_output_init_gamma_size(output) < 0)
|
||||
goto err_output;
|
||||
|
||||
weston_head_set_physical_size(head, output->connector->mmWidth,
|
||||
weston_head_set_physical_size(&head->base, output->connector->mmWidth,
|
||||
output->connector->mmHeight);
|
||||
|
||||
output->state_cur = drm_output_state_alloc(output, NULL);
|
||||
|
@ -5008,6 +5125,7 @@ create_output_for_connector(struct drm_backend *b,
|
|||
return 0;
|
||||
|
||||
err_output:
|
||||
drm_head_destroy(head);
|
||||
drm_output_destroy(&output->base);
|
||||
return -1;
|
||||
/* no fallthrough! */
|
||||
|
@ -5189,6 +5307,7 @@ static void
|
|||
drm_destroy(struct weston_compositor *ec)
|
||||
{
|
||||
struct drm_backend *b = to_drm_backend(ec);
|
||||
struct weston_head *base, *next;
|
||||
|
||||
udev_input_destroy(&b->input);
|
||||
|
||||
|
@ -5201,6 +5320,9 @@ drm_destroy(struct weston_compositor *ec)
|
|||
|
||||
weston_compositor_shutdown(ec);
|
||||
|
||||
wl_list_for_each_safe(base, next, &ec->head_list, compositor_link)
|
||||
drm_head_destroy(to_drm_head(base));
|
||||
|
||||
if (b->gbm)
|
||||
gbm_device_destroy(b->gbm);
|
||||
|
||||
|
@ -5718,6 +5840,7 @@ drm_backend_create(struct weston_compositor *compositor,
|
|||
b->base.repaint_begin = drm_repaint_begin;
|
||||
b->base.repaint_flush = drm_repaint_flush;
|
||||
b->base.repaint_cancel = drm_repaint_cancel;
|
||||
b->base.create_output = drm_output_create;
|
||||
|
||||
weston_setup_vt_switch_bindings(compositor);
|
||||
|
||||
|
|
Loading…
Reference in a new issue