wayland/dma-buf: Only advertise supported formats

Analogous to how we use `eglQueryDmaBufModifiersEXT()` to query
supported modifiers, use `eglQueryDmaBufFormatsEXT()` to ensure
we only advertise formats supported by both the compositor and the
driver.

If there is no overlap, don't advertise `zwp_linux_dmabuf_v1` at
all.

Closes https://gitlab.gnome.org/GNOME/mutter/-/issues/2238

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2386>
This commit is contained in:
Robert Mader 2022-04-25 18:00:50 +02:00 committed by Marge Bot
parent 2cfd4f325b
commit c8095b4306

View File

@ -1347,28 +1347,72 @@ init_format_table (MetaWaylandDmaBufManager *dma_buf_manager)
meta_anonymous_file_new (size, (uint8_t *) format_table);
}
static void
init_formats (MetaWaylandDmaBufManager *dma_buf_manager,
EGLDisplay egl_display)
static EGLint supported_formats[] = {
DRM_FORMAT_ARGB8888,
DRM_FORMAT_ABGR8888,
DRM_FORMAT_XRGB8888,
DRM_FORMAT_XBGR8888,
DRM_FORMAT_ARGB2101010,
DRM_FORMAT_ABGR2101010,
DRM_FORMAT_XRGB2101010,
DRM_FORMAT_XBGR2101010,
DRM_FORMAT_RGB565,
DRM_FORMAT_ABGR16161616F,
DRM_FORMAT_XBGR16161616F,
DRM_FORMAT_XRGB16161616F,
DRM_FORMAT_ARGB16161616F
};
static gboolean
init_formats (MetaWaylandDmaBufManager *dma_buf_manager,
EGLDisplay egl_display,
GError **error)
{
MetaContext *context = dma_buf_manager->compositor->context;
MetaBackend *backend = meta_context_get_backend (context);
MetaEgl *egl = meta_backend_get_egl (backend);
EGLint num_formats;
g_autofree EGLint *driver_formats = NULL;
int i, j;
dma_buf_manager->formats = g_array_new (FALSE, FALSE,
sizeof (MetaWaylandDmaBufFormat));
add_format (dma_buf_manager, egl_display, DRM_FORMAT_ARGB8888);
add_format (dma_buf_manager, egl_display, DRM_FORMAT_ABGR8888);
add_format (dma_buf_manager, egl_display, DRM_FORMAT_XRGB8888);
add_format (dma_buf_manager, egl_display, DRM_FORMAT_XBGR8888);
add_format (dma_buf_manager, egl_display, DRM_FORMAT_ARGB2101010);
add_format (dma_buf_manager, egl_display, DRM_FORMAT_ABGR2101010);
add_format (dma_buf_manager, egl_display, DRM_FORMAT_XRGB2101010);
add_format (dma_buf_manager, egl_display, DRM_FORMAT_XBGR2101010);
add_format (dma_buf_manager, egl_display, DRM_FORMAT_RGB565);
add_format (dma_buf_manager, egl_display, DRM_FORMAT_ABGR16161616F);
add_format (dma_buf_manager, egl_display, DRM_FORMAT_XBGR16161616F);
add_format (dma_buf_manager, egl_display, DRM_FORMAT_XRGB16161616F);
add_format (dma_buf_manager, egl_display, DRM_FORMAT_ARGB16161616F);
if (!meta_egl_query_dma_buf_formats (egl, egl_display, 0, NULL, &num_formats,
error))
return FALSE;
if (num_formats == 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"EGL doesn't support any DRM formats");
return FALSE;
}
driver_formats = g_new0 (EGLint, num_formats);
if (!meta_egl_query_dma_buf_formats (egl, egl_display, num_formats,
driver_formats, &num_formats, error))
return FALSE;
for (i = 0; i < G_N_ELEMENTS (supported_formats); i++)
{
for (j = 0; j < num_formats; j++)
{
if (supported_formats[i] == driver_formats[j])
add_format (dma_buf_manager, egl_display, supported_formats[i]);
}
}
if (dma_buf_manager->formats->len == 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"EGL doesn't support any DRM formats supported by the "
"compositor");
return FALSE;
}
init_format_table (dma_buf_manager);
return TRUE;
}
static void
@ -1495,6 +1539,16 @@ initialize:
dma_buf_manager = g_object_new (META_TYPE_WAYLAND_DMA_BUF_MANAGER, NULL);
dma_buf_manager->compositor = compositor;
dma_buf_manager->main_device_id = device_id;
if (!init_formats (dma_buf_manager, egl_display, &local_error))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"No supported formats detected: %s", local_error->message);
return NULL;
}
if (!wl_global_create (compositor->wayland_display,
&zwp_linux_dmabuf_v1_interface,
protocol_version,
@ -1506,10 +1560,6 @@ initialize:
return NULL;
}
dma_buf_manager->compositor = compositor;
dma_buf_manager->main_device_id = device_id;
init_formats (dma_buf_manager, egl_display);
init_default_feedback (dma_buf_manager);
return g_steal_pointer (&dma_buf_manager);