onscreen/native: Move DRM modifier querying to MetaRenderDevice

It's only implemented by the GBM render device backend, and uses EGL,
thus does not distinguish scanout capable modifiers.

A filter enum is added to Cogl, since it'll be used via the Cogl API,
but the actual Cogl API isn't added yet.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3900>
This commit is contained in:
Jonas Ådahl 2022-12-16 17:01:18 +01:00 committed by Marge Bot
parent a8fe1fd625
commit a4ddba44e9
6 changed files with 126 additions and 26 deletions

View File

@ -39,6 +39,12 @@
G_BEGIN_DECLS
typedef enum _CoglDrmModifierFilter
{
COGL_DRM_MODIFIER_FILTER_NONE = 0,
COGL_DRM_MODIFIER_FILTER_SINGLE_PLANE = 1 << 0,
} CoglDrmModifierFilter;
/**
* CoglRenderer:
*

View File

@ -2083,47 +2083,27 @@ get_supported_egl_modifiers (CoglOnscreen *onscreen,
{
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
MetaRendererNative *renderer_native = onscreen_native->renderer_native;
MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native);
MetaGpu *gpu;
MetaRendererNativeGpuData *renderer_gpu_data;
MetaRenderDevice *render_device;
EGLDisplay egl_display;
EGLint num_modifiers;
g_autofree EGLuint64KHR *modifiers = NULL;
GArray *modifiers;
g_autoptr (GError) error = NULL;
gboolean ret;
gpu = meta_crtc_get_gpu (META_CRTC (crtc_kms));
renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native,
META_GPU_KMS (gpu));
render_device = renderer_gpu_data->render_device;
egl_display = meta_render_device_get_egl_display (render_device);
if (!meta_egl_has_extensions (egl, egl_display, NULL,
"EGL_EXT_image_dma_buf_import_modifiers",
NULL))
return NULL;
ret = meta_egl_query_dma_buf_modifiers (egl, egl_display,
format, 0, NULL, NULL,
&num_modifiers, NULL);
if (!ret || num_modifiers == 0)
return NULL;
modifiers = g_new (typeof (*modifiers), num_modifiers);
ret = meta_egl_query_dma_buf_modifiers (egl, egl_display,
format, num_modifiers,
modifiers, NULL,
&num_modifiers, &error);
if (!ret)
modifiers = meta_render_device_query_drm_modifiers (render_device, format,
COGL_DRM_MODIFIER_FILTER_NONE,
&error);
if (!modifiers)
{
g_warning ("Failed to query DMABUF modifiers: %s", error->message);
return NULL;
}
return g_array_new_take (g_steal_pointer (&modifiers), num_modifiers, FALSE,
sizeof (*modifiers));
return modifiers;
}
static GArray *

View File

@ -106,6 +106,86 @@ meta_render_device_gbm_import_dma_buf (MetaRenderDevice *render_device,
return META_DRM_BUFFER (buffer_import);
}
static GArray *
meta_render_device_gbm_query_drm_modifiers (MetaRenderDevice *render_device,
uint32_t drm_format,
CoglDrmModifierFilter filter,
GError **error)
{
MetaRenderDeviceGbm *render_device_gbm =
META_RENDER_DEVICE_GBM (render_device);
MetaBackend *backend = meta_render_device_get_backend (render_device);
MetaEgl *egl = meta_backend_get_egl (backend);
EGLDisplay egl_display;
EGLint n_modifiers;
g_autoptr (GArray) modifiers = NULL;
egl_display = meta_render_device_get_egl_display (render_device);
if (!meta_egl_has_extensions (egl, egl_display, NULL,
"EGL_EXT_image_dma_buf_import_modifiers",
NULL))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
"Missing EGL extension "
"'EGL_EXT_image_dma_buf_import_modifiers'");
return NULL;
}
if (!meta_egl_query_dma_buf_modifiers (egl, egl_display,
drm_format, 0, NULL, NULL,
&n_modifiers, error))
return NULL;
if (n_modifiers == 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"No modifiers supported for given format");
return NULL;
}
modifiers = g_array_sized_new (FALSE, FALSE, sizeof (uint64_t),
n_modifiers);
if (!meta_egl_query_dma_buf_modifiers (egl, egl_display,
drm_format, n_modifiers,
(EGLuint64KHR *) modifiers->data, NULL,
&n_modifiers, error))
return NULL;
g_array_set_size (modifiers, n_modifiers);
if (filter & COGL_DRM_MODIFIER_FILTER_SINGLE_PLANE)
{
g_autoptr (GArray) filtered_modifiers = NULL;
struct gbm_device *gbm_device = render_device_gbm->gbm_device;
int i;
filtered_modifiers = g_array_new (FALSE, FALSE, sizeof (uint64_t));
for (i = 0; i < modifiers->len; i++)
{
uint64_t modifier = g_array_index (modifiers, uint64_t, i);
if (gbm_device_get_format_modifier_plane_count (gbm_device,
drm_format,
modifier) == 1)
g_array_append_val (filtered_modifiers, modifier);
}
if (filtered_modifiers->len == 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
"No single plane modifiers found");
return NULL;
}
g_array_free (modifiers, TRUE);
modifiers = g_steal_pointer (&filtered_modifiers);
}
return g_steal_pointer (&modifiers);
}
static EGLDisplay
meta_render_device_gbm_create_egl_display (MetaRenderDevice *render_device,
GError **error)
@ -213,6 +293,8 @@ meta_render_device_gbm_class_init (MetaRenderDeviceGbmClass *klass)
meta_render_device_gbm_allocate_dma_buf;
render_device_class->import_dma_buf =
meta_render_device_gbm_import_dma_buf;
render_device_class->query_drm_modifiers =
meta_render_device_gbm_query_drm_modifiers;
}
static void

View File

@ -44,4 +44,9 @@ struct _MetaRenderDeviceClass
MetaDrmBuffer * (* import_dma_buf) (MetaRenderDevice *render_device,
MetaDrmBuffer *buffer,
GError **error);
GArray * (* query_drm_modifiers) (MetaRenderDevice *render_device,
uint32_t format,
CoglDrmModifierFilter filter,
GError **error);
};

View File

@ -340,6 +340,28 @@ meta_render_device_get_name (MetaRenderDevice *render_device)
return "(device-less)";
}
GArray *
meta_render_device_query_drm_modifiers (MetaRenderDevice *render_device,
uint32_t drm_format,
CoglDrmModifierFilter filter,
GError **error)
{
MetaRenderDeviceClass *klass = META_RENDER_DEVICE_GET_CLASS (render_device);
if (klass->query_drm_modifiers)
{
return klass->query_drm_modifiers (render_device,
drm_format, filter,
error);
}
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
"Render device '%s' doesn't support allocating DMA buffers",
meta_render_device_get_name (render_device));
return NULL;
}
MetaDrmBuffer *
meta_render_device_allocate_dma_buf (MetaRenderDevice *render_device,
int width,

View File

@ -38,6 +38,11 @@ gboolean meta_render_device_is_hardware_accelerated (MetaRenderDevice *render_de
MetaDeviceFile * meta_render_device_get_device_file (MetaRenderDevice *render_device);
GArray * meta_render_device_query_drm_modifiers (MetaRenderDevice *render_device,
uint32_t drm_format,
CoglDrmModifierFilter filter,
GError **error);
MetaDrmBuffer * meta_render_device_allocate_dma_buf (MetaRenderDevice *render_device,
int width,
int height,