[vlc-commits] [Git][videolan/vlc][master] 6 commits: egl: move interop code to vaapi

Hugo Beauzée-Luyssen (@chouquette) gitlab at videolan.org
Thu Nov 18 10:00:03 UTC 2021



Hugo Beauzée-Luyssen pushed to branch master at VideoLAN / VLC


Commits:
3cd47204 by Alexandre Janniaux at 2021-11-18T09:37:55+00:00
egl: move interop code to vaapi

This will use extensions from EGL directly into interop_vaapi, instead
of using those loaded by EGL.

The only users of those extensions are interop modules, so only
interop_vaapi for extension related to EGL integration.

By moving the loading of those extension to the interop, we can have
them working even when the OpenGL platform context is provided by the
vglmem (vgl.c) module callbacks, allowing hardware acceleration even
when using the libvlc OpenGL callbacks.

Filters would likely be using only OpenGL extensions that are already
available, but could be using the same mechanism in the worst-case
scenario.

This patch is the EGL equivalent of the same[¹] version merged for WGL
but it doesn't directly enable hardware decoding for the non-EGL_EXT
clients, since interop_vaapi still requires EGL_EXT for QueryString.

[^1]: c48c0a6192eb4c0d138861962b3405d4c4ded80b

Refs #25234, #25256

- - - - -
415a4a85 by Alexandre Janniaux at 2021-11-18T09:37:55+00:00
interop_vaapi: refactor error path

Redirect to the error label in every non-trivial cases.

- - - - -
168bbe6c by Alexandre Janniaux at 2021-11-18T09:37:55+00:00
interop_vaapi: use eglQueryString from GetProcAddress

This allows using the correct implementation for EGL to query the
information for, even when multiple implementation are existing in
different plugins or modules both in the dynamic case or (with partial
linking) the static case.

This effectively makes the interop independant of which EGL
implementation is provided to OpenGL and allows implementation from vgl
callbacks to use vaapi for decoding.

Fix #25256

- - - - -
f7dac0f3 by Alexandre Janniaux at 2021-11-18T09:37:55+00:00
egl_pbuffer: remove now unused extension code

The vlc_gl_t clients are not using the extensions from vlc_gl_t anymore,
so we can remove this now.

- - - - -
d6bf6d3e by Alexandre Janniaux at 2021-11-18T09:37:55+00:00
egl_surfacetexture: remove now unused extension code

The vlc_gl_t clients are not using the extensions from vlc_gl_t anymore,
so we can remove this now.

- - - - -
5b7d875c by Alexandre Janniaux at 2021-11-18T09:37:55+00:00
egl: remove now useless VLC_OPENGL_EXT_*

EGL is now dynamically detected, so there is no point in signalling that
the implementation supports EGL-based extensions, which were not
compatible with libvlc callbacks.

WGL extensions were already made dynamics through previous[^1] similar
commits, and it was only write and never read.

Android was also setting VLC_OPENGL_EXT_EGL for the sake of completness
but didn't actually made use of it. Most of the checks are made through
the availability of the `GL_OES_EGL_image_external` OpenGL extension
which doesn't involve the OpenGL provider API at all.

[^1]: c48c0a6192eb4c0d138861962b3405d4c4ded80b

- - - - -


6 changed files:

- include/vlc_opengl.h
- modules/video_filter/egl_pbuffer.c
- modules/video_filter/egl_surfacetexture.c
- modules/video_output/opengl/egl.c
- modules/video_output/opengl/interop_vaapi.c
- modules/video_output/win32/wgl.c


Changes:

=====================================
include/vlc_opengl.h
=====================================
@@ -76,31 +76,6 @@ struct vlc_gl_t
     void*(*get_proc_address)(vlc_gl_t *, const char *);
     void (*destroy)(vlc_gl_t *);
 
-    enum {
-        VLC_GL_EXT_DEFAULT,
-        VLC_GL_EXT_EGL,
-        VLC_GL_EXT_WGL,
-    } ext;
-
-    union {
-        /* if ext == VLC_GL_EXT_EGL */
-        struct {
-            /* call eglQueryString() with current display */
-            const char *(*queryString)(vlc_gl_t *, int32_t name);
-            /* call eglCreateImageKHR() with current display and context, can
-             * be NULL */
-            void *(*createImageKHR)(vlc_gl_t *, unsigned target, void *buffer,
-                                    const int32_t *attrib_list);
-            /* call eglDestroyImageKHR() with current display, can be NULL */
-            bool (*destroyImageKHR)(vlc_gl_t *, void *image);
-        } egl;
-        /* if ext == VLC_GL_EXT_WGL */
-        struct
-        {
-            const char *(*getExtensionsString)(vlc_gl_t *);
-        } wgl;
-    };
-
     /* Defined by the core for libvlc_opengl API loading. */
     enum vlc_gl_api_type api_type;
 };


=====================================
modules/video_filter/egl_pbuffer.c
=====================================
@@ -71,9 +71,6 @@ struct vlc_gl_pbuffer
     EGLSurface surface;
     EGLContext context;
 
-    PFNEGLCREATEIMAGEKHRPROC    eglCreateImageKHR;
-    PFNEGLDESTROYIMAGEKHRPROC   eglDestroyImageKHR;
-
     bool current;
 };
 
@@ -107,29 +104,6 @@ static void *GetSymbol(vlc_gl_t *gl, const char *procname)
     return (void *)eglGetProcAddress (procname);
 }
 
-static const char *QueryString(vlc_gl_t *gl, int32_t name)
-{
-    struct vlc_gl_pbuffer *sys = gl->sys;
-
-    return eglQueryString(sys->display, name);
-}
-
-static void *CreateImageKHR(vlc_gl_t *gl, unsigned target, void *buffer,
-                            const int32_t *attrib_list)
-{
-    struct vlc_gl_pbuffer *sys = gl->sys;
-
-    return sys->eglCreateImageKHR(sys->display, NULL, target, buffer,
-                                  attrib_list);
-}
-
-static bool DestroyImageKHR(vlc_gl_t *gl, void *image)
-{
-    struct vlc_gl_pbuffer *sys = gl->sys;
-
-    return sys->eglDestroyImageKHR(sys->display, image);
-}
-
 static int InitEGL(vlc_gl_t *gl, unsigned width, unsigned height)
 {
     struct vlc_gl_pbuffer *sys = gl->sys;
@@ -422,24 +396,14 @@ static int Open(vlc_gl_t *gl, unsigned width, unsigned height)
         goto error1;
     }
 
-    gl->ext = VLC_GL_EXT_EGL;
     gl->make_current = MakeCurrent;
     gl->release_current = ReleaseCurrent;
     gl->resize = NULL;
     gl->swap_offscreen = Swap;
     gl->get_proc_address = GetSymbol;
     gl->destroy = Close;
-    gl->egl.queryString = QueryString;
     gl->offscreen_vflip = true;
 
-    sys->eglCreateImageKHR = (void *)eglGetProcAddress("eglCreateImageKHR");
-    sys->eglDestroyImageKHR = (void *)eglGetProcAddress("eglDestroyImageKHR");
-    if (sys->eglCreateImageKHR != NULL && sys->eglDestroyImageKHR != NULL)
-    {
-        gl->egl.createImageKHR = CreateImageKHR;
-        gl->egl.destroyImageKHR = DestroyImageKHR;
-    }
-
     vlc_gl_MakeCurrent(gl);
     int ret = vlc_gl_api_Init(&sys->api, gl);
     if (ret != VLC_SUCCESS)


=====================================
modules/video_filter/egl_surfacetexture.c
=====================================
@@ -69,9 +69,6 @@ struct surfacetexture_sys
 
     EGLConfig cfgv;
 
-    PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;
-    PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR;
-
     picture_t *current_picture;
 };
 
@@ -113,31 +110,6 @@ static void *GetSymbol(vlc_gl_t *gl, const char *procname)
     return (void *)eglGetProcAddress(procname);
 }
 
-static const char *QueryString(vlc_gl_t *gl, int32_t name)
-{
-    struct video_ctx *vctx = GetVCtx(gl);
-
-    return eglQueryString(vctx->display, name);
-}
-
-static void *CreateImageKHR(vlc_gl_t *gl, unsigned target, void *buffer,
-                            const int32_t *attrib_list)
-{
-    struct surfacetexture_sys *sys = gl->sys;
-    struct video_ctx *vctx = GetVCtx(gl);
-
-    return sys->eglCreateImageKHR(vctx->display, NULL, target, buffer,
-                                  attrib_list);
-}
-
-static bool DestroyImageKHR(vlc_gl_t *gl, void *image)
-{
-    struct surfacetexture_sys *sys = gl->sys;
-    struct video_ctx *vctx = GetVCtx(gl);
-
-    return sys->eglDestroyImageKHR(vctx->display, image);
-}
-
 static picture_context_t *CopyPictureContext(picture_context_t *input)
 {
     vlc_video_context_Hold(input->vctx);
@@ -394,27 +366,15 @@ static int Open(vlc_gl_t *gl, unsigned width, unsigned height)
         goto error2;
     }
 
-    gl->ext = VLC_GL_EXT_EGL;
     gl->make_current = MakeCurrent;
     gl->release_current = ReleaseCurrent;
     gl->resize = NULL;
     gl->swap_offscreen = SwapOffscreen;
     gl->get_proc_address = GetSymbol;
     gl->destroy = Close;
-    gl->egl.queryString = QueryString;
 
     struct video_ctx *vctx = GetVCtx(gl);
 
-    sys->eglCreateImageKHR =
-        (PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress("eglCreateImageKHR");
-    sys->eglDestroyImageKHR =
-        (PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress("eglDestroyImageKHR");
-    if (sys->eglCreateImageKHR != NULL && sys->eglDestroyImageKHR != NULL)
-    {
-        gl->egl.createImageKHR = CreateImageKHR;
-        gl->egl.destroyImageKHR = DestroyImageKHR;
-    }
-
     if (InitPicturePool(gl) != VLC_SUCCESS)
         goto error3;
 


=====================================
modules/video_output/opengl/egl.c
=====================================
@@ -54,8 +54,6 @@ typedef struct vlc_gl_sys_t
 #if defined (USE_PLATFORM_WAYLAND)
     struct wl_egl_window *window;
 #endif
-    PFNEGLCREATEIMAGEKHRPROC    eglCreateImageKHR;
-    PFNEGLDESTROYIMAGEKHRPROC   eglDestroyImageKHR;
 } vlc_gl_sys_t;
 
 static int MakeCurrent (vlc_gl_t *gl)
@@ -100,29 +98,6 @@ static void *GetSymbol(vlc_gl_t *gl, const char *procname)
     return (void *)eglGetProcAddress (procname);
 }
 
-static const char *QueryString(vlc_gl_t *gl, int32_t name)
-{
-    vlc_gl_sys_t *sys = gl->sys;
-
-    return eglQueryString(sys->display, name);
-}
-
-static void *CreateImageKHR(vlc_gl_t *gl, unsigned target, void *buffer,
-                            const int32_t *attrib_list)
-{
-    vlc_gl_sys_t *sys = gl->sys;
-
-    return sys->eglCreateImageKHR(sys->display, NULL, target, buffer,
-                                  attrib_list);
-}
-
-static bool DestroyImageKHR(vlc_gl_t *gl, void *image)
-{
-    vlc_gl_sys_t *sys = gl->sys;
-
-    return sys->eglDestroyImageKHR(sys->display, image);
-}
-
 static bool CheckAPI (EGLDisplay dpy, const char *api)
 {
     const char *apis = eglQueryString (dpy, EGL_CLIENT_APIS);
@@ -217,8 +192,6 @@ static int Open(vlc_gl_t *gl, const struct gl_api *api,
     sys->display = EGL_NO_DISPLAY;
     sys->surface = EGL_NO_SURFACE;
     sys->context = EGL_NO_CONTEXT;
-    sys->eglCreateImageKHR = NULL;
-    sys->eglDestroyImageKHR = NULL;
 
     vout_window_t *wnd = gl->surface;
     EGLSurface (*createSurface)(EGLDisplay, EGLConfig, void *, const EGLint *)
@@ -387,22 +360,12 @@ static int Open(vlc_gl_t *gl, const struct gl_api *api,
     sys->context = ctx;
 
     /* Initialize OpenGL callbacks */
-    gl->ext = VLC_GL_EXT_EGL;
     gl->make_current = MakeCurrent;
     gl->release_current = ReleaseCurrent;
     gl->resize = Resize;
     gl->swap = SwapBuffers;
     gl->get_proc_address = GetSymbol;
     gl->destroy = Close;
-    gl->egl.queryString = QueryString;
-
-    sys->eglCreateImageKHR = (void *)eglGetProcAddress("eglCreateImageKHR");
-    sys->eglDestroyImageKHR = (void *)eglGetProcAddress("eglDestroyImageKHR");
-    if (sys->eglCreateImageKHR != NULL && sys->eglDestroyImageKHR != NULL)
-    {
-        gl->egl.createImageKHR = CreateImageKHR;
-        gl->egl.destroyImageKHR = DestroyImageKHR;
-    }
 
     return VLC_SUCCESS;
 


=====================================
modules/video_output/opengl/interop_vaapi.c
=====================================
@@ -61,6 +61,16 @@ struct priv
     VASurfaceID *va_surface_ids;
     PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;
 
+    struct
+    {
+        EGLDisplay display;
+        EGLDisplay (*getCurrentDisplay)();
+        const char *(*queryString)(EGLDisplay, EGLint);
+        EGLImage (*createImageKHR)(EGLDisplay, EGLContext, EGLenum target, EGLClientBuffer buffer,
+                const EGLint *attrib_list);
+        void (*destroyImageKHR)(EGLDisplay, EGLImage image);
+    } egl;
+
     unsigned fourcc;
     EGLint drm_fourccs[3];
 
@@ -83,7 +93,8 @@ vaegl_image_create(const struct vlc_gl_interop *interop, EGLint w, EGLint h,
                    EGLint fourcc, EGLint fd, EGLint offset, EGLint pitch,
                    EGLuint64KHR modifier)
 {
-    EGLint attribs[] = {
+    struct priv *priv = interop->priv;
+    const EGLint attribs[] = {
         EGL_WIDTH, w,
         EGL_HEIGHT, h,
         EGL_LINUX_DRM_FOURCC_EXT, fourcc,
@@ -95,14 +106,15 @@ vaegl_image_create(const struct vlc_gl_interop *interop, EGLint w, EGLint h,
         EGL_NONE
     };
 
-    return interop->gl->egl.createImageKHR(interop->gl, EGL_LINUX_DMA_BUF_EXT,
-                                           NULL, attribs);
+    return priv->egl.createImageKHR(priv->egl.display,
+            EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
 }
 
 static void
 vaegl_image_destroy(const struct vlc_gl_interop *interop, EGLImageKHR image)
 {
-    interop->gl->egl.destroyImageKHR(interop->gl, image);
+    struct priv *priv = interop->priv;
+    priv->egl.destroyImageKHR(priv->egl.display, image);
 }
 
 static void
@@ -418,34 +430,21 @@ static int
 Open(vlc_object_t *obj)
 {
     struct vlc_gl_interop *interop = (void *) obj;
+    struct priv *priv = NULL;
 
     if (interop->vctx == NULL)
         return VLC_EGENERIC;
     vlc_decoder_device *dec_device = vlc_video_context_HoldDevice(interop->vctx);
     if (dec_device->type != VLC_DECODER_DEVICE_VAAPI
-     || !vlc_vaapi_IsChromaOpaque(interop->fmt_in.i_chroma)
-     || interop->gl->ext != VLC_GL_EXT_EGL
-     || interop->gl->egl.createImageKHR == NULL
-     || interop->gl->egl.destroyImageKHR == NULL)
+     || !vlc_vaapi_IsChromaOpaque(interop->fmt_in.i_chroma))
     {
-        vlc_decoder_device_Release(dec_device);
-        return VLC_EGENERIC;
+        goto error;
     }
 
     if (!vlc_gl_StrHasToken(interop->api->extensions, "GL_OES_EGL_image"))
-    {
-        vlc_decoder_device_Release(dec_device);
-        return VLC_EGENERIC;
-    }
-
-    const char *eglexts = interop->gl->egl.queryString(interop->gl, EGL_EXTENSIONS);
-    if (eglexts == NULL || !vlc_gl_StrHasToken(eglexts, "EGL_EXT_image_dma_buf_import"))
-    {
-        vlc_decoder_device_Release(dec_device);
-        return VLC_EGENERIC;
-    }
+        goto error;
 
-    struct priv *priv = interop->priv = calloc(1, sizeof(struct priv));
+    priv = interop->priv = calloc(1, sizeof(struct priv));
     if (unlikely(priv == NULL))
         goto error;
     priv->fourcc = 0;
@@ -469,6 +468,33 @@ Open(vlc_object_t *obj)
     if (vaegl_init_fourcc(priv, va_fourcc))
         goto error;
 
+    priv->egl.getCurrentDisplay = vlc_gl_GetProcAddress(interop->gl, "eglGetCurrentDisplay");
+    if (priv->egl.getCurrentDisplay == EGL_NO_DISPLAY)
+        goto error;
+
+    priv->egl.display = priv->egl.getCurrentDisplay();
+    if (priv->egl.display == EGL_NO_DISPLAY)
+        goto error;
+
+    priv->egl.queryString = vlc_gl_GetProcAddress(interop->gl, "eglQueryString");
+    if (priv->egl.queryString == NULL)
+        goto error;
+
+    /* EGL_EXT_image_dma_buf_import implies EGL_KHR_image_base */
+    const char *eglexts = priv->egl.queryString(priv->egl.display, EGL_EXTENSIONS);
+    if (eglexts == NULL || !vlc_gl_StrHasToken(eglexts, "EGL_EXT_image_dma_buf_import"))
+        goto error;
+
+    priv->egl.createImageKHR =
+        vlc_gl_GetProcAddress(interop->gl, "eglCreateImageKHR");
+    if (priv->egl.createImageKHR == NULL)
+        goto error;
+
+    priv->egl.destroyImageKHR =
+        vlc_gl_GetProcAddress(interop->gl, "eglDestroyImageKHR");
+    if (priv->egl.destroyImageKHR == NULL)
+        goto error;
+
     priv->glEGLImageTargetTexture2DOES =
         vlc_gl_GetProcAddress(interop->gl, "glEGLImageTargetTexture2DOES");
     if (priv->glEGLImageTargetTexture2DOES == NULL)


=====================================
modules/video_output/win32/wgl.c
=====================================
@@ -219,7 +219,6 @@ static int Open(vlc_gl_t *gl, unsigned width, unsigned height)
 
     wglMakeCurrent(sys->hGLDC, NULL);
 
-    gl->ext = VLC_GL_EXT_WGL;
     gl->make_current = MakeCurrent;
     gl->release_current = ReleaseCurrent;
     gl->resize = NULL;



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/f80e843cbc8df2c734d559c9b5bf4da7db81ffac...5b7d875cdde8ef65475e6a4fdcd2c8523ee3538e

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/f80e843cbc8df2c734d559c9b5bf4da7db81ffac...5b7d875cdde8ef65475e6a4fdcd2c8523ee3538e
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list