egl: Introduce meta_egl_create_dmabuf_image
This bit of code was more or less duplicated in meta-renderer-native-gles3.c
and meta-wayland-dma-buf.c. Start consolidating the two implementations by
moving the *-gles3.c function into meta-egl.c and generalizing it so it could
also accommodate the meta-wayland-dma-buf.c usage.
The workaround in the *-gles3.c implementation is moved to the caller. It is
the caller's responsibility to check for the existence of the appropriate EGL
extensions.
Commit 6f59e4858e
worked around the lack of
EGL_EXT_image_dma_buf_import_modifiers with the assumption that if the modifier
is linear, there is no need to pass it into EGL. The problem is that not
passing a modifier explicitly to EGL invokes implementation-defined behaviour,
so we should not have that workaround in meta-egl.c.
This patch intends to be pure refactoring, no behavioral changes. The one
change is the addition of g_assert to catch overwriting arbitrary memory.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/615
This commit is contained in:
parent
6061abbf90
commit
9cd3b07472
@ -1,7 +1,8 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Red Hat Inc.
|
* Copyright (C) 2016, 2017 Red Hat Inc.
|
||||||
|
* Copyright (C) 2018, 2019 DisplayLink (UK) Ltd.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License as
|
* modify it under the terms of the GNU General Public License as
|
||||||
@ -574,6 +575,97 @@ meta_egl_destroy_image (MetaEgl *egl,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EGLImageKHR
|
||||||
|
meta_egl_create_dmabuf_image (MetaEgl *egl,
|
||||||
|
EGLDisplay egl_display,
|
||||||
|
unsigned int width,
|
||||||
|
unsigned int height,
|
||||||
|
uint32_t drm_format,
|
||||||
|
uint32_t n_planes,
|
||||||
|
const int *fds,
|
||||||
|
const uint32_t *strides,
|
||||||
|
const uint32_t *offsets,
|
||||||
|
const uint64_t *modifiers,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
EGLint attribs[37];
|
||||||
|
int atti = 0;
|
||||||
|
|
||||||
|
/* This requires the Mesa commit in
|
||||||
|
* Mesa 10.3 (08264e5dad4df448e7718e782ad9077902089a07) or
|
||||||
|
* Mesa 10.2.7 (55d28925e6109a4afd61f109e845a8a51bd17652).
|
||||||
|
* Otherwise Mesa closes the fd behind our back and re-importing
|
||||||
|
* will fail.
|
||||||
|
* https://bugs.freedesktop.org/show_bug.cgi?id=76188
|
||||||
|
*/
|
||||||
|
|
||||||
|
attribs[atti++] = EGL_WIDTH;
|
||||||
|
attribs[atti++] = width;
|
||||||
|
attribs[atti++] = EGL_HEIGHT;
|
||||||
|
attribs[atti++] = height;
|
||||||
|
attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT;
|
||||||
|
attribs[atti++] = drm_format;
|
||||||
|
|
||||||
|
if (n_planes > 0)
|
||||||
|
{
|
||||||
|
attribs[atti++] = EGL_DMA_BUF_PLANE0_FD_EXT;
|
||||||
|
attribs[atti++] = fds[0];
|
||||||
|
attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
|
||||||
|
attribs[atti++] = offsets[0];
|
||||||
|
attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
|
||||||
|
attribs[atti++] = strides[0];
|
||||||
|
if (modifiers)
|
||||||
|
{
|
||||||
|
attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT;
|
||||||
|
attribs[atti++] = modifiers[0] & 0xFFFFFFFF;
|
||||||
|
attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT;
|
||||||
|
attribs[atti++] = modifiers[0] >> 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n_planes > 1)
|
||||||
|
{
|
||||||
|
attribs[atti++] = EGL_DMA_BUF_PLANE1_FD_EXT;
|
||||||
|
attribs[atti++] = fds[1];
|
||||||
|
attribs[atti++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT;
|
||||||
|
attribs[atti++] = offsets[1];
|
||||||
|
attribs[atti++] = EGL_DMA_BUF_PLANE1_PITCH_EXT;
|
||||||
|
attribs[atti++] = strides[1];
|
||||||
|
if (modifiers)
|
||||||
|
{
|
||||||
|
attribs[atti++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT;
|
||||||
|
attribs[atti++] = modifiers[1] & 0xFFFFFFFF;
|
||||||
|
attribs[atti++] = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT;
|
||||||
|
attribs[atti++] = modifiers[1] >> 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n_planes > 2)
|
||||||
|
{
|
||||||
|
attribs[atti++] = EGL_DMA_BUF_PLANE2_FD_EXT;
|
||||||
|
attribs[atti++] = fds[2];
|
||||||
|
attribs[atti++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT;
|
||||||
|
attribs[atti++] = offsets[2];
|
||||||
|
attribs[atti++] = EGL_DMA_BUF_PLANE2_PITCH_EXT;
|
||||||
|
attribs[atti++] = strides[2];
|
||||||
|
if (modifiers)
|
||||||
|
{
|
||||||
|
attribs[atti++] = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT;
|
||||||
|
attribs[atti++] = modifiers[2] & 0xFFFFFFFF;
|
||||||
|
attribs[atti++] = EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT;
|
||||||
|
attribs[atti++] = modifiers[2] >> 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
attribs[atti++] = EGL_NONE;
|
||||||
|
g_assert (atti <= G_N_ELEMENTS (attribs));
|
||||||
|
|
||||||
|
return meta_egl_create_image (egl, egl_display, EGL_NO_CONTEXT,
|
||||||
|
EGL_LINUX_DMA_BUF_EXT, NULL,
|
||||||
|
attribs,
|
||||||
|
error);
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_egl_make_current (MetaEgl *egl,
|
meta_egl_make_current (MetaEgl *egl,
|
||||||
EGLDisplay display,
|
EGLDisplay display,
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Red Hat Inc.
|
* Copyright (C) 2016 Red Hat Inc.
|
||||||
|
* Copyright (C) 2019 DisplayLink (UK) Ltd.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License as
|
* modify it under the terms of the GNU General Public License as
|
||||||
@ -100,6 +101,18 @@ gboolean meta_egl_destroy_image (MetaEgl *egl,
|
|||||||
EGLImageKHR image,
|
EGLImageKHR image,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
EGLImageKHR meta_egl_create_dmabuf_image (MetaEgl *egl,
|
||||||
|
EGLDisplay egl_display,
|
||||||
|
unsigned int width,
|
||||||
|
unsigned int height,
|
||||||
|
uint32_t drm_format,
|
||||||
|
uint32_t n_planes,
|
||||||
|
const int *fds,
|
||||||
|
const uint32_t *strides,
|
||||||
|
const uint32_t *offsets,
|
||||||
|
const uint64_t *modifiers,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
EGLSurface meta_egl_create_window_surface (MetaEgl *egl,
|
EGLSurface meta_egl_create_window_surface (MetaEgl *egl,
|
||||||
EGLDisplay display,
|
EGLDisplay display,
|
||||||
EGLConfig config,
|
EGLConfig config,
|
||||||
|
@ -45,101 +45,6 @@
|
|||||||
#error "Somehow included OpenGL headers when we shouldn't have"
|
#error "Somehow included OpenGL headers when we shouldn't have"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static EGLImageKHR
|
|
||||||
create_egl_image (MetaEgl *egl,
|
|
||||||
EGLDisplay egl_display,
|
|
||||||
EGLContext egl_context,
|
|
||||||
unsigned int width,
|
|
||||||
unsigned int height,
|
|
||||||
uint32_t n_planes,
|
|
||||||
uint32_t *strides,
|
|
||||||
uint32_t *offsets,
|
|
||||||
uint64_t *modifiers,
|
|
||||||
uint32_t format,
|
|
||||||
int fd,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
EGLint attribs[37];
|
|
||||||
int atti = 0;
|
|
||||||
gboolean has_modifier;
|
|
||||||
|
|
||||||
/* This requires the Mesa commit in
|
|
||||||
* Mesa 10.3 (08264e5dad4df448e7718e782ad9077902089a07) or
|
|
||||||
* Mesa 10.2.7 (55d28925e6109a4afd61f109e845a8a51bd17652).
|
|
||||||
* Otherwise Mesa closes the fd behind our back and re-importing
|
|
||||||
* will fail.
|
|
||||||
* https://bugs.freedesktop.org/show_bug.cgi?id=76188
|
|
||||||
*/
|
|
||||||
|
|
||||||
attribs[atti++] = EGL_WIDTH;
|
|
||||||
attribs[atti++] = width;
|
|
||||||
attribs[atti++] = EGL_HEIGHT;
|
|
||||||
attribs[atti++] = height;
|
|
||||||
attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT;
|
|
||||||
attribs[atti++] = format;
|
|
||||||
|
|
||||||
has_modifier = (modifiers[0] != DRM_FORMAT_MOD_INVALID &&
|
|
||||||
modifiers[0] != DRM_FORMAT_MOD_LINEAR);
|
|
||||||
|
|
||||||
if (n_planes > 0)
|
|
||||||
{
|
|
||||||
attribs[atti++] = EGL_DMA_BUF_PLANE0_FD_EXT;
|
|
||||||
attribs[atti++] = fd;
|
|
||||||
attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
|
|
||||||
attribs[atti++] = offsets[0];
|
|
||||||
attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
|
|
||||||
attribs[atti++] = strides[0];
|
|
||||||
if (has_modifier)
|
|
||||||
{
|
|
||||||
attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT;
|
|
||||||
attribs[atti++] = modifiers[0] & 0xFFFFFFFF;
|
|
||||||
attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT;
|
|
||||||
attribs[atti++] = modifiers[0] >> 32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n_planes > 1)
|
|
||||||
{
|
|
||||||
attribs[atti++] = EGL_DMA_BUF_PLANE1_FD_EXT;
|
|
||||||
attribs[atti++] = fd;
|
|
||||||
attribs[atti++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT;
|
|
||||||
attribs[atti++] = offsets[1];
|
|
||||||
attribs[atti++] = EGL_DMA_BUF_PLANE1_PITCH_EXT;
|
|
||||||
attribs[atti++] = strides[1];
|
|
||||||
if (has_modifier)
|
|
||||||
{
|
|
||||||
attribs[atti++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT;
|
|
||||||
attribs[atti++] = modifiers[1] & 0xFFFFFFFF;
|
|
||||||
attribs[atti++] = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT;
|
|
||||||
attribs[atti++] = modifiers[1] >> 32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n_planes > 2)
|
|
||||||
{
|
|
||||||
attribs[atti++] = EGL_DMA_BUF_PLANE2_FD_EXT;
|
|
||||||
attribs[atti++] = fd;
|
|
||||||
attribs[atti++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT;
|
|
||||||
attribs[atti++] = offsets[2];
|
|
||||||
attribs[atti++] = EGL_DMA_BUF_PLANE2_PITCH_EXT;
|
|
||||||
attribs[atti++] = strides[2];
|
|
||||||
if (has_modifier)
|
|
||||||
{
|
|
||||||
attribs[atti++] = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT;
|
|
||||||
attribs[atti++] = modifiers[2] & 0xFFFFFFFF;
|
|
||||||
attribs[atti++] = EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT;
|
|
||||||
attribs[atti++] = modifiers[2] >> 32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
attribs[atti++] = EGL_NONE;
|
|
||||||
|
|
||||||
return meta_egl_create_image (egl, egl_display, EGL_NO_CONTEXT,
|
|
||||||
EGL_LINUX_DMA_BUF_EXT, NULL,
|
|
||||||
attribs,
|
|
||||||
error);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
paint_egl_image (MetaGles3 *gles3,
|
paint_egl_image (MetaGles3 *gles3,
|
||||||
EGLImageKHR egl_image,
|
EGLImageKHR egl_image,
|
||||||
@ -195,8 +100,10 @@ meta_renderer_native_gles3_blit_shared_bo (MetaEgl *egl,
|
|||||||
uint32_t strides[4] = { 0 };
|
uint32_t strides[4] = { 0 };
|
||||||
uint32_t offsets[4] = { 0 };
|
uint32_t offsets[4] = { 0 };
|
||||||
uint64_t modifiers[4] = { 0 };
|
uint64_t modifiers[4] = { 0 };
|
||||||
|
int fds[4] = { -1, -1, -1, -1 };
|
||||||
uint32_t format;
|
uint32_t format;
|
||||||
EGLImageKHR egl_image;
|
EGLImageKHR egl_image;
|
||||||
|
gboolean use_modifiers;
|
||||||
|
|
||||||
shared_bo_fd = gbm_bo_get_fd (shared_bo);
|
shared_bo_fd = gbm_bo_get_fd (shared_bo);
|
||||||
if (shared_bo_fd < 0)
|
if (shared_bo_fd < 0)
|
||||||
@ -216,17 +123,27 @@ meta_renderer_native_gles3_blit_shared_bo (MetaEgl *egl,
|
|||||||
strides[i] = gbm_bo_get_stride_for_plane (shared_bo, i);
|
strides[i] = gbm_bo_get_stride_for_plane (shared_bo, i);
|
||||||
offsets[i] = gbm_bo_get_offset (shared_bo, i);
|
offsets[i] = gbm_bo_get_offset (shared_bo, i);
|
||||||
modifiers[i] = gbm_bo_get_modifier (shared_bo);
|
modifiers[i] = gbm_bo_get_modifier (shared_bo);
|
||||||
|
fds[i] = shared_bo_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
egl_image = create_egl_image (egl,
|
/* Workaround for https://gitlab.gnome.org/GNOME/mutter/issues/18 */
|
||||||
egl_display,
|
if (modifiers[0] == DRM_FORMAT_MOD_LINEAR ||
|
||||||
egl_context,
|
modifiers[0] == DRM_FORMAT_MOD_INVALID)
|
||||||
width, height,
|
use_modifiers = FALSE;
|
||||||
n_planes,
|
else
|
||||||
strides, offsets,
|
use_modifiers = TRUE;
|
||||||
modifiers, format,
|
|
||||||
shared_bo_fd,
|
egl_image = meta_egl_create_dmabuf_image (egl,
|
||||||
error);
|
egl_display,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
format,
|
||||||
|
n_planes,
|
||||||
|
fds,
|
||||||
|
strides,
|
||||||
|
offsets,
|
||||||
|
use_modifiers ? modifiers : NULL,
|
||||||
|
error);
|
||||||
close (shared_bo_fd);
|
close (shared_bo_fd);
|
||||||
|
|
||||||
if (!egl_image)
|
if (!egl_image)
|
||||||
|
Loading…
Reference in New Issue
Block a user