compositor-drm: Use GBM modifier API
Now that we collect information about which modifiers are supported for KMS display, and are able to create KMS framebuffers with modifiers, begin using the modifier-aware GBM API. Client buffers from dmabuf already store multi-plane and modifier information into drm_fb. Extend this to drm_fb_get_from_bo(), used for wl_buffer, cursor, and gbm_surface buffers. wl_buffer buffers should by convention not require modifiers. Cursor buffers must not require modifiers, as they should be linear. Prior to this patch, GBM buffers must have been single-planar, and able to used without explicitly naming modifiers. Using gbm_surface_create_with_modifiers allows us to pass the list of modifiers acceptable to KMS for scanout to GBM, so it can allocate multi-planar buffers or those which are otherwise only addressible with modifiers. On platforms supporting and preferring modifiers for scanout, this means that the gbm_bos we get from our scanout surface need to use the extended API to query multiple planes, offsets, modifiers, etc. Signed-off-by: Daniel Stone <daniels@collabora.com> Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Tested-by: Emre Ucan <eucan@de.adit-jv.com>
This commit is contained in:
@@ -215,6 +215,9 @@ if test x$enable_drm_compositor = xyes; then
|
|||||||
PKG_CHECK_MODULES(DRM_COMPOSITOR_FORMATS_BLOB, [libdrm >= 2.4.83],
|
PKG_CHECK_MODULES(DRM_COMPOSITOR_FORMATS_BLOB, [libdrm >= 2.4.83],
|
||||||
[AC_DEFINE([HAVE_DRM_FORMATS_BLOB], 1, [libdrm supports modifier advertisement])],
|
[AC_DEFINE([HAVE_DRM_FORMATS_BLOB], 1, [libdrm supports modifier advertisement])],
|
||||||
[AC_MSG_WARN([libdrm does not support modifier advertisement])])
|
[AC_MSG_WARN([libdrm does not support modifier advertisement])])
|
||||||
|
PKG_CHECK_MODULES(DRM_COMPOSITOR_GBM_MODIFIERS, [gbm >= 17.1],
|
||||||
|
[AC_DEFINE([HAVE_GBM_MODIFIERS], 1, [GBM supports modifiers])],
|
||||||
|
[AC_MSG_WARN([GBM does not support modifiers])])
|
||||||
PKG_CHECK_MODULES(DRM_COMPOSITOR_GBM, [gbm >= 17.2],
|
PKG_CHECK_MODULES(DRM_COMPOSITOR_GBM, [gbm >= 17.2],
|
||||||
[AC_DEFINE([HAVE_GBM_FD_IMPORT], 1, [gbm supports import with modifiers])],
|
[AC_DEFINE([HAVE_GBM_FD_IMPORT], 1, [gbm supports import with modifiers])],
|
||||||
[AC_MSG_WARN([GBM does not support dmabuf import, will omit that capability])])
|
[AC_MSG_WARN([GBM does not support dmabuf import, will omit that capability])])
|
||||||
|
|||||||
@@ -1199,6 +1199,9 @@ drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend *backend,
|
|||||||
bool is_opaque, enum drm_fb_type type)
|
bool is_opaque, enum drm_fb_type type)
|
||||||
{
|
{
|
||||||
struct drm_fb *fb = gbm_bo_get_user_data(bo);
|
struct drm_fb *fb = gbm_bo_get_user_data(bo);
|
||||||
|
#ifdef HAVE_GBM_MODIFIERS
|
||||||
|
int i;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (fb) {
|
if (fb) {
|
||||||
assert(fb->type == type);
|
assert(fb->type == type);
|
||||||
@@ -1212,15 +1215,25 @@ drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend *backend,
|
|||||||
fb->type = type;
|
fb->type = type;
|
||||||
fb->refcnt = 1;
|
fb->refcnt = 1;
|
||||||
fb->bo = bo;
|
fb->bo = bo;
|
||||||
|
fb->fd = backend->drm.fd;
|
||||||
|
|
||||||
fb->width = gbm_bo_get_width(bo);
|
fb->width = gbm_bo_get_width(bo);
|
||||||
fb->height = gbm_bo_get_height(bo);
|
fb->height = gbm_bo_get_height(bo);
|
||||||
|
fb->format = pixel_format_get_info(gbm_bo_get_format(bo));
|
||||||
|
fb->size = 0;
|
||||||
|
|
||||||
|
#ifdef HAVE_GBM_MODIFIERS
|
||||||
|
fb->modifier = gbm_bo_get_modifier(bo);
|
||||||
|
for (i = 0; i < gbm_bo_get_plane_count(bo); i++) {
|
||||||
|
fb->strides[i] = gbm_bo_get_stride_for_plane(bo, i);
|
||||||
|
fb->handles[i] = gbm_bo_get_handle_for_plane(bo, i).u32;
|
||||||
|
fb->offsets[i] = gbm_bo_get_offset(bo, i);
|
||||||
|
}
|
||||||
|
#else
|
||||||
fb->strides[0] = gbm_bo_get_stride(bo);
|
fb->strides[0] = gbm_bo_get_stride(bo);
|
||||||
fb->handles[0] = gbm_bo_get_handle(bo).u32;
|
fb->handles[0] = gbm_bo_get_handle(bo).u32;
|
||||||
fb->format = pixel_format_get_info(gbm_bo_get_format(bo));
|
|
||||||
fb->modifier = DRM_FORMAT_MOD_INVALID;
|
fb->modifier = DRM_FORMAT_MOD_INVALID;
|
||||||
fb->size = 0;
|
#endif
|
||||||
fb->fd = backend->drm.fd;
|
|
||||||
|
|
||||||
if (!fb->format) {
|
if (!fb->format) {
|
||||||
weston_log("couldn't look up format 0x%lx\n",
|
weston_log("couldn't look up format 0x%lx\n",
|
||||||
@@ -4365,13 +4378,39 @@ drm_output_init_egl(struct drm_output *output, struct drm_backend *b)
|
|||||||
fallback_format_for(output->gbm_format),
|
fallback_format_for(output->gbm_format),
|
||||||
};
|
};
|
||||||
int n_formats = 1;
|
int n_formats = 1;
|
||||||
|
struct weston_mode *mode = output->base.current_mode;
|
||||||
|
struct drm_plane *plane = output->scanout_plane;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < plane->count_formats; i++) {
|
||||||
|
if (plane->formats[i].format == output->gbm_format)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == plane->count_formats) {
|
||||||
|
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) {
|
||||||
|
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);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
output->gbm_surface =
|
||||||
|
gbm_surface_create(b->gbm, mode->width, mode->height,
|
||||||
|
output->gbm_format,
|
||||||
|
GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
|
||||||
|
}
|
||||||
|
|
||||||
output->gbm_surface = gbm_surface_create(b->gbm,
|
|
||||||
output->base.current_mode->width,
|
|
||||||
output->base.current_mode->height,
|
|
||||||
format[0],
|
|
||||||
GBM_BO_USE_SCANOUT |
|
|
||||||
GBM_BO_USE_RENDERING);
|
|
||||||
if (!output->gbm_surface) {
|
if (!output->gbm_surface) {
|
||||||
weston_log("failed to create gbm surface\n");
|
weston_log("failed to create gbm surface\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
Reference in New Issue
Block a user