libs: egl: surface: export EGLImage as DMABuf not as GEM

This code path is used when frames are rendered as textures through
GstVideoGLTextureUploadMeta with EGL, mainly under Wayland.

Oringally the EGLImage was exported as GEM, which was handled by
the intel-vaapi-driver, but gallium cannot create VA surfaces from
GEM buffers, breaking the decoding.

This patch replace the exporting of EGLImages from GEM to DMABuf.

DMABuf is well handled either by intel-vaapi-driver and gallium.

Fixes: #137
parent 42472fb5
Pipeline #59196 passed with stages
in 61 minutes and 44 seconds
......@@ -130,6 +130,26 @@ EGL_PROTO_ARG(stride, EGLint *))
EGL_PROTO_INVOKE(ExportDRMImageMESA, EGLBoolean, (dpy, image, name, handle, stride))
EGL_PROTO_END()
EGL_PROTO_BEGIN(ExportDMABUFImageMESA, EGLBoolean, MESA_image_dma_buf_export)
EGL_PROTO_ARG_LIST(
EGL_PROTO_ARG(dpy, EGLDisplay),
EGL_PROTO_ARG(image, EGLImageKHR),
EGL_PROTO_ARG(fds, int *),
EGL_PROTO_ARG(strides, EGLint *),
EGL_PROTO_ARG(offsets, EGLint *))
EGL_PROTO_INVOKE(ExportDMABUFImageMESA, EGLBoolean, (dpy, image, fds, strides, offsets))
EGL_PROTO_END()
EGL_PROTO_BEGIN(ExportDMABUFImageQueryMESA, EGLBoolean, MESA_image_dma_buf_export)
EGL_PROTO_ARG_LIST(
EGL_PROTO_ARG(dpy, EGLDisplay),
EGL_PROTO_ARG(image, EGLImageKHR),
EGL_PROTO_ARG(fourcc, int *),
EGL_PROTO_ARG(num_planes, int *),
EGL_PROTO_ARG(modifiers, EGLuint64KHR *))
EGL_PROTO_INVOKE(ExportDMABUFImageQueryMESA, EGLBoolean, (dpy, image, fourcc, num_planes, modifiers))
EGL_PROTO_END()
EGL_DEFINE_EXTENSION(EXT_image_dma_buf_import)
EGL_DEFINE_EXTENSION(KHR_create_context)
EGL_DEFINE_EXTENSION(KHR_gl_texture_2D_image)
......@@ -137,6 +157,7 @@ EGL_DEFINE_EXTENSION(KHR_image_base)
EGL_DEFINE_EXTENSION(KHR_surfaceless_context)
EGL_DEFINE_EXTENSION(MESA_configless_context)
EGL_DEFINE_EXTENSION(MESA_drm_image)
EGL_DEFINE_EXTENSION(MESA_image_dma_buf_export)
GL_PROTO_BEGIN(GetError, GLenum, CORE_1_0)
GL_PROTO_ARG_LIST()
......
......@@ -46,47 +46,56 @@ do_create_surface_with_egl_image_unlocked (GstVaapiDisplayEGL * display,
GstVaapiDisplay *const base_display = GST_VAAPI_DISPLAY_CAST (display);
EglContext *const ctx = GST_VAAPI_DISPLAY_EGL_CONTEXT (display);
EglVTable *vtable;
gsize size, offset[GST_VIDEO_MAX_PLANES];
gint name, stride[GST_VIDEO_MAX_PLANES];
int num_planes, fd;
EGLint offset = 0;
EGLint stride = 0;
GstVideoInfo vi;
if (!ctx || !(vtable = egl_context_get_vtable (ctx, FALSE)))
return NULL;
memset (offset, 0, sizeof (offset));
memset (stride, 0, sizeof (stride));
if (!vtable->has_EGL_MESA_drm_image)
if (!vtable->has_EGL_MESA_image_dma_buf_export)
goto error_mission_extension;
if (!vtable->eglExportDMABUFImageQueryMESA (ctx->display->base.handle.p,
image, NULL, &num_planes, NULL))
goto error_export_dma_buf_image_query;
/* Don't allow multi-plane dmabufs */
if (num_planes < 1)
goto error_bad_num_planes;
/* EGL_MESA_drm_image extension */
if (!vtable->eglExportDRMImageMESA (ctx->display->base.handle.p, image,
&name, NULL, &stride[0]))
goto error_export_image_gem_buf;
size = height * stride[0];
/*
* XXX: The below surface creation may fail on Intel due to:
* https://github.com/01org/intel-vaapi-driver/issues/222
* A permanent fix for that problem will be released in intel-vaapi-driver
* version 1.8.4 and later, and also in 1.8.3-1ubuntu1.
* However if you don't have that fix then a simple workaround is to
* uncomment this line of code:
* size = GST_ROUND_UP_32 (height) * stride[0];
*/
return gst_vaapi_surface_new_with_gem_buf_handle (base_display, name, size,
format, width, height, offset, stride);
if (!vtable->eglExportDMABUFImageMESA (ctx->display->base.handle.p, image,
&fd, &stride, &offset))
goto error_export_dma_buf_image;
gst_video_info_set_format (&vi, format, width, height);
GST_VIDEO_INFO_PLANE_OFFSET (&vi, 0) = offset;
GST_VIDEO_INFO_PLANE_STRIDE (&vi, 0) = stride;
return gst_vaapi_surface_new_with_dma_buf_handle (base_display, fd, &vi);
/* ERRORS */
error_export_image_gem_buf:
error_export_dma_buf_image_query:
{
GST_ERROR ("failed to query EGL image for dmabuf export");
return NULL;
}
error_bad_num_planes:
{
GST_ERROR ("multi-planed dmabufs are not supported");
return NULL;
}
error_export_dma_buf_image:
{
GST_ERROR ("failed to export EGL image to GEM buffer");
GST_ERROR ("failed to export EGL image to DMABuf");
return NULL;
}
error_mission_extension:
{
GST_ERROR ("missing EGL_MESA_drm_image extension");
GST_ERROR ("missing EGL_MESA_image_dma_buf_export extension");
return NULL;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment