[vlc-devel] [PATCH 31/41] opengl: store fragment shader in sampler

Romain Vimont rom1v at videolabs.io
Fri Feb 7 17:42:17 CET 2020


The function opengl_fragment_shader_init() both initializes the
and creates the fragment shader.

To be able to move its initialization outside the renderer, store it in
the sampler instead of returning it. This will also allow to provide the
"extensions" part of the fragment shader as a separate string.
---
 .../video_output/opengl/fragment_shaders.c    | 24 ++++++++++++-------
 modules/video_output/opengl/internal.h        |  2 +-
 modules/video_output/opengl/renderer.c        |  9 ++++---
 modules/video_output/opengl/sampler.c         |  4 ++++
 modules/video_output/opengl/sampler.h         | 12 ++++++++++
 5 files changed, 36 insertions(+), 15 deletions(-)

diff --git a/modules/video_output/opengl/fragment_shaders.c b/modules/video_output/opengl/fragment_shaders.c
index 6661a3746d..eb84a9ec0f 100644
--- a/modules/video_output/opengl/fragment_shaders.c
+++ b/modules/video_output/opengl/fragment_shaders.c
@@ -352,7 +352,7 @@ sampler_xyz12_prepare_shader(const struct vlc_gl_sampler *sampler)
     vt->Uniform1i(sampler->uloc.Texture[0], 0);
 }
 
-static char *
+static int
 xyz12_shader_init(struct vlc_gl_sampler *sampler)
 {
     sampler->pf_fetch_locations = sampler_xyz12_fetch_locations;
@@ -387,7 +387,11 @@ xyz12_shader_init(struct vlc_gl_sampler *sampler)
         " return v_out;"
         "}\n";
 
-    return strdup(template);
+    sampler->shader.body = strdup(template);
+    if (!sampler->shader.body)
+        return VLC_ENOMEM;
+
+    return VLC_SUCCESS;
 }
 
 static int
@@ -449,7 +453,7 @@ opengl_init_swizzle(const struct vlc_gl_interop *interop,
     return VLC_SUCCESS;
 }
 
-char *
+int
 opengl_fragment_shader_init(struct vlc_gl_sampler *sampler, GLenum tex_target,
                             vlc_fourcc_t chroma, video_color_space_t yuv_space)
 {
@@ -462,7 +466,7 @@ opengl_fragment_shader_init(struct vlc_gl_sampler *sampler, GLenum tex_target,
 
     const vlc_chroma_description_t *desc = vlc_fourcc_GetChromaDescription(chroma);
     if (desc == NULL)
-        return NULL;
+        return VLC_EGENERIC;
 
     if (chroma == VLC_CODEC_XYZ12)
         return xyz12_shader_init(sampler);
@@ -471,10 +475,10 @@ opengl_fragment_shader_init(struct vlc_gl_sampler *sampler, GLenum tex_target,
     {
         ret = sampler_yuv_base_init(sampler, chroma, desc, yuv_space);
         if (ret != VLC_SUCCESS)
-            return NULL;
+            return ret;
         ret = opengl_init_swizzle(interop, swizzle_per_tex, chroma, desc);
         if (ret != VLC_SUCCESS)
-            return NULL;
+            return ret;
     }
 
     const char *sampler_name, *lookup;
@@ -498,7 +502,7 @@ opengl_fragment_shader_init(struct vlc_gl_sampler *sampler, GLenum tex_target,
 
     struct vlc_memstream ms;
     if (vlc_memstream_open(&ms) != 0)
-        return NULL;
+        return ret;
 
 #define ADD(x) vlc_memstream_puts(&ms, x)
 #define ADDF(x, ...) vlc_memstream_printf(&ms, x, ##__VA_ARGS__)
@@ -661,10 +665,12 @@ opengl_fragment_shader_init(struct vlc_gl_sampler *sampler, GLenum tex_target,
 #undef ADDF
 
     if (vlc_memstream_close(&ms) != 0)
-        return NULL;
+        return VLC_EGENERIC;
+
+    sampler->shader.body = ms.ptr;
 
     sampler->pf_fetch_locations = sampler_base_fetch_locations;
     sampler->pf_prepare_shader = sampler_base_prepare_shader;
 
-    return ms.ptr;
+    return VLC_SUCCESS;
 }
diff --git a/modules/video_output/opengl/internal.h b/modules/video_output/opengl/internal.h
index a6e4101663..14946de3f9 100644
--- a/modules/video_output/opengl/internal.h
+++ b/modules/video_output/opengl/internal.h
@@ -28,7 +28,7 @@ int
 opengl_interop_init_impl(struct vlc_gl_interop *interop, GLenum tex_target,
                          vlc_fourcc_t chroma, video_color_space_t yuv_space);
 
-char *
+int
 opengl_fragment_shader_init(struct vlc_gl_sampler *sampler,
                             GLenum, vlc_fourcc_t, video_color_space_t);
 int
diff --git a/modules/video_output/opengl/renderer.c b/modules/video_output/opengl/renderer.c
index b620d0d0a9..9440238080 100644
--- a/modules/video_output/opengl/renderer.c
+++ b/modules/video_output/opengl/renderer.c
@@ -270,11 +270,11 @@ BuildFragmentShader(struct vlc_gl_renderer *renderer)
 {
     struct vlc_gl_sampler *sampler = renderer->sampler;
     const struct vlc_gl_interop *interop = sampler->interop;
-    char *vlc_texture =
+    int ret =
         opengl_fragment_shader_init(sampler, interop->tex_target,
                                     interop->sw_fmt.i_chroma,
                                     interop->sw_fmt.space);
-    if (!vlc_texture)
+    if (ret != VLC_SUCCESS)
         return NULL;
 
     static const char *template =
@@ -293,9 +293,8 @@ BuildFragmentShader(struct vlc_gl_renderer *renderer)
                            : "";
 
     char *code;
-    int ret = asprintf(&code, template, renderer->glsl_version, extensions,
-                       renderer->glsl_precision_header, vlc_texture);
-    free(vlc_texture);
+    ret = asprintf(&code, template, renderer->glsl_version, extensions,
+                   renderer->glsl_precision_header, sampler->shader.body);
     if (ret < 0)
         return NULL;
 
diff --git a/modules/video_output/opengl/sampler.c b/modules/video_output/opengl/sampler.c
index 176b0c8e9e..915f8c19c5 100644
--- a/modules/video_output/opengl/sampler.c
+++ b/modules/video_output/opengl/sampler.c
@@ -44,6 +44,8 @@ vlc_gl_sampler_New(struct vlc_gl_interop *interop)
     sampler->gl = interop->gl;
     sampler->vt = interop->vt;
 
+    sampler->shader.body = NULL;
+
 #ifdef HAVE_LIBPLACEBO
     // Create the main libplacebo context
     sampler->pl_ctx = vlc_placebo_Create(VLC_OBJECT(interop->gl));
@@ -103,5 +105,7 @@ vlc_gl_sampler_Delete(struct vlc_gl_sampler *sampler)
         pl_context_destroy(&sampler->pl_ctx);
 #endif
 
+    free(sampler->shader.body);
+
     free(sampler);
 }
diff --git a/modules/video_output/opengl/sampler.h b/modules/video_output/opengl/sampler.h
index cec8e68e72..0640715a3c 100644
--- a/modules/video_output/opengl/sampler.h
+++ b/modules/video_output/opengl/sampler.h
@@ -91,6 +91,18 @@ struct vlc_gl_sampler {
 
     struct vlc_gl_interop *interop;
 
+    struct {
+        /* Piece of code necessary to declare and implement the GLSL function
+         * vlc_texture(vec2 coords).
+         *
+         * It must be injected in the fragment shader before calling this
+         * function.
+         *
+         * It may not be NULL.
+         */
+        char *body;
+    } shader;
+
     /**
      * Callback to fetch locations of uniform or attributes variables
      *
-- 
2.25.0



More information about the vlc-devel mailing list