[PATCH weston v12 39/40] compositor-drm: Support plane IN_FORMATS
Pekka Paalanen
ppaalanen at gmail.com
Thu Sep 28 10:59:56 UTC 2017
On Tue, 26 Sep 2017 18:16:12 +0100
Daniel Stone <daniels at collabora.com> wrote:
> From: Sergi Granell <xerpi.g.12 at gmail.com>
>
> The per-plane IN_FORMATS property adds information about format
> modifiers; we can use these to both feed GBM with the set of modifiers
> we want to use for rendering, and also as an early-out test when we're
> trying to see if a FB will go on a particular plane.
>
> Signed-off-by: Sergi Granell <xerpi.g.12 at gmail.com>
> Reviewed-by: Daniel Stone <daniels at collabora.com>
> Signed-off-by: Daniel Stone <daniels at collabora.com>
> ---
> libweston/compositor-drm.c | 126 ++++++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 118 insertions(+), 8 deletions(-)
>
> diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
> index 111cb9e3..811adbbd 100644
> --- a/libweston/compositor-drm.c
> +++ b/libweston/compositor-drm.c
> @@ -83,6 +83,20 @@
> #define GBM_BO_USE_CURSOR GBM_BO_USE_CURSOR_64X64
> #endif
>
> +#ifdef HAVE_DRM_ATOMIC
> +static inline uint32_t *
> +formats_ptr(struct drm_format_modifier_blob *blob)
> +{
> + return (uint32_t *)(((char *)blob) + blob->formats_offset);
> +}
> +
> +static inline struct drm_format_modifier *
> +modifiers_ptr(struct drm_format_modifier_blob *blob)
> +{
> + return (struct drm_format_modifier *)(((char *)blob) + blob->modifiers_offset);
> +}
> +#endif
Hi,
a quick build test with libdrm 2.4.80 produces this:
CC libweston/drm_backend_la-compositor-drm.lo
/home/pq/git/weston/libweston/compositor-drm.c:88:20: warning: ‘struct drm_format_modifier_blob’ declared inside parameter list
formats_ptr(struct drm_format_modifier_blob *blob)
^
/home/pq/git/weston/libweston/compositor-drm.c:88:20: warning: its scope is only this definition or declaration, which is probably not what you want
/home/pq/git/weston/libweston/compositor-drm.c: In function ‘formats_ptr’:
/home/pq/git/weston/libweston/compositor-drm.c:90:43: error: dereferencing pointer to incomplete type
return (uint32_t *)(((char *)blob) + blob->formats_offset);
^
and a ton more. I suppose HAVE_DRM_ATOMIC check is not quite enough?
Looks like it should require libdrm 2.4.83.
Thanks,
pq
> +
> /**
> * Represents the values of an enum-type KMS property
> */
> @@ -127,6 +141,7 @@ enum wdrm_plane_property {
> WDRM_PLANE_CRTC_H,
> WDRM_PLANE_FB_ID,
> WDRM_PLANE_CRTC_ID,
> + WDRM_PLANE_IN_FORMATS,
> WDRM_PLANE__COUNT
> };
>
> @@ -168,6 +183,7 @@ static const struct drm_property_info plane_props[] = {
> [WDRM_PLANE_CRTC_H] = { .name = "CRTC_H", },
> [WDRM_PLANE_FB_ID] = { .name = "FB_ID", },
> [WDRM_PLANE_CRTC_ID] = { .name = "CRTC_ID", },
> + [WDRM_PLANE_IN_FORMATS] = { .name = "IN_FORMATS" },
> };
>
> /**
> @@ -397,7 +413,11 @@ struct drm_plane {
>
> struct wl_list link;
>
> - uint32_t formats[];
> + struct {
> + uint32_t format;
> + uint32_t count_modifiers;
> + uint64_t *modifiers;
> + } formats[];
> };
>
> struct drm_output {
> @@ -2811,7 +2831,19 @@ drm_output_prepare_overlay_view(struct drm_output_state *output_state,
>
> /* Check whether the format is supported */
> for (i = 0; i < p->count_formats; i++) {
> - if (p->formats[i] == fb->format->format)
> + unsigned int j;
> +
> + if (p->formats[i].format != fb->format->format)
> + continue;
> +
> + if (fb->modifier == DRM_FORMAT_MOD_INVALID)
> + break;
> +
> + for (j = 0; j < p->formats[i].count_modifiers; j++) {
> + if (p->formats[i].modifiers[j] == fb->modifier)
> + break;
> + }
> + if (j != p->formats[i].count_modifiers)
> break;
> }
> if (i == p->count_formats)
> @@ -3578,6 +3610,61 @@ init_pixman(struct drm_backend *b)
> return pixman_renderer_init(b->compositor);
> }
>
> +/**
> + * Populates the formats array, and the modifiers of each format for a drm_plane.
> + */
> +#ifdef HAVE_DRM_ATOMIC
> +static bool
> +populate_format_modifiers(struct drm_plane *plane, const drmModePlane *kplane,
> + uint32_t blob_id)
> +{
> + unsigned i, j;
> + drmModePropertyBlobRes *blob;
> + struct drm_format_modifier_blob *fmt_mod_blob;
> + uint32_t *blob_formats;
> + struct drm_format_modifier *blob_modifiers;
> +
> + blob = drmModeGetPropertyBlob(plane->backend->drm.fd, blob_id);
> + if (!blob)
> + return false;
> +
> + fmt_mod_blob = blob->data;
> + blob_formats = formats_ptr(fmt_mod_blob);
> + blob_modifiers = modifiers_ptr(fmt_mod_blob);
> +
> + assert(plane->count_formats == fmt_mod_blob->count_formats);
> +
> + for (i = 0; i < fmt_mod_blob->count_formats; i++) {
> + uint32_t count_modifiers = 0;
> + uint64_t *modifiers = NULL;
> +
> + for (j = 0; j < fmt_mod_blob->count_modifiers; j++) {
> + struct drm_format_modifier *mod = &blob_modifiers[j];
> +
> + if ((i < mod->offset) || (i > mod->offset + 63))
> + continue;
> + if (!(mod->formats & (1 << (i - mod->offset))))
> + continue;
> +
> + modifiers = realloc(modifiers, (count_modifiers + 1) * sizeof(modifiers[0]));
> + if (!modifiers) {
> + drmModeFreePropertyBlob(blob);
> + return false;
> + }
> + modifiers[count_modifiers++] = mod->modifier;
> + }
> +
> + plane->formats[i].format = blob_formats[i];
> + plane->formats[i].modifiers = modifiers;
> + plane->formats[i].count_modifiers = count_modifiers;
> + }
> +
> + drmModeFreePropertyBlob(blob);
> +
> + return true;
> +}
> +#endif
> +
> /**
> * Create a drm_plane for a hardware plane
> *
> @@ -3607,25 +3694,27 @@ drm_plane_create(struct drm_backend *b, const drmModePlane *kplane,
> {
> struct drm_plane *plane;
> drmModeObjectProperties *props;
> - int num_formats = (kplane) ? kplane->count_formats : 1;
> + uint32_t num_formats = (kplane) ? kplane->count_formats : 1;
>
> plane = zalloc(sizeof(*plane) +
> - (sizeof(uint32_t) * num_formats));
> + (sizeof(plane->formats[0]) * num_formats));
> if (!plane) {
> weston_log("%s: out of memory\n", __func__);
> return NULL;
> }
>
> plane->backend = b;
> + plane->count_formats = num_formats;
> plane->state_cur = drm_plane_state_alloc(NULL, plane);
> plane->state_cur->complete = true;
>
> if (kplane) {
> +#ifdef HAVE_DRM_ATOMIC
> + uint32_t blob_id;
> +#endif
> +
> plane->possible_crtcs = kplane->possible_crtcs;
> plane->plane_id = kplane->plane_id;
> - plane->count_formats = kplane->count_formats;
> - memcpy(plane->formats, kplane->formats,
> - kplane->count_formats * sizeof(kplane->formats[0]));
>
> props = drmModeObjectGetProperties(b->drm.fd, kplane->plane_id,
> DRM_MODE_OBJECT_PLANE);
> @@ -3640,13 +3729,34 @@ drm_plane_create(struct drm_backend *b, const drmModePlane *kplane,
> drm_property_get_value(&plane->props[WDRM_PLANE_TYPE],
> props,
> WDRM_PLANE_TYPE__COUNT);
> +
> +#ifdef HAVE_DRM_ATOMIC
> + blob_id = drm_property_get_value(&plane->props[WDRM_PLANE_IN_FORMATS],
> + props,
> + 0);
> + if (blob_id) {
> + if (!populate_format_modifiers(plane, kplane, blob_id)) {
> + weston_log("%s: out of memory\n", __func__);
> + drm_property_info_free(plane->props, WDRM_PLANE__COUNT);
> + drmModeFreeObjectProperties(props);
> + free(plane);
> + return NULL;
> + }
> + } else
> +#endif
> + {
> + uint32_t i;
> + for (i = 0; i < kplane->count_formats; i++)
> + plane->formats[i].format = kplane->formats[i];
> + }
> +
> drmModeFreeObjectProperties(props);
> }
> else {
> plane->possible_crtcs = (1 << output->pipe);
> plane->plane_id = 0;
> plane->count_formats = 1;
> - plane->formats[0] = format;
> + plane->formats[0].format = format;
> plane->type = type;
> }
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/wayland-devel/attachments/20170928/a6bab30f/attachment.sig>
More information about the wayland-devel
mailing list