[mutter/wip/nielsdg/add-yuv-support: 59/59] WIP
- From: Niels De Graef <nielsdg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/nielsdg/add-yuv-support: 59/59] WIP
- Date: Mon, 14 Jan 2019 14:49:35 +0000 (UTC)
commit 501e75dc5d1c645fc2cb44f24fe73c7c81441c93
Author: Niels De Graef <nielsdegraef gmail com>
Date: Tue Dec 4 16:57:12 2018 +0100
WIP
cogl/cogl/cogl-multi-plane-texture.c | 7 +-
src/wayland/meta-wayland-buffer.c | 23 ++--
src/wayland/meta-wayland-dma-buf.c | 226 ++++++++++++++++++++++++-----------
3 files changed, 173 insertions(+), 83 deletions(-)
---
diff --git a/cogl/cogl/cogl-multi-plane-texture.c b/cogl/cogl/cogl-multi-plane-texture.c
index cf0d164e2..dea06b515 100644
--- a/cogl/cogl/cogl-multi-plane-texture.c
+++ b/cogl/cogl/cogl-multi-plane-texture.c
@@ -147,8 +147,9 @@ cogl_multi_plane_texture_new_from_bitmaps (CoglPixelFormat format,
if (format == COGL_PIXEL_FORMAT_NV12)
{
+ /* Issue here: the data is inside the A coordinate, rather than the X coordinate */
if (i == 0)
- _cogl_bitmap_set_format (bitmaps[i], COGL_PIXEL_FORMAT_A_8);
+ _cogl_bitmap_set_format (bitmaps[i], COGL_PIXEL_FORMAT_G_8);
else
_cogl_bitmap_set_format (bitmaps[i], COGL_PIXEL_FORMAT_RG_88);
}
@@ -159,8 +160,8 @@ cogl_multi_plane_texture_new_from_bitmaps (CoglPixelFormat format,
{
if (i == 0)
{
- _cogl_texture_set_internal_format (plane, COGL_PIXEL_FORMAT_A_8);
- _cogl_bitmap_set_format (bitmaps[i], COGL_PIXEL_FORMAT_A_8);
+ _cogl_texture_set_internal_format (plane, COGL_PIXEL_FORMAT_G_8);
+ _cogl_bitmap_set_format (bitmaps[i], COGL_PIXEL_FORMAT_G_8);
}
else
{
diff --git a/src/wayland/meta-wayland-buffer.c b/src/wayland/meta-wayland-buffer.c
index 61a38eefb..b86943541 100644
--- a/src/wayland/meta-wayland-buffer.c
+++ b/src/wayland/meta-wayland-buffer.c
@@ -321,8 +321,6 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
CoglPixelFormat cogl_format;
guint i, n_planes;
GPtrArray *planes;
- gboolean ret = FALSE;
- EGLint attrib_list[3] = { EGL_NONE, EGL_NONE, EGL_NONE };
if (buffer->texture)
return TRUE;
@@ -378,22 +376,24 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
/* Each EGLImage is a plane in the final texture */
for (i = 0; i < n_planes; i++)
{
+ EGLint egl_attribs[3];
EGLImageKHR egl_img;
CoglTexture2D *texture;
/* Specify that we want the i'th plane */
- attrib_list[0] = EGL_WAYLAND_PLANE_WL;
- attrib_list[1] = i;
+ egl_attribs[0] = EGL_WAYLAND_PLANE_WL;
+ egl_attribs[1] = i;
+ egl_attribs[2] = EGL_NONE;
/* The WL_bind_wayland_display spec states that EGL_NO_CONTEXT is to be
* used in conjunction with the EGL_WAYLAND_BUFFER_WL target. */
egl_img = meta_egl_create_image (egl, egl_display, EGL_NO_CONTEXT,
EGL_WAYLAND_BUFFER_WL, buffer->resource,
- attrib_list,
+ egl_attribs,
error);
if (G_UNLIKELY (egl_img == EGL_NO_IMAGE_KHR))
- goto out;
+ goto on_error;
texture = cogl_egl_texture_2d_new_from_image (cogl_context,
width, height,
@@ -404,7 +404,7 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
meta_egl_destroy_image (egl, egl_display, egl_img, NULL);
if (G_UNLIKELY (!texture))
- goto out;
+ goto on_error;
g_ptr_array_add (planes, texture);
}
@@ -415,13 +415,12 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
n_planes);
buffer->is_y_inverted = !!y_inverted;
- ret = TRUE;
+ return TRUE;
-out:
- if (!ret)
- g_ptr_array_free (planes, TRUE);
+on_error:
+ g_ptr_array_free (planes, TRUE);
- return ret;
+ return FALSE;
}
#ifdef HAVE_WAYLAND_EGLSTREAM
diff --git a/src/wayland/meta-wayland-dma-buf.c b/src/wayland/meta-wayland-dma-buf.c
index d52678c19..f8bc0ad0b 100644
--- a/src/wayland/meta-wayland-dma-buf.c
+++ b/src/wayland/meta-wayland-dma-buf.c
@@ -56,8 +56,10 @@ struct _MetaWaylandDmaBufBuffer
int width;
int height;
uint32_t drm_format;
- uint64_t drm_modifier;
bool is_y_inverted;
+
+ guint n_planes;
+ uint64_t drm_modifier[META_WAYLAND_DMA_BUF_MAX_FDS];
int fds[META_WAYLAND_DMA_BUF_MAX_FDS];
int offsets[META_WAYLAND_DMA_BUF_MAX_FDS];
unsigned int strides[META_WAYLAND_DMA_BUF_MAX_FDS];
@@ -65,6 +67,58 @@ struct _MetaWaylandDmaBufBuffer
G_DEFINE_TYPE (MetaWaylandDmaBufBuffer, meta_wayland_dma_buf_buffer, G_TYPE_OBJECT);
+static CoglPixelFormat
+drm_buffer_get_cogl_pixel_format (MetaWaylandDmaBufBuffer *dma_buf)
+{
+ g_warning ("Got dma format %d", dma_buf->drm_format);
+ switch (dma_buf->drm_format)
+ {
+ /*
+ * NOTE: The cogl_format here is only used for texture color channel
+ * swizzling as compared to COGL_PIXEL_FORMAT_ARGB. It is *not* used
+ * for accessing the buffer memory. EGL will access the buffer
+ * memory according to the DRM fourcc code. Cogl will not mmap
+ * and access the buffer memory at all.
+ */
+ case DRM_FORMAT_XRGB8888:
+ return COGL_PIXEL_FORMAT_RGB_888;
+ case DRM_FORMAT_ARGB8888:
+ return COGL_PIXEL_FORMAT_ARGB_8888_PRE;
+ case DRM_FORMAT_ARGB2101010:
+ return COGL_PIXEL_FORMAT_ARGB_2101010_PRE;
+ case DRM_FORMAT_RGB565:
+ return COGL_PIXEL_FORMAT_RGB_565;
+ case DRM_FORMAT_YUYV:
+ return COGL_PIXEL_FORMAT_YUYV;
+ case DRM_FORMAT_NV12:
+ return COGL_PIXEL_FORMAT_NV12;
+ case DRM_FORMAT_NV21:
+ return COGL_PIXEL_FORMAT_NV21;
+ case DRM_FORMAT_YUV410:
+ return COGL_PIXEL_FORMAT_YUV410;
+ case DRM_FORMAT_YVU410:
+ return COGL_PIXEL_FORMAT_YVU410;
+ case DRM_FORMAT_YUV411:
+ return COGL_PIXEL_FORMAT_YUV411;
+ case DRM_FORMAT_YVU411:
+ return COGL_PIXEL_FORMAT_YVU411;
+ case DRM_FORMAT_YUV420:
+ return COGL_PIXEL_FORMAT_YUV420;
+ case DRM_FORMAT_YVU420:
+ return COGL_PIXEL_FORMAT_YVU420;
+ case DRM_FORMAT_YUV422:
+ return COGL_PIXEL_FORMAT_YUV422;
+ case DRM_FORMAT_YVU422:
+ return COGL_PIXEL_FORMAT_YVU422;
+ case DRM_FORMAT_YUV444:
+ return COGL_PIXEL_FORMAT_YUV444;
+ case DRM_FORMAT_YVU444:
+ return COGL_PIXEL_FORMAT_YVU444;
+ default:
+ return COGL_PIXEL_FORMAT_ANY;
+ }
+}
+
gboolean
meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer,
GError **error)
@@ -76,43 +130,25 @@ meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer,
EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context);
MetaWaylandDmaBufBuffer *dma_buf = buffer->dma_buf.dma_buf;
CoglPixelFormat cogl_format;
- EGLImageKHR egl_image;
- CoglTexture2D *texture;
- CoglTexture **textures;
EGLint attribs[64];
int attr_idx = 0;
+ GPtrArray *planes;
+ guint i = 0, n_planes = 1;
if (buffer->texture)
return TRUE;
- switch (dma_buf->drm_format)
+ cogl_format = drm_buffer_get_cogl_pixel_format (dma_buf);
+ if (G_UNLIKELY (cogl_format == COGL_PIXEL_FORMAT_ANY))
{
- /*
- * NOTE: The cogl_format here is only used for texture color channel
- * swizzling as compared to COGL_PIXEL_FORMAT_ARGB. It is *not* used
- * for accessing the buffer memory. EGL will access the buffer
- * memory according to the DRM fourcc code. Cogl will not mmap
- * and access the buffer memory at all.
- */
- case DRM_FORMAT_XRGB8888:
- cogl_format = COGL_PIXEL_FORMAT_RGB_888;
- break;
- case DRM_FORMAT_ARGB8888:
- cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
- break;
- case DRM_FORMAT_ARGB2101010:
- cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE;
- break;
- case DRM_FORMAT_RGB565:
- cogl_format = COGL_PIXEL_FORMAT_RGB_565;
- break;
- default:
g_set_error (error, G_IO_ERROR,
G_IO_ERROR_FAILED,
"Unsupported buffer format %d", dma_buf->drm_format);
return FALSE;
}
+ g_warning ("Got cOGL format %d", cogl_format);
+ /* Can't we put the following inside the for loop? */
attribs[attr_idx++] = EGL_WIDTH;
attribs[attr_idx++] = dma_buf->width;
attribs[attr_idx++] = EGL_HEIGHT;
@@ -127,9 +163,9 @@ meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer,
attribs[attr_idx++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
attribs[attr_idx++] = dma_buf->strides[0];
attribs[attr_idx++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT;
- attribs[attr_idx++] = dma_buf->drm_modifier & 0xffffffff;
+ attribs[attr_idx++] = dma_buf->drm_modifier[0] & 0xffffffff;
attribs[attr_idx++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT;
- attribs[attr_idx++] = dma_buf->drm_modifier >> 32;
+ attribs[attr_idx++] = dma_buf->drm_modifier[0] >> 32;
if (dma_buf->fds[1] >= 0)
{
@@ -140,9 +176,9 @@ meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer,
attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_PITCH_EXT;
attribs[attr_idx++] = dma_buf->strides[1];
attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT;
- attribs[attr_idx++] = dma_buf->drm_modifier & 0xffffffff;
+ attribs[attr_idx++] = dma_buf->drm_modifier[1] & 0xffffffff;
attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT;
- attribs[attr_idx++] = dma_buf->drm_modifier >> 32;
+ attribs[attr_idx++] = dma_buf->drm_modifier[1] >> 32;
}
if (dma_buf->fds[2] >= 0)
@@ -154,9 +190,9 @@ meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer,
attribs[attr_idx++] = EGL_DMA_BUF_PLANE2_PITCH_EXT;
attribs[attr_idx++] = dma_buf->strides[2];
attribs[attr_idx++] = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT;
- attribs[attr_idx++] = dma_buf->drm_modifier & 0xffffffff;
+ attribs[attr_idx++] = dma_buf->drm_modifier[2] & 0xffffffff;
attribs[attr_idx++] = EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT;
- attribs[attr_idx++] = dma_buf->drm_modifier >> 32;
+ attribs[attr_idx++] = dma_buf->drm_modifier[2] >> 32;
}
if (dma_buf->fds[3] >= 0)
@@ -168,41 +204,79 @@ meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer,
attribs[attr_idx++] = EGL_DMA_BUF_PLANE3_PITCH_EXT;
attribs[attr_idx++] = dma_buf->strides[3];
attribs[attr_idx++] = EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT;
- attribs[attr_idx++] = dma_buf->drm_modifier & 0xffffffff;
+ attribs[attr_idx++] = dma_buf->drm_modifier[3] & 0xffffffff;
attribs[attr_idx++] = EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT;
- attribs[attr_idx++] = dma_buf->drm_modifier >> 32;
+ attribs[attr_idx++] = dma_buf->drm_modifier[3] >> 32;
}
attribs[attr_idx++] = EGL_NONE;
- attribs[attr_idx++] = EGL_NONE;
- /* The EXT_image_dma_buf_import spec states that EGL_NO_CONTEXT is to be used
- * in conjunction with the EGL_LINUX_DMA_BUF_EXT target. Similarly, the
- * native buffer is named in the attribs. */
- egl_image = meta_egl_create_image (egl, egl_display, EGL_NO_CONTEXT,
- EGL_LINUX_DMA_BUF_EXT, NULL, attribs,
- error);
- if (egl_image == EGL_NO_IMAGE_KHR)
- return FALSE;
+ n_planes = cogl_pixel_format_get_n_planes (cogl_format);
+ /* If this isn't correct, then something went very wrong, so bail out */
+ g_warning ("n_planes == %d <-> dma_buf planes = %d", n_planes, dma_buf->n_planes);
+ /* FIXME uncomment */
+ /* g_return_val_if_fail (n_planes == dma_buf->n_planes, FALSE); */
- texture = cogl_egl_texture_2d_new_from_image (cogl_context,
- dma_buf->width,
- dma_buf->height,
- cogl_format,
- egl_image,
- error);
+ /*XXX probeersel*/
+ /* cogl_format = COGL_PIXEL_FORMAT_NV12; */
- meta_egl_destroy_image (egl, egl_display, egl_image, NULL);
+ planes = g_ptr_array_new_full (n_planes, cogl_object_unref);
- if (!texture)
- return FALSE;
+ /* Each EGLImage is a plane in the final CoglMultiPlaneTexture */
+ for (i = 0; i < dma_buf->n_planes; i++)
+ {
+ EGLImageKHR egl_img;
+ CoglTexture2D *plane;
+
+ /* XXX can't we do this? */
+ /* if (dma_buf->fds[i] >= 0) */
+ /* { */
+ /* attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_FD_EXT; */
+ /* attribs[attr_idx++] = dma_buf->fds[i]; */
+ /* attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT; */
+ /* attribs[attr_idx++] = dma_buf->offsets[i]; */
+ /* attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_PITCH_EXT; */
+ /* attribs[attr_idx++] = dma_buf->strides[i]; */
+ /* attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT; */
+ /* attribs[attr_idx++] = dma_buf->drm_modifier[i] & 0xffffffff; */
+ /* attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT; */
+ /* attribs[attr_idx++] = dma_buf->drm_modifier[i] >> 32; */
+ /* } */
+
+ /* The EXT_image_dma_buf_import spec states that EGL_NO_CONTEXT is to be
+ * used in conjunction with the EGL_LINUX_DMA_BUF_EXT target. Similarly,
+ * the native buffer is named in the attribs. */
+ egl_img = meta_egl_create_image (egl, egl_display, EGL_NO_CONTEXT,
+ EGL_LINUX_DMA_BUF_EXT, NULL, attribs,
+ error);
+ if (G_UNLIKELY (egl_img == EGL_NO_IMAGE_KHR))
+ goto on_error;
+
+ plane = cogl_egl_texture_2d_new_from_image (cogl_context,
+ dma_buf->width,
+ dma_buf->height,
+ cogl_format,
+ egl_img,
+ error);
+
+ meta_egl_destroy_image (egl, egl_display, egl_img, NULL);
+
+ if (G_UNLIKELY (!plane))
+ goto on_error;
+
+ g_ptr_array_add (planes, plane);
+ }
- textures = g_new (CoglTexture *, 1);
- textures[0] = COGL_TEXTURE (texture);
- buffer->texture = cogl_multi_plane_texture_new (cogl_format, textures, 1);
+ buffer->texture = cogl_multi_plane_texture_new (cogl_format,
+ g_ptr_array_free (planes, FALSE),
+ dma_buf->n_planes);
buffer->is_y_inverted = dma_buf->is_y_inverted;
return TRUE;
+
+on_error:
+ g_ptr_array_free (planes, TRUE);
+ return FALSE;
}
static void
@@ -221,8 +295,10 @@ buffer_params_add (struct wl_client *client,
drm_modifier = ((uint64_t) drm_modifier_hi) << 32;
drm_modifier |= ((uint64_t) drm_modifier_lo) & 0xffffffff;
+ g_warning ("buffer_params_add %d", plane_idx);
+
dma_buf = wl_resource_get_user_data (resource);
- if (!dma_buf)
+ if (G_UNLIKELY (!dma_buf))
{
wl_resource_post_error (resource,
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_ALREADY_USED,
@@ -230,7 +306,7 @@ buffer_params_add (struct wl_client *client,
return;
}
- if (plane_idx >= META_WAYLAND_DMA_BUF_MAX_FDS)
+ if (G_UNLIKELY (plane_idx >= META_WAYLAND_DMA_BUF_MAX_FDS))
{
wl_resource_post_error (resource,
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_IDX,
@@ -239,7 +315,7 @@ buffer_params_add (struct wl_client *client,
return;
}
- if (dma_buf->fds[plane_idx] != -1)
+ if (G_UNLIKELY (dma_buf->fds[plane_idx] != -1))
{
wl_resource_post_error (resource,
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_SET,
@@ -248,17 +324,19 @@ buffer_params_add (struct wl_client *client,
return;
}
- if (dma_buf->drm_modifier != DRM_FORMAT_MOD_INVALID &&
- dma_buf->drm_modifier != drm_modifier)
- {
- wl_resource_post_error (resource,
- ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_WL_BUFFER,
- "mismatching modifier between planes");
- return;
- }
+ /* if (G_UNLIKELY (dma_buf->drm_modifier[plane_idx] != DRM_FORMAT_MOD_INVALID && */
+ /* dma_buf->drm_modifier != drm_modifier)) */
+ /* { */
+ /* wl_resource_post_error (resource, */
+ /* ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_WL_BUFFER, */
+ /* "mismatching modifier between planes"); */
+ /* return; */
+ /* } */
- dma_buf->drm_modifier = drm_modifier;
+
+ dma_buf->n_planes = plane_idx + 1;
dma_buf->fds[plane_idx] = fd;
+ dma_buf->drm_modifier[plane_idx] = drm_modifier;
dma_buf->offsets[plane_idx] = offset;
dma_buf->strides[plane_idx] = stride;
}
@@ -538,6 +616,16 @@ dma_buf_bind (struct wl_client *client,
send_modifiers (resource, DRM_FORMAT_XRGB8888);
send_modifiers (resource, DRM_FORMAT_ARGB2101010);
send_modifiers (resource, DRM_FORMAT_RGB565);
+ send_modifiers (resource, DRM_FORMAT_NV12);
+ send_modifiers (resource, DRM_FORMAT_YUV410);
+ send_modifiers (resource, DRM_FORMAT_YVU410);
+ send_modifiers (resource, DRM_FORMAT_YUV411);
+ send_modifiers (resource, DRM_FORMAT_YVU420);
+ send_modifiers (resource, DRM_FORMAT_YVU420);
+ send_modifiers (resource, DRM_FORMAT_YUV422);
+ send_modifiers (resource, DRM_FORMAT_YVU422);
+ send_modifiers (resource, DRM_FORMAT_YUV444);
+ send_modifiers (resource, DRM_FORMAT_YVU444);
}
gboolean
@@ -586,10 +674,12 @@ meta_wayland_dma_buf_buffer_init (MetaWaylandDmaBufBuffer *dma_buf)
{
int i;
- dma_buf->drm_modifier = DRM_FORMAT_MOD_INVALID;
for (i = 0; i < META_WAYLAND_DMA_BUF_MAX_FDS; i++)
- dma_buf->fds[i] = -1;
+ {
+ dma_buf->drm_modifier[i] = DRM_FORMAT_MOD_INVALID;
+ dma_buf->fds[i] = -1;
+ }
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]