backend-drm: start to use weston_drm_format in drm_plane

In commit "libweston: add struct weston_drm_format" struct
weston_drm_format and its helper functions were added to libweston.
Also, unit tests for this API have been added in commit "tests: add unit
tests for struct weston_drm_format".

Start to use this API in the DRM-backend, as it enhances the code by
avoiding repetition and ensuring correctness.

Signed-off-by: Scott Anderson <scott.anderson@collabora.com>
Co-authored-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
This commit is contained in:
Scott Anderson 2021-02-01 15:46:33 -03:00 committed by Daniel Stone
parent 859e3f220d
commit 7466309c12
6 changed files with 70 additions and 81 deletions

View file

@ -181,6 +181,10 @@ err:
int
drm_output_init_egl(struct drm_output *output, struct drm_backend *b)
{
struct weston_drm_format *fmt;
const uint64_t *modifiers;
unsigned int num_modifiers;
uint32_t format[2] = {
output->gbm_format,
fallback_format_for(output->gbm_format),
@ -191,30 +195,26 @@ drm_output_init_egl(struct drm_output *output, struct drm_backend *b)
};
struct weston_mode *mode = output->base.current_mode;
struct drm_plane *plane = output->scanout_plane;
unsigned int i;
assert(output->gbm_surface == NULL);
for (i = 0; i < plane->count_formats; i++) {
if (plane->formats[i].format == output->gbm_format)
break;
}
if (i == plane->count_formats) {
fmt = weston_drm_format_array_find_format(&plane->formats, output->gbm_format);
if (!fmt) {
weston_log("format 0x%x not supported by output %s\n",
output->gbm_format, output->base.name);
return -1;
}
#ifdef HAVE_GBM_MODIFIERS
if (plane->formats[i].count_modifiers > 0) {
modifiers = weston_drm_format_get_modifiers(fmt, &num_modifiers);
if (num_modifiers > 0) {
output->gbm_surface =
gbm_surface_create_with_modifiers(b->gbm,
mode->width,
mode->height,
output->gbm_format,
plane->formats[i].modifiers,
plane->formats[i].count_modifiers);
modifiers,
num_modifiers);
}
/* If allocating with modifiers fails, try again without. This can

View file

@ -435,7 +435,6 @@ struct drm_plane {
uint32_t possible_crtcs;
uint32_t plane_id;
uint32_t count_formats;
struct drm_property_info props[WDRM_PLANE__COUNT];
@ -447,11 +446,7 @@ struct drm_plane {
struct wl_list link;
struct {
uint32_t format;
uint32_t count_modifiers;
uint64_t *modifiers;
} formats[];
struct weston_drm_format_array formats;
};
struct drm_connector {

View file

@ -93,9 +93,10 @@ static struct drm_plane *
drm_virtual_plane_create(struct drm_backend *b, struct drm_output *output)
{
struct drm_plane *plane;
struct weston_drm_format *fmt;
int ret;
/* num of formats is one */
plane = zalloc(sizeof(*plane) + sizeof(plane->formats[0]));
plane = zalloc(sizeof(*plane));
if (!plane) {
weston_log("%s: out of memory\n", __func__);
return NULL;
@ -105,21 +106,28 @@ drm_virtual_plane_create(struct drm_backend *b, struct drm_output *output)
plane->backend = b;
plane->state_cur = drm_plane_state_alloc(NULL, plane);
plane->state_cur->complete = true;
plane->formats[0].format = output->gbm_format;
plane->count_formats = 1;
weston_drm_format_array_init(&plane->formats);
fmt = weston_drm_format_array_add_format(&plane->formats, output->gbm_format);
if (!fmt)
goto err;
if ((output->gbm_bo_flags & GBM_BO_USE_LINEAR) && b->fb_modifiers) {
uint64_t *modifiers = zalloc(sizeof *modifiers);
if (modifiers) {
*modifiers = DRM_FORMAT_MOD_LINEAR;
plane->formats[0].modifiers = modifiers;
plane->formats[0].count_modifiers = 1;
}
ret = weston_drm_format_add_modifier(fmt, DRM_FORMAT_MOD_LINEAR);
if (ret < 0)
goto err;
}
weston_plane_init(&plane->base, b->compositor, 0, 0);
wl_list_insert(&b->plane_list, &plane->link);
return plane;
err:
drm_plane_state_free(plane->state_cur, true);
weston_drm_format_array_fini(&plane->formats);
free(plane);
return NULL;
}
/**
@ -133,8 +141,7 @@ drm_virtual_plane_destroy(struct drm_plane *plane)
drm_plane_state_free(plane->state_cur, true);
weston_plane_release(&plane->base);
wl_list_remove(&plane->link);
if (plane->formats[0].modifiers)
free(plane->formats[0].modifiers);
weston_drm_format_array_fini(&plane->formats);
free(plane);
}

View file

@ -760,20 +760,19 @@ drm_plane_create(struct drm_backend *b, const drmModePlane *kplane,
struct drm_plane *plane;
drmModeObjectProperties *props;
uint64_t *zpos_range_values;
uint32_t num_formats = (kplane) ? kplane->count_formats : 1;
plane = zalloc(sizeof(*plane) +
(sizeof(plane->formats[0]) * num_formats));
plane = zalloc(sizeof(*plane));
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;
weston_drm_format_array_init(&plane->formats);
if (kplane) {
plane->possible_crtcs = kplane->possible_crtcs;
plane->plane_id = kplane->plane_id;
@ -814,11 +813,11 @@ drm_plane_create(struct drm_backend *b, const drmModePlane *kplane,
else {
plane->possible_crtcs = (1 << output->crtc->pipe);
plane->plane_id = 0;
plane->count_formats = 1;
plane->formats[0].format = format;
plane->type = type;
plane->zpos_max = DRM_PLANE_ZPOS_INVALID_PLANE;
plane->zpos_min = DRM_PLANE_ZPOS_INVALID_PLANE;
if (!weston_drm_format_array_add_format(&plane->formats, format))
goto err;
}
if (plane->type == WDRM_PLANE_TYPE__COUNT)
@ -845,6 +844,7 @@ drm_plane_create(struct drm_backend *b, const drmModePlane *kplane,
err_props:
drm_property_info_free(plane->props, WDRM_PLANE__COUNT);
err:
weston_drm_format_array_fini(&plane->formats);
drm_plane_state_free(plane->state_cur, true);
free(plane);
return NULL;
@ -945,6 +945,7 @@ drm_plane_destroy(struct drm_plane *plane)
drm_plane_state_free(plane->state_cur, true);
drm_property_info_free(plane->props, WDRM_PLANE__COUNT);
weston_plane_release(&plane->base);
weston_drm_format_array_fini(&plane->formats);
wl_list_remove(&plane->link);
free(plane);
}

View file

@ -433,12 +433,14 @@ drm_plane_populate_formats(struct drm_plane *plane, const drmModePlane *kplane,
const drmModeObjectProperties *props,
const bool use_modifiers)
{
unsigned i;
drmModePropertyBlobRes *blob;
unsigned i, j;
drmModePropertyBlobRes *blob = NULL;
struct drm_format_modifier_blob *fmt_mod_blob;
struct drm_format_modifier *blob_modifiers;
uint32_t *blob_formats;
uint32_t blob_id;
struct weston_drm_format *fmt;
int ret = 0;
if (!use_modifiers)
goto fallback;
@ -457,20 +459,15 @@ drm_plane_populate_formats(struct drm_plane *plane, const drmModePlane *kplane,
blob_formats = formats_ptr(fmt_mod_blob);
blob_modifiers = modifiers_ptr(fmt_mod_blob);
if (plane->count_formats != fmt_mod_blob->count_formats) {
weston_log("DRM backend: format count differs between "
"plane (%d) and IN_FORMATS (%d)\n",
plane->count_formats,
fmt_mod_blob->count_formats);
weston_log("This represents a kernel bug; Weston is "
"unable to continue.\n");
abort();
}
assert(kplane->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;
unsigned j;
fmt = weston_drm_format_array_add_format(&plane->formats,
blob_formats[i]);
if (!fmt) {
ret = -1;
goto out;
}
for (j = 0; j < fmt_mod_blob->count_modifiers; j++) {
struct drm_format_modifier *mod = &blob_modifiers[j];
@ -480,38 +477,33 @@ drm_plane_populate_formats(struct drm_plane *plane, const drmModePlane *kplane,
if (!(mod->formats & (1 << (i - mod->offset))))
continue;
modifiers = realloc(modifiers,
(count_modifiers + 1) *
sizeof(modifiers[0]));
assert(modifiers);
modifiers[count_modifiers++] = mod->modifier;
ret = weston_drm_format_add_modifier(fmt, mod->modifier);
if (ret < 0)
goto out;
}
if (count_modifiers == 0) {
modifiers = malloc(sizeof(*modifiers));
*modifiers = DRM_FORMAT_MOD_LINEAR;
count_modifiers = 1;
if (fmt->modifiers.size == 0) {
ret = weston_drm_format_add_modifier(fmt, DRM_FORMAT_MOD_LINEAR);
if (ret < 0)
goto out;
}
plane->formats[i].format = blob_formats[i];
plane->formats[i].modifiers = modifiers;
plane->formats[i].count_modifiers = count_modifiers;
}
out:
drmModeFreePropertyBlob(blob);
return 0;
return ret;
fallback:
/* No IN_FORMATS blob available, so just use the old. */
assert(plane->count_formats == kplane->count_formats);
for (i = 0; i < kplane->count_formats; i++) {
plane->formats[i].format = kplane->formats[i];
plane->formats[i].modifiers = malloc(sizeof(uint64_t));
plane->formats[i].modifiers[0] = DRM_FORMAT_MOD_LINEAR;
plane->formats[i].count_modifiers = 1;
fmt = weston_drm_format_array_add_format(&plane->formats,
kplane->formats[i]);
if (!fmt)
return -1;
ret = weston_drm_format_add_modifier(fmt, DRM_FORMAT_MOD_LINEAR);
if (ret < 0)
return -1;
}
return 0;
}

View file

@ -129,25 +129,19 @@ drm_output_plane_has_valid_format(struct drm_plane *plane,
struct drm_fb *fb)
{
struct drm_backend *b = plane->backend;
unsigned int i;
struct weston_drm_format *fmt;
if (!fb)
return false;
/* Check whether the format is supported */
for (i = 0; i < plane->count_formats; i++) {
unsigned int j;
if (plane->formats[i].format != fb->format->format)
continue;
fmt = weston_drm_format_array_find_format(&plane->formats,
fb->format->format);
if (fmt) {
if (fb->modifier == DRM_FORMAT_MOD_INVALID)
return true;
for (j = 0; j < plane->formats[i].count_modifiers; j++) {
if (plane->formats[i].modifiers[j] == fb->modifier)
return true;
}
if (weston_drm_format_has_modifier(fmt, fb->modifier))
return true;
}
drm_debug(b, "\t\t\t\t[%s] not placing view on %s: "