Make DMA buffer allocation format and modifier aware

This makes DMA buffer allocation in all layers take an array of possible
modifiers to allocate using, or zero modifiers if implicit modifiers
should be used.

The format hard coding previously used is moved to the screen cast code,
or in case of the (unused by default) shadow buffer buffers use the same
format as the the CoglOnscreen.

This also means the CoglDmaBufHandle and MetaDrmBuffer got taught how to
distinguish between planes. It's mostly unused in practice, so rather
untested.

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

View File

@ -649,13 +649,14 @@ cogl_context_from_renderer_native (MetaRendererNative *renderer_native)
CoglFramebuffer *
meta_renderer_native_create_dma_buf_framebuffer (MetaRendererNative *renderer_native,
int dmabuf_fd,
uint32_t width,
uint32_t height,
uint32_t stride,
uint32_t offset,
uint64_t *modifier,
uint32_t drm_format,
int n_planes,
int *fds,
uint32_t *strides,
uint32_t *offsets,
uint64_t *modifiers,
GError **error)
{
CoglContext *cogl_context =
@ -666,8 +667,6 @@ meta_renderer_native_create_dma_buf_framebuffer (MetaRendererNative *renderer_n
EGLDisplay egl_display = cogl_renderer_egl->edpy;
MetaEgl *egl = meta_renderer_native_get_egl (renderer_native);
EGLImageKHR egl_image;
uint32_t strides[1];
uint32_t offsets[1];
CoglPixelFormat cogl_format;
CoglEglImageFlags flags;
CoglTexture *cogl_tex;
@ -678,18 +677,16 @@ meta_renderer_native_create_dma_buf_framebuffer (MetaRendererNative *renderer_n
g_assert (format_info);
cogl_format = format_info->cogl_format;
strides[0] = stride;
offsets[0] = offset;
egl_image = meta_egl_create_dmabuf_image (egl,
egl_display,
width,
height,
drm_format,
1 /* n_planes */,
&dmabuf_fd,
n_planes,
fds,
strides,
offsets,
modifier,
modifiers,
error);
if (egl_image == EGL_NO_IMAGE_KHR)
return NULL;
@ -957,6 +954,16 @@ meta_renderer_native_queue_mode_set_update (MetaRendererNative *renderer_native,
meta_kms_update_free (new_kms_update);
}
static void
close_fds (int *fds,
int n_fds)
{
int i;
for (i = 0; i < n_fds; i++)
close (fds[i]);
}
static CoglDmaBufHandle *
meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer,
CoglPixelFormat format,
@ -977,11 +984,15 @@ meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer,
MetaRenderDevice *render_device;
MetaDrmBufferFlags flags;
g_autoptr (MetaDrmBuffer) buffer = NULL;
int dmabuf_fd;
uint32_t stride;
uint32_t offset;
uint64_t buffer_modifier;
int n_planes;
int *fds;
uint32_t *offsets;
uint32_t *strides;
uint64_t *plane_modifiers = NULL;
uint32_t bpp;
uint32_t drm_format;
int i;
CoglFramebuffer *dmabuf_fb;
CoglDmaBufHandle *dmabuf_handle;
const MetaFormatInfo *format_info;
@ -1007,49 +1018,59 @@ meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer,
if (!buffer)
return NULL;
dmabuf_fd = meta_drm_buffer_export_fd (buffer, error);
if (dmabuf_fd == -1)
return NULL;
stride = meta_drm_buffer_get_stride (buffer);
offset = meta_drm_buffer_get_offset (buffer, 0);
buffer_modifier = meta_drm_buffer_get_modifier (buffer);
bpp = meta_drm_buffer_get_bpp (buffer);
if (n_modifiers)
{
uint64_t modifier = meta_drm_buffer_get_modifier (buffer);
dmabuf_fb =
meta_renderer_native_create_dma_buf_framebuffer (renderer_native,
dmabuf_fd,
width, height,
stride,
offset,
&modifier,
drm_format,
error);
}
else
n_planes = meta_drm_buffer_get_n_planes (buffer);
fds = g_newa (int, n_planes);
offsets = g_newa (uint32_t, n_planes);
strides = g_newa (uint32_t, n_planes);
if (n_modifiers > 0)
plane_modifiers = g_newa (uint64_t, n_planes);
for (i = 0; i < n_planes; i++)
{
dmabuf_fb =
meta_renderer_native_create_dma_buf_framebuffer (renderer_native,
dmabuf_fd,
width, height,
stride,
offset,
NULL,
drm_format,
error);
fds[i] = meta_drm_buffer_export_fd_for_plane (buffer, i, error);
if (fds[i] == -1)
{
close_fds (fds, i);
return NULL;
}
offsets[i] = meta_drm_buffer_get_offset_for_plane (buffer, i);
strides[i] = meta_drm_buffer_get_stride_for_plane (buffer, i);
if (n_modifiers > 0)
plane_modifiers[i] = buffer_modifier;
}
dmabuf_fb =
meta_renderer_native_create_dma_buf_framebuffer (renderer_native,
width,
height,
drm_format,
n_planes,
fds,
strides,
offsets,
plane_modifiers,
error);
close_fds (fds, n_planes);
if (!dmabuf_fb)
{
close (dmabuf_fd);
return NULL;
}
return NULL;
dmabuf_handle =
cogl_dma_buf_handle_new (dmabuf_fb, dmabuf_fd,
width, height, stride, offset, bpp,
cogl_dma_buf_handle_new (dmabuf_fb,
width, height,
format,
buffer_modifier,
n_planes,
fds,
strides,
offsets,
bpp,
g_steal_pointer (&buffer),
g_object_unref);
g_object_unref (dmabuf_fb);