[vlc-commits] [Git][videolan/vlc][master] 3 commits: video_filter: opengl: use correct OpenGL flavour

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Fri Jul 7 07:14:15 UTC 2023



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
dac685b7 by Alexandre Janniaux at 2023-07-07T06:44:19+00:00
video_filter: opengl: use correct OpenGL flavour

Use the correct OpenGL flavour (GLES or OpenGL) at runtime by providing
both capabilities, fixing the usage of OpenGL filters through GLES2 on
Linux where both are supported.

The filter only has a single implementation, but will probe both OpenGL
and OpenGL ES2 by default. It can be restricted to a specific flavour by
enforcing a gl module to `any` or any specific implementation. Eg.

    --video-filter=opengl{filter=mock,gles=any}
    --video-filter=opengl{filter=mock,gl=any}
    --video-filter=opengl{filter=mock,gl=any,gles=foo}

OpenGL is favoured when probing since it provides much more
functionality and performance optimization opportunities that its
embedded counterpart. However, when USE_OPENGL_ES2 is defined, it means
that OpenGL headers were not available. In this case, it's highly likely
that OpenGL is **not** available at all and we only probe OpenGL ES
instead.

There are guenuine reasons why it could fail on OpenGL but not on
OpenGL ES, like the presence of an extension like the support for
GL_OES_EGL_image_external or the non-support of anything else but
OpenGL ES with a given version.

- - - - -
dd10f6ba by Alexandre Janniaux at 2023-07-07T06:44:19+00:00
egl_pbuffer allow both OpenGL and GLES2

Provide both the OpenGL offscreen implementation and the GLES2 offscreen
implementation from the same module, since it's the same code.

There is no need to differentiate the name between any of the two
modules, just like we don't need for EGL, because they have distinct
capabilities and are referred by separate objects anyway (--opengl-gl
versus --opengl-gles).

- - - - -
4d100f60 by Alexandre Janniaux at 2023-07-07T06:44:19+00:00
egl_pbuffer: generalize and simplify client_version handling

We can support GL ES3 even if the capability name doesn't reflect that,
since it's mostly a "at least GLES 2". By doing so, we can simplify the
checks on the EGL client version.

- - - - -


2 changed files:

- modules/video_filter/egl_pbuffer.c
- modules/video_filter/opengl.c


Changes:

=====================================
modules/video_filter/egl_pbuffer.c
=====================================
@@ -109,7 +109,19 @@ static void *GetSymbol(vlc_gl_t *gl, const char *procname)
     return (void *)eglGetProcAddress (procname);
 }
 
-static int InitEGL(vlc_gl_t *gl, unsigned width, unsigned height)
+static EGLContext CreateContext(vlc_gl_t *gl, EGLConfig cfg, EGLint client_version)
+{
+    struct vlc_gl_pbuffer *sys = gl->sys;
+
+    const EGLint ctx_attr[] = {
+        EGL_CONTEXT_CLIENT_VERSION, client_version,
+        EGL_NONE
+    };
+
+    return eglCreateContext(sys->display, cfg, EGL_NO_CONTEXT, ctx_attr);
+}
+
+static int InitEGL(vlc_gl_t *gl, int opengl_api, unsigned width, unsigned height)
 {
     struct vlc_gl_pbuffer *sys = gl->sys;
 
@@ -130,36 +142,24 @@ static int InitEGL(vlc_gl_t *gl, unsigned width, unsigned height)
     msg_Dbg(gl, "EGL version %s by %s, API %s",
             eglQueryString(sys->display, EGL_VERSION),
             eglQueryString(sys->display, EGL_VENDOR),
-#ifdef USE_OPENGL_ES2
-            "OpenGL ES2"
-#else
-            "OpenGL"
-#endif
-            );
+            opengl_api == VLC_OPENGL ? "OpenGL" : "OpenGL ES2");
 
     const char *extensions = eglQueryString(sys->display, EGL_EXTENSIONS);
     bool need_surface =
         !vlc_gl_StrHasToken(extensions, "EGL_KHR_surfaceless_context");
 
-    static const EGLint conf_attr_surface[] = {
+    EGLint renderable_type = opengl_api == VLC_OPENGL ? EGL_OPENGL_BIT : EGL_OPENGL_ES2_BIT;
+    const EGLint conf_attr_surface[] = {
         EGL_RED_SIZE, 8,
         EGL_GREEN_SIZE, 8,
         EGL_BLUE_SIZE, 8,
-#ifdef USE_OPENGL_ES2
-        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-#else
-        EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
-#endif
+        EGL_RENDERABLE_TYPE, renderable_type,
         EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
         EGL_NONE,
     };
 
-    static const EGLint conf_attr_surfaceless[] = {
-#ifdef USE_OPENGL_ES2
-        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-#else
-        EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
-#endif
+    const EGLint conf_attr_surfaceless[] = {
+        EGL_RENDERABLE_TYPE, renderable_type,
         EGL_NONE,
     };
 
@@ -198,59 +198,31 @@ static int InitEGL(vlc_gl_t *gl, unsigned width, unsigned height)
     else
         sys->surface = EGL_NO_SURFACE;
 
-#ifdef USE_OPENGL_ES2
-    if (eglBindAPI (EGL_OPENGL_ES_API) != EGL_TRUE)
-    {
-        msg_Err (gl, "cannot bind EGL OPENGL ES API");
-        goto error;
-    }
+    EGLint egl_api;
+    if (opengl_api == VLC_OPENGL_ES2)
+        egl_api = EGL_OPENGL_ES_API;
+    else
+        egl_api = EGL_OPENGL_API;
 
-    const GLint ctx_attr[] = {
-        EGL_CONTEXT_CLIENT_VERSION, 2,
-        EGL_NONE
-    };
-#else
-    if (eglBindAPI (EGL_OPENGL_API) != EGL_TRUE)
+    if (eglBindAPI(egl_api) != EGL_TRUE)
     {
         msg_Err (gl, "cannot bind EGL OPENGL API");
         goto error;
     }
 
-    const GLint ctx_attr[] = {
-        EGL_CONTEXT_CLIENT_VERSION, 3,
-        EGL_NONE
-    };
-#endif
-
-    EGLContext ctx
-        = sys->context
-        = eglCreateContext(sys->display, cfgv[0], EGL_NO_CONTEXT, ctx_attr);
+    EGLContext ctx = CreateContext(gl, cfgv[0], 3);
+    if (ctx != EGL_NO_CONTEXT)
+        goto context_created;
 
-#ifdef USE_OPENGL_ES2
-    if (ctx == EGL_NO_CONTEXT)
-    {
-        msg_Err (gl, "cannot create EGL context");
-        goto error;
-    }
-#else
-    if (ctx == EGL_NO_CONTEXT)
-    {
-        const GLint ctx_attr_fallback[] = {
-            EGL_CONTEXT_CLIENT_VERSION, 2,
-            EGL_NONE
-        };
+    ctx = CreateContext(gl, cfgv[0], 2);
+    if (ctx != EGL_NO_CONTEXT)
+        goto context_created;
 
-        ctx
-            = sys->context
-            = eglCreateContext(sys->display, cfgv[0], EGL_NO_CONTEXT, ctx_attr_fallback);
+    msg_Err (gl, "cannot create EGL context");
+    goto error;
 
-        if (ctx == EGL_NO_CONTEXT)
-        {
-            msg_Err (gl, "cannot create EGL context");
-            goto error;
-        }
-    }
-#endif
+context_created:
+    sys->context = ctx;
 
     return VLC_SUCCESS;
 error:
@@ -422,7 +394,7 @@ static int Open(vlc_gl_t *gl, unsigned width, unsigned height,
 
     gl->sys = sys;
 
-    if (InitEGL(gl, width, height) != VLC_SUCCESS)
+    if (InitEGL(gl, gl->api_type, width, height) != VLC_SUCCESS)
     {
         msg_Err(gl, "Failed to create opengl context\n");
         goto error1;
@@ -495,12 +467,11 @@ error1:
 }
 
 vlc_module_begin()
+    add_shortcut( "egl_pbuffer" )
     set_shortname( N_("egl_pbuffer") )
     set_description( N_("EGL PBuffer offscreen opengl provider") )
-#ifdef USE_OPENGL_ES2
-    set_callback_opengl_es2_offscreen( Open, 1 )
-#else
     set_callback_opengl_offscreen( Open, 1 )
-#endif
-    add_shortcut( "egl_pbuffer" )
+
+    add_submodule()
+    set_callback_opengl_es2_offscreen( Open, 1 )
 vlc_module_end()


=====================================
modules/video_filter/opengl.c
=====================================
@@ -38,7 +38,7 @@
 #include "../video_output/opengl/interop.h"
 
 #define OPENGL_CFG_PREFIX "opengl-"
-static const char *const opengl_options[] = { "filter", NULL };
+static const char *const opengl_options[] = { "filter", "gl", "gles", NULL };
 
 typedef struct
 {
@@ -162,7 +162,68 @@ static void Close( filter_t *filter )
     }
 }
 
-static int Open( vlc_object_t *obj )
+static vlc_gl_t *CreateGL(vlc_object_t *obj, struct vlc_decoder_device *device,
+                          unsigned width, unsigned height)
+{
+
+#ifdef USE_OPENGL_ES2
+    char *opengles_name = var_InheritString(obj, "opengl-gles");
+    vlc_gl_t *gl = vlc_gl_CreateOffscreen(obj, device, width, height,
+                                         VLC_OPENGL_ES2, opengles_name, NULL);
+    free(opengles_name);
+    return gl;
+#else
+    vlc_gl_t *gl = NULL;
+    char *opengl_name = var_InheritString(obj, "opengl-gl");
+    char *opengles_name = var_InheritString(obj, "opengl-gles");
+
+    const char *gl_module = opengl_name;
+    const char *gles_module = opengles_name;
+
+    if (EMPTY_STR(gl_module))
+    {
+        if (EMPTY_STR(opengles_name) || strcmp(opengles_name, "none") == 0)
+        {
+            gl_module = "any";
+        }
+        else
+        {
+            gl_module = NULL;
+        }
+    }
+
+    if (EMPTY_STR(gles_module))
+    {
+        if (EMPTY_STR(opengl_name) || strcmp(opengl_name, "none") == 0)
+        {
+            gles_module = "any";
+        }
+        else
+        {
+            gles_module = NULL;
+        }
+    }
+
+    if (opengl_name == NULL)
+        opengl_name = strdup("");
+
+    if (gl_module != NULL)
+        gl = vlc_gl_CreateOffscreen(obj, device, width, height,
+                                         VLC_OPENGL, gl_module, NULL);
+    if (gl != NULL)
+        goto end;
+
+    if (gles_module != NULL)
+        gl = vlc_gl_CreateOffscreen(obj, device, width, height,
+                                         VLC_OPENGL_ES2, opengles_name, NULL);
+end:
+    free(opengl_name);
+    free(opengles_name);
+    return gl;
+#endif
+}
+
+static int OpenOpenGL(vlc_object_t *obj)
 {
     filter_t *filter = (filter_t *)obj;
 
@@ -172,19 +233,14 @@ static int Open( vlc_object_t *obj )
     if (sys == NULL)
         return VLC_ENOMEM;
 
+    config_ChainParse(filter, OPENGL_CFG_PREFIX, opengl_options, filter->p_cfg);
+
     unsigned width = filter->fmt_out.video.i_visible_width;
     unsigned height = filter->fmt_out.video.i_visible_height;
 
-    // TODO: other than BGRA format ?
-#ifdef USE_OPENGL_ES2
-# define VLCGLAPI VLC_OPENGL_ES2
-#else
-# define VLCGLAPI VLC_OPENGL
-#endif
-
     struct vlc_decoder_device *device = filter_HoldDecoderDevice(filter);
-    sys->gl = vlc_gl_CreateOffscreen(obj, device, width, height, VLCGLAPI,
-                                     NULL, NULL);
+
+    sys->gl = CreateGL(obj, device, width, height);
 
     /* The vlc_gl_t instance must have hold the device if it needs it. */
     if (device)
@@ -218,8 +274,6 @@ static int Open( vlc_object_t *obj )
         goto gl_interop_failure;
     }
 
-    config_ChainParse(filter, OPENGL_CFG_PREFIX, opengl_options, filter->p_cfg);
-
     char *glfilters_config =
         var_InheritString(filter, OPENGL_CFG_PREFIX "filter");
     if (!glfilters_config)
@@ -311,9 +365,13 @@ vlc_module_begin()
     set_shortname( N_("opengl") )
     set_description( N_("Opengl filter executor") )
     set_subcategory( SUBCAT_VIDEO_VFILTER )
-    set_capability( "video filter", 0 )
+    set_capability( "video filter", 1 )
     add_shortcut( "opengl" )
-    set_callback( Open )
+    set_callback( OpenOpenGL )
     add_module_list( "opengl-filter", "opengl filter", NULL,
                      FILTER_LIST_TEXT, FILTER_LIST_LONGTEXT )
+    add_module( "opengl-gl", "opengl offscreen", "", "OpenGL provider",
+                "OpenGL provider to execute the filters with" )
+    add_module("opengl-gles", "opengl es2 offscreen", "", "OpenGL ES2 provider",
+               "OpenGL ES2 provider to execute the filters with")
 vlc_module_end()



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/28d1b42626fdd7a430709e978400c7565b1bac28...4d100f6028f71979d7348988f447c7702f8479e2

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/28d1b42626fdd7a430709e978400c7565b1bac28...4d100f6028f71979d7348988f447c7702f8479e2
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list