[vlc-devel] [PATCH 02/10] opengl: store fragment shader in sampler

Romain Vimont rom1v at videolabs.io
Wed May 20 16:08:13 CEST 2020


The function opengl_fragment_shader_init() both initializes the sampler
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 a779d7df5d10..a85b6e409101 100644
--- a/modules/video_output/opengl/fragment_shaders.c
+++ b/modules/video_output/opengl/fragment_shaders.c
@@ -392,7 +392,7 @@ sampler_xyz12_prepare_shader(const struct vlc_gl_sampler *sampler)
                          sampler->var.OrientationMatrix);
 }
 
-static char *
+static int
 xyz12_shader_init(struct vlc_gl_sampler *sampler)
 {
     sampler->pf_fetch_locations = sampler_xyz12_fetch_locations;
@@ -433,7 +433,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
@@ -495,7 +499,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)
 {
@@ -507,7 +511,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);
@@ -516,10 +520,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 *glsl_sampler, *lookup;
@@ -543,7 +547,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__)
@@ -701,10 +705,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 a6e4101663b8..14946de3f9c5 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 3083988ef435..095245f6e51f 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 12d6f7bdc994..42f9851de94b 100644
--- a/modules/video_output/opengl/sampler.c
+++ b/modules/video_output/opengl/sampler.c
@@ -55,6 +55,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));
@@ -123,5 +125,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 b5b296872b65..9b0614403ff8 100644
--- a/modules/video_output/opengl/sampler.h
+++ b/modules/video_output/opengl/sampler.h
@@ -90,6 +90,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.27.0.rc0



More information about the vlc-devel mailing list