mirror of
https://gitlab.freedesktop.org/wayland/weston
synced 2024-09-06 18:05:39 +00:00
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:
parent
859e3f220d
commit
7466309c12
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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: "
|
||||
|
|
Loading…
Reference in a new issue