opengl: rename tex converter to renderer
authorRomain Vimont <rom1v@videolabs.io>
Thu, 23 Jan 2020 14:43:30 +0000 (15:43 +0100)
committerJean-Baptiste Kempf <jb@videolan.org>
Thu, 13 Feb 2020 22:11:21 +0000 (23:11 +0100)
The opengl_tex_converter_t is not a converter anymore: it is only used
to communicate between the renderer (currently managed in vout_helper.c)
and the fragment shader generation code (fragment_shaders.c).

Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
modules/video_output/Makefile.am
modules/video_output/opengl/converter.h [deleted file]
modules/video_output/opengl/fragment_shaders.c
modules/video_output/opengl/internal.h
modules/video_output/opengl/renderer.h [new file with mode: 0644]
modules/video_output/opengl/vout_helper.c
modules/video_output/opengl/vout_helper.h

index 55b6e0e..049648f 100644 (file)
@@ -7,9 +7,10 @@ OPENGL_COMMONSOURCES = video_output/opengl/vout_helper.c \
        video_output/opengl/gl_common.h \
        video_output/opengl/gl_util.h \
        video_output/opengl/interop.h \
-       video_output/opengl/vout_helper.h video_output/opengl/converter.h \
+       video_output/opengl/vout_helper.h \
        video_output/opengl/internal.h video_output/opengl/fragment_shaders.c \
        video_output/opengl/interop.c video_output/opengl/interop_sw.c \
+       video_output/opengl/renderer.h \
        video_output/opengl/sub_renderer.c \
        video_output/opengl/sub_renderer.h
 if HAVE_LIBPLACEBO
diff --git a/modules/video_output/opengl/converter.h b/modules/video_output/opengl/converter.h
deleted file mode 100644 (file)
index 11a2ab6..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*****************************************************************************
- * converter.h: OpenGL internal header
- *****************************************************************************
- * Copyright (C) 2016 VLC authors and VideoLAN
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifndef VLC_OPENGL_CONVERTER_H
-#define VLC_OPENGL_CONVERTER_H
-
-#include <vlc_common.h>
-#include <vlc_codec.h>
-#include <vlc_opengl.h>
-#include <vlc_picture_pool.h>
-#include <vlc_plugin.h>
-#include "gl_common.h"
-#include "interop.h"
-
-struct pl_context;
-struct pl_shader;
-struct pl_shader_res;
-
-/*
- * Structure that is filled by "glhw converter" module probe function
- * The implementation should initialize every members of the struct that are
- * not set by the caller
- */
-typedef struct opengl_tex_converter_t opengl_tex_converter_t;
-struct opengl_tex_converter_t
-{
-    /* Pointer to object gl, set by the caller */
-    vlc_gl_t *gl;
-
-    /* libplacebo context, created by the caller (optional) */
-    struct pl_context *pl_ctx;
-
-    /* Function pointers to OpenGL functions, set by the caller */
-    const opengl_vtable_t *vt;
-
-    /* True to dump shaders, set by the caller */
-    bool b_dump_shaders;
-
-    /* GLSL version, set by the caller. 100 for GLSL ES, 120 for desktop GLSL */
-    unsigned glsl_version;
-    /* Precision header, set by the caller. In OpenGLES, the fragment language
-     * has no default precision qualifier for floating point types. */
-    const char *glsl_precision_header;
-
-    /* The following is used and filled by the opengl_fragment_shader_init
-     * function. */
-    struct {
-        GLint Texture[PICTURE_PLANE_MAX];
-        GLint TexSize[PICTURE_PLANE_MAX]; /* for GL_TEXTURE_RECTANGLE */
-        GLint ConvMatrix;
-        GLint FillColor;
-        GLint *pl_vars; /* for pl_sh_res */
-    } uloc;
-    bool yuv_color;
-    GLfloat conv_matrix[16];
-
-    struct pl_shader *pl_sh;
-    const struct pl_shader_res *pl_sh_res;
-
-    struct vlc_gl_interop *interop;
-
-    /**
-     * Callback to fetch locations of uniform or attributes variables
-     *
-     * This function pointer cannot be NULL. This callback is called one time
-     * after init.
-     *
-     * \param tc OpenGL tex converter
-     * \param program linked program that will be used by this tex converter
-     * \return VLC_SUCCESS or a VLC error
-     */
-    int (*pf_fetch_locations)(opengl_tex_converter_t *tc, GLuint program);
-
-    /**
-     * Callback to prepare the fragment shader
-     *
-     * This function pointer cannot be NULL. This callback can be used to
-     * specify values of uniform variables.
-     *
-     * \param tc OpenGL tex converter
-     * \param tex_width array of tex width (one per plane)
-     * \param tex_height array of tex height (one per plane)
-     * \param alpha alpha value, used only for RGBA fragment shader
-     */
-    void (*pf_prepare_shader)(const opengl_tex_converter_t *tc,
-                              const GLsizei *tex_width, const GLsizei *tex_height,
-                              float alpha);
-};
-
-#endif /* include-guard */
index 7cd7aaa..086a57d 100644 (file)
@@ -128,13 +128,13 @@ init_conv_matrix(float conv_matrix_out[],
 }
 
 static int
-tc_yuv_base_init(opengl_tex_converter_t *tc, vlc_fourcc_t chroma,
+tc_yuv_base_init(struct vlc_gl_renderer *renderer, vlc_fourcc_t chroma,
                  const vlc_chroma_description_t *desc,
                  video_color_space_t yuv_space)
 {
     /* The current implementation always converts from limited to full range. */
     const video_color_range_t range = COLOR_RANGE_LIMITED;
-    float *matrix = tc->conv_matrix;
+    float *matrix = renderer->conv_matrix;
     init_conv_matrix(matrix, yuv_space, range);
 
     if (desc->pixel_size == 2)
@@ -167,7 +167,7 @@ tc_yuv_base_init(opengl_tex_converter_t *tc, vlc_fourcc_t chroma,
         }
     }
 
-    tc->yuv_color = true;
+    renderer->yuv_color = true;
 
     /* Some formats require to swap the U and V components.
      *
@@ -202,15 +202,16 @@ tc_yuv_base_init(opengl_tex_converter_t *tc, vlc_fourcc_t chroma,
 }
 
 static int
-tc_base_fetch_locations(opengl_tex_converter_t *tc, GLuint program)
+tc_base_fetch_locations(struct vlc_gl_renderer *renderer, GLuint program)
 {
-    struct vlc_gl_interop *interop = tc->interop;
+    struct vlc_gl_interop *interop = renderer->interop;
+    const opengl_vtable_t *vt = renderer->vt;
 
-    if (tc->yuv_color)
+    if (renderer->yuv_color)
     {
-        tc->uloc.ConvMatrix = tc->vt->GetUniformLocation(program,
-                                                         "ConvMatrix");
-        if (tc->uloc.ConvMatrix == -1)
+        renderer->uloc.ConvMatrix = vt->GetUniformLocation(program,
+                                                           "ConvMatrix");
+        if (renderer->uloc.ConvMatrix == -1)
             return VLC_EGENERIC;
     }
 
@@ -218,27 +219,27 @@ tc_base_fetch_locations(opengl_tex_converter_t *tc, GLuint program)
     {
         char name[sizeof("TextureX")];
         snprintf(name, sizeof(name), "Texture%1u", i);
-        tc->uloc.Texture[i] = tc->vt->GetUniformLocation(program, name);
-        if (tc->uloc.Texture[i] == -1)
+        renderer->uloc.Texture[i] = vt->GetUniformLocation(program, name);
+        if (renderer->uloc.Texture[i] == -1)
             return VLC_EGENERIC;
         if (interop->tex_target == GL_TEXTURE_RECTANGLE)
         {
             snprintf(name, sizeof(name), "TexSize%1u", i);
-            tc->uloc.TexSize[i] = tc->vt->GetUniformLocation(program, name);
-            if (tc->uloc.TexSize[i] == -1)
+            renderer->uloc.TexSize[i] = vt->GetUniformLocation(program, name);
+            if (renderer->uloc.TexSize[i] == -1)
                 return VLC_EGENERIC;
         }
     }
 
-    tc->uloc.FillColor = tc->vt->GetUniformLocation(program, "FillColor");
-    if (tc->uloc.FillColor == -1)
+    renderer->uloc.FillColor = vt->GetUniformLocation(program, "FillColor");
+    if (renderer->uloc.FillColor == -1)
         return VLC_EGENERIC;
 
 #ifdef HAVE_LIBPLACEBO
-    const struct pl_shader_res *res = tc->pl_sh_res;
+    const struct pl_shader_res *res = renderer->pl_sh_res;
     for (int i = 0; res && i < res->num_variables; i++) {
         struct pl_shader_var sv = res->variables[i];
-        tc->uloc.pl_vars[i] = tc->vt->GetUniformLocation(program, sv.var.name);
+        renderer->uloc.pl_vars[i] = vt->GetUniformLocation(program, sv.var.name);
     }
 #endif
 
@@ -246,33 +247,34 @@ tc_base_fetch_locations(opengl_tex_converter_t *tc, GLuint program)
 }
 
 static void
-tc_base_prepare_shader(const opengl_tex_converter_t *tc,
+tc_base_prepare_shader(const struct vlc_gl_renderer *renderer,
                        const GLsizei *tex_width, const GLsizei *tex_height,
                        float alpha)
 {
     (void) tex_width; (void) tex_height;
-    const struct vlc_gl_interop *interop = tc->interop;
+    const struct vlc_gl_interop *interop = renderer->interop;
+    const opengl_vtable_t *vt = renderer->vt;
 
-    if (tc->yuv_color)
-        tc->vt->UniformMatrix4fv(tc->uloc.ConvMatrix, 1, GL_FALSE,
-                                 tc->conv_matrix);
+    if (renderer->yuv_color)
+        vt->UniformMatrix4fv(renderer->uloc.ConvMatrix, 1, GL_FALSE,
+                             renderer->conv_matrix);
 
     for (unsigned i = 0; i < interop->tex_count; ++i)
-        tc->vt->Uniform1i(tc->uloc.Texture[i], i);
+        vt->Uniform1i(renderer->uloc.Texture[i], i);
 
-    tc->vt->Uniform4f(tc->uloc.FillColor, 1.0f, 1.0f, 1.0f, alpha);
+    vt->Uniform4f(renderer->uloc.FillColor, 1.0f, 1.0f, 1.0f, alpha);
 
     if (interop->tex_target == GL_TEXTURE_RECTANGLE)
     {
         for (unsigned i = 0; i < interop->tex_count; ++i)
-            tc->vt->Uniform2f(tc->uloc.TexSize[i], tex_width[i],
-                               tex_height[i]);
+            vt->Uniform2f(renderer->uloc.TexSize[i], tex_width[i],
+                          tex_height[i]);
     }
 
 #ifdef HAVE_LIBPLACEBO
-    const struct pl_shader_res *res = tc->pl_sh_res;
+    const struct pl_shader_res *res = renderer->pl_sh_res;
     for (int i = 0; res && i < res->num_variables; i++) {
-        GLint loc = tc->uloc.pl_vars[i];
+        GLint loc = renderer->uloc.pl_vars[i];
         if (loc == -1) // uniform optimized out
             continue;
 
@@ -286,16 +288,16 @@ tc_base_prepare_shader(const opengl_tex_converter_t *tc,
 
         const float *f = sv.data;
         switch (var.dim_m) {
-        case 4: tc->vt->UniformMatrix4fv(loc, 1, GL_FALSE, f); break;
-        case 3: tc->vt->UniformMatrix3fv(loc, 1, GL_FALSE, f); break;
-        case 2: tc->vt->UniformMatrix2fv(loc, 1, GL_FALSE, f); break;
+        case 4: vt->UniformMatrix4fv(loc, 1, GL_FALSE, f); break;
+        case 3: vt->UniformMatrix3fv(loc, 1, GL_FALSE, f); break;
+        case 2: vt->UniformMatrix2fv(loc, 1, GL_FALSE, f); break;
 
         case 1:
             switch (var.dim_v) {
-            case 1: tc->vt->Uniform1f(loc, f[0]); break;
-            case 2: tc->vt->Uniform2f(loc, f[0], f[1]); break;
-            case 3: tc->vt->Uniform3f(loc, f[0], f[1], f[2]); break;
-            case 4: tc->vt->Uniform4f(loc, f[0], f[1], f[2], f[3]); break;
+            case 1: vt->Uniform1f(loc, f[0]); break;
+            case 2: vt->Uniform2f(loc, f[0], f[1]); break;
+            case 3: vt->Uniform3f(loc, f[0], f[1], f[2]); break;
+            case 4: vt->Uniform4f(loc, f[0], f[1], f[2], f[3]); break;
             }
             break;
         }
@@ -304,26 +306,29 @@ tc_base_prepare_shader(const opengl_tex_converter_t *tc,
 }
 
 static int
-tc_xyz12_fetch_locations(opengl_tex_converter_t *tc, GLuint program)
+tc_xyz12_fetch_locations(struct vlc_gl_renderer *renderer, GLuint program)
 {
-    tc->uloc.Texture[0] = tc->vt->GetUniformLocation(program, "Texture0");
-    return tc->uloc.Texture[0] != -1 ? VLC_SUCCESS : VLC_EGENERIC;
+    const opengl_vtable_t *vt = renderer->vt;
+    renderer->uloc.Texture[0] = vt->GetUniformLocation(program, "Texture0");
+    return renderer->uloc.Texture[0] != -1 ? VLC_SUCCESS : VLC_EGENERIC;
 }
 
 static void
-tc_xyz12_prepare_shader(const opengl_tex_converter_t *tc,
+tc_xyz12_prepare_shader(const struct vlc_gl_renderer *renderer,
                         const GLsizei *tex_width, const GLsizei *tex_height,
                         float alpha)
 {
     (void) tex_width; (void) tex_height; (void) alpha;
-    tc->vt->Uniform1i(tc->uloc.Texture[0], 0);
+    const opengl_vtable_t *vt = renderer->vt;
+    vt->Uniform1i(renderer->uloc.Texture[0], 0);
 }
 
 static GLuint
-xyz12_shader_init(opengl_tex_converter_t *tc)
+xyz12_shader_init(struct vlc_gl_renderer *renderer)
 {
-    tc->pf_fetch_locations = tc_xyz12_fetch_locations;
-    tc->pf_prepare_shader = tc_xyz12_prepare_shader;
+    const opengl_vtable_t *vt = renderer->vt;
+    renderer->pf_fetch_locations = tc_xyz12_fetch_locations;
+    renderer->pf_prepare_shader = tc_xyz12_prepare_shader;
 
     /* Shader for XYZ to RGB correction
      * 3 steps :
@@ -358,12 +363,13 @@ xyz12_shader_init(opengl_tex_converter_t *tc)
         "}";
 
     char *code;
-    if (asprintf(&code, template, tc->glsl_version, tc->glsl_precision_header) < 0)
+    if (asprintf(&code, template, renderer->glsl_version,
+                 renderer->glsl_precision_header) < 0)
         return 0;
 
-    GLuint fragment_shader = tc->vt->CreateShader(GL_FRAGMENT_SHADER);
-    tc->vt->ShaderSource(fragment_shader, 1, (const char **) &code, NULL);
-    tc->vt->CompileShader(fragment_shader);
+    GLuint fragment_shader = vt->CreateShader(GL_FRAGMENT_SHADER);
+    vt->ShaderSource(fragment_shader, 1, (const char **) &code, NULL);
+    vt->CompileShader(fragment_shader);
     free(code);
     return fragment_shader;
 }
@@ -428,10 +434,11 @@ opengl_init_swizzle(const struct vlc_gl_interop *interop,
 }
 
 GLuint
-opengl_fragment_shader_init(opengl_tex_converter_t *tc, GLenum tex_target,
+opengl_fragment_shader_init(struct vlc_gl_renderer *renderer, GLenum tex_target,
                             vlc_fourcc_t chroma, video_color_space_t yuv_space)
 {
-    struct vlc_gl_interop *interop = tc->interop;
+    struct vlc_gl_interop *interop = renderer->interop;
+    const opengl_vtable_t *vt = renderer->vt;
 
     const char *swizzle_per_tex[PICTURE_PLANE_MAX] = { NULL, };
     const bool is_yuv = vlc_fourcc_IsYUV(chroma);
@@ -442,14 +449,14 @@ opengl_fragment_shader_init(opengl_tex_converter_t *tc, GLenum tex_target,
         return 0;
 
     if (chroma == VLC_CODEC_XYZ12)
-        return xyz12_shader_init(tc);
+        return xyz12_shader_init(renderer);
 
     if (is_yuv)
     {
-        ret = tc_yuv_base_init(tc, chroma, desc, yuv_space);
+        ret = tc_yuv_base_init(renderer, chroma, desc, yuv_space);
         if (ret != VLC_SUCCESS)
             return 0;
-        ret = opengl_init_swizzle(tc->interop, swizzle_per_tex, chroma, desc);
+        ret = opengl_init_swizzle(renderer->interop, swizzle_per_tex, chroma, desc);
         if (ret != VLC_SUCCESS)
             return 0;
     }
@@ -483,47 +490,47 @@ opengl_fragment_shader_init(opengl_tex_converter_t *tc, GLenum tex_target,
 #define ADD(x) vlc_memstream_puts(&ms, x)
 #define ADDF(x, ...) vlc_memstream_printf(&ms, x, ##__VA_ARGS__)
 
-    ADDF("#version %u\n", tc->glsl_version);
+    ADDF("#version %u\n", renderer->glsl_version);
 
     if (tex_target == GL_TEXTURE_EXTERNAL_OES)
         ADDF("#extension GL_OES_EGL_image_external : require\n");
 
-    ADDF("%s", tc->glsl_precision_header);
+    ADDF("%s", renderer->glsl_precision_header);
 
     for (unsigned i = 0; i < interop->tex_count; ++i)
         ADDF("uniform %s Texture%u;\n"
              "varying vec2 TexCoord%u;\n", sampler, i, i);
 
 #ifdef HAVE_LIBPLACEBO
-    if (tc->pl_sh) {
-        struct pl_shader *sh = tc->pl_sh;
+    if (renderer->pl_sh) {
+        struct pl_shader *sh = renderer->pl_sh;
         struct pl_color_map_params color_params = pl_color_map_default_params;
-        color_params.intent = var_InheritInteger(tc->gl, "rendering-intent");
-        color_params.tone_mapping_algo = var_InheritInteger(tc->gl, "tone-mapping");
-        color_params.tone_mapping_param = var_InheritFloat(tc->gl, "tone-mapping-param");
+        color_params.intent = var_InheritInteger(renderer->gl, "rendering-intent");
+        color_params.tone_mapping_algo = var_InheritInteger(renderer->gl, "tone-mapping");
+        color_params.tone_mapping_param = var_InheritFloat(renderer->gl, "tone-mapping-param");
 #    if PL_API_VER >= 10
-        color_params.desaturation_strength = var_InheritFloat(tc->gl, "desat-strength");
-        color_params.desaturation_exponent = var_InheritFloat(tc->gl, "desat-exponent");
-        color_params.desaturation_base = var_InheritFloat(tc->gl, "desat-base");
+        color_params.desaturation_strength = var_InheritFloat(renderer->gl, "desat-strength");
+        color_params.desaturation_exponent = var_InheritFloat(renderer->gl, "desat-exponent");
+        color_params.desaturation_base = var_InheritFloat(renderer->gl, "desat-base");
 #    else
-        color_params.tone_mapping_desaturate = var_InheritFloat(tc->gl, "tone-mapping-desat");
+        color_params.tone_mapping_desaturate = var_InheritFloat(renderer->gl, "tone-mapping-desat");
 #    endif
-        color_params.gamut_warning = var_InheritBool(tc->gl, "tone-mapping-warn");
+        color_params.gamut_warning = var_InheritBool(renderer->gl, "tone-mapping-warn");
 
         struct pl_color_space dst_space = pl_color_space_unknown;
-        dst_space.primaries = var_InheritInteger(tc->gl, "target-prim");
-        dst_space.transfer = var_InheritInteger(tc->gl, "target-trc");
+        dst_space.primaries = var_InheritInteger(renderer->gl, "target-prim");
+        dst_space.transfer = var_InheritInteger(renderer->gl, "target-trc");
 
         pl_shader_color_map(sh, &color_params,
                 vlc_placebo_ColorSpace(&interop->fmt),
                 dst_space, NULL, false);
 
         struct pl_shader_obj *dither_state = NULL;
-        int method = var_InheritInteger(tc->gl, "dither-algo");
+        int method = var_InheritInteger(renderer->gl, "dither-algo");
         if (method >= 0) {
 
             unsigned out_bits = 0;
-            int override = var_InheritInteger(tc->gl, "dither-depth");
+            int override = var_InheritInteger(renderer->gl, "dither-depth");
             if (override > 0)
                 out_bits = override;
             else
@@ -531,10 +538,10 @@ opengl_fragment_shader_init(opengl_tex_converter_t *tc, GLenum tex_target,
                 GLint fb_depth = 0;
 #if !defined(USE_OPENGL_ES2)
                 /* fetch framebuffer depth (we are already bound to the default one). */
-                if (tc->vt->GetFramebufferAttachmentParameteriv != NULL)
-                    tc->vt->GetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_BACK_LEFT,
-                                                                GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE,
-                                                                &fb_depth);
+                if (vt->GetFramebufferAttachmentParameteriv != NULL)
+                    vt->GetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_BACK_LEFT,
+                                                            GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE,
+                                                            &fb_depth);
 #endif
                 if (fb_depth <= 0)
                     fb_depth = 8;
@@ -547,11 +554,11 @@ opengl_fragment_shader_init(opengl_tex_converter_t *tc, GLenum tex_target,
             });
         }
 
-        const struct pl_shader_res *res = tc->pl_sh_res = pl_shader_finalize(sh);
+        const struct pl_shader_res *res = renderer->pl_sh_res = pl_shader_finalize(sh);
         pl_shader_obj_destroy(&dither_state);
 
-        FREENULL(tc->uloc.pl_vars);
-        tc->uloc.pl_vars = calloc(res->num_variables, sizeof(GLint));
+        FREENULL(renderer->uloc.pl_vars);
+        renderer->uloc.pl_vars = calloc(res->num_variables, sizeof(GLint));
         for (int i = 0; i < res->num_variables; i++) {
             struct pl_shader_var sv = res->variables[i];
             const char *glsl_type_name = pl_var_glsl_type_name(sv.var);
@@ -569,7 +576,7 @@ opengl_fragment_shader_init(opengl_tex_converter_t *tc, GLenum tex_target,
         interop->fmt.primaries == COLOR_PRIMARIES_BT2020)
     {
         // no warning for HLG because it's more or less backwards-compatible
-        msg_Warn(tc->gl, "VLC needs to be built with support for libplacebo "
+        msg_Warn(renderer->gl, "VLC needs to be built with support for libplacebo "
                  "in order to display wide gamut or HDR signals correctly.");
     }
 #endif
@@ -622,8 +629,8 @@ opengl_fragment_shader_init(opengl_tex_converter_t *tc, GLenum tex_target,
     assert(yuv_space == COLOR_SPACE_UNDEF || color_count == 3);
 
 #ifdef HAVE_LIBPLACEBO
-    if (tc->pl_sh_res) {
-        const struct pl_shader_res *res = tc->pl_sh_res;
+    if (renderer->pl_sh_res) {
+        const struct pl_shader_res *res = renderer->pl_sh_res;
         assert(res->input  == PL_SHADER_SIG_COLOR);
         assert(res->output == PL_SHADER_SIG_COLOR);
         ADDF(" result = %s(result);\n", res->name);
@@ -639,22 +646,22 @@ opengl_fragment_shader_init(opengl_tex_converter_t *tc, GLenum tex_target,
     if (vlc_memstream_close(&ms) != 0)
         return 0;
 
-    GLuint fragment_shader = tc->vt->CreateShader(GL_FRAGMENT_SHADER);
+    GLuint fragment_shader = vt->CreateShader(GL_FRAGMENT_SHADER);
     if (fragment_shader == 0)
     {
         free(ms.ptr);
         return 0;
     }
     GLint length = ms.length;
-    tc->vt->ShaderSource(fragment_shader, 1, (const char **)&ms.ptr, &length);
-    tc->vt->CompileShader(fragment_shader);
-    if (tc->b_dump_shaders)
-        msg_Dbg(tc->gl, "\n=== Fragment shader for fourcc: %4.4s, colorspace: %d ===\n%s\n",
+    vt->ShaderSource(fragment_shader, 1, (const char **)&ms.ptr, &length);
+    vt->CompileShader(fragment_shader);
+    if (renderer->b_dump_shaders)
+        msg_Dbg(renderer->gl, "\n=== Fragment shader for fourcc: %4.4s, colorspace: %d ===\n%s\n",
                 (const char *)&chroma, yuv_space, ms.ptr);
     free(ms.ptr);
 
-    tc->pf_fetch_locations = tc_base_fetch_locations;
-    tc->pf_prepare_shader = tc_base_prepare_shader;
+    renderer->pf_fetch_locations = tc_base_fetch_locations;
+    renderer->pf_prepare_shader = tc_base_prepare_shader;
 
     return fragment_shader;
 }
index e881e79..e7143e1 100644 (file)
 #ifndef VLC_OPENGL_INTERNAL_H
 #define VLC_OPENGL_INTERNAL_H
 
-#include "converter.h"
 #include "interop.h"
+#include "renderer.h"
 
 int
 opengl_interop_init_impl(struct vlc_gl_interop *interop, GLenum tex_target,
                          vlc_fourcc_t chroma, video_color_space_t yuv_space);
 
 GLuint
-opengl_fragment_shader_init(opengl_tex_converter_t *,
+opengl_fragment_shader_init(struct vlc_gl_renderer *rendeer,
                             GLenum, vlc_fourcc_t, video_color_space_t);
 int
 opengl_interop_generic_init(struct vlc_gl_interop *interop, bool);
diff --git a/modules/video_output/opengl/renderer.h b/modules/video_output/opengl/renderer.h
new file mode 100644 (file)
index 0000000..a7be668
--- /dev/null
@@ -0,0 +1,103 @@
+/*****************************************************************************
+ * renderer.h: OpenGL internal header
+ *****************************************************************************
+ * Copyright (C) 2016 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef VLC_GL_RENDERER_H
+#define VLC_GL_RENDERER_H
+
+#include <vlc_common.h>
+#include <vlc_codec.h>
+#include <vlc_opengl.h>
+#include <vlc_plugin.h>
+#include "gl_common.h"
+#include "interop.h"
+
+struct pl_context;
+struct pl_shader;
+struct pl_shader_res;
+
+/**
+ * OpenGL picture renderer
+ */
+struct vlc_gl_renderer
+{
+    /* Pointer to object gl, set by the caller */
+    vlc_gl_t *gl;
+
+    /* libplacebo context, created by the caller (optional) */
+    struct pl_context *pl_ctx;
+
+    /* Function pointers to OpenGL functions, set by the caller */
+    const opengl_vtable_t *vt;
+
+    /* True to dump shaders, set by the caller */
+    bool b_dump_shaders;
+
+    /* GLSL version, set by the caller. 100 for GLSL ES, 120 for desktop GLSL */
+    unsigned glsl_version;
+    /* Precision header, set by the caller. In OpenGLES, the fragment language
+     * has no default precision qualifier for floating point types. */
+    const char *glsl_precision_header;
+
+    /* The following is used and filled by the opengl_fragment_shader_init
+     * function. */
+    struct {
+        GLint Texture[PICTURE_PLANE_MAX];
+        GLint TexSize[PICTURE_PLANE_MAX]; /* for GL_TEXTURE_RECTANGLE */
+        GLint ConvMatrix;
+        GLint FillColor;
+        GLint *pl_vars; /* for pl_sh_res */
+    } uloc;
+    bool yuv_color;
+    GLfloat conv_matrix[16];
+
+    struct pl_shader *pl_sh;
+    const struct pl_shader_res *pl_sh_res;
+
+    struct vlc_gl_interop *interop;
+
+    /**
+     * Callback to fetch locations of uniform or attributes variables
+     *
+     * This function pointer cannot be NULL. This callback is called one time
+     * after init.
+     *
+     * \param renderer OpenGL renderer
+     * \param program linked program that will be used by this renderer
+     * \return VLC_SUCCESS or a VLC error
+     */
+    int (*pf_fetch_locations)(struct vlc_gl_renderer *renderer, GLuint program);
+
+    /**
+     * Callback to prepare the fragment shader
+     *
+     * This function pointer cannot be NULL. This callback can be used to
+     * specify values of uniform variables.
+     *
+     * \param renderer OpenGL renderer
+     * \param tex_width array of tex width (one per plane)
+     * \param tex_height array of tex height (one per plane)
+     * \param alpha alpha value, used only for RGBA fragment shader
+     */
+    void (*pf_prepare_shader)(const struct vlc_gl_renderer *renderer,
+                              const GLsizei *tex_width, const GLsizei *tex_height,
+                              float alpha);
+};
+
+#endif /* include-guard */
index a538f1a..1abac86 100644 (file)
@@ -49,7 +49,7 @@
 struct prgm
 {
     GLuint id;
-    opengl_tex_converter_t *tc;
+    struct vlc_gl_renderer *renderer;
 
     struct {
         GLfloat OrientationMatrix[16];
@@ -240,9 +240,11 @@ static void getOrientationTransformMatrix(video_orientation_t orientation,
     }
 }
 
-static GLuint BuildVertexShader(const opengl_tex_converter_t *tc,
+static GLuint BuildVertexShader(const struct vlc_gl_renderer *renderer,
                                 unsigned plane_count)
 {
+    const opengl_vtable_t *vt = renderer->vt;
+
     /* Basic vertex shader */
     static const char *template =
         "#version %u\n"
@@ -272,16 +274,16 @@ static GLuint BuildVertexShader(const opengl_tex_converter_t *tc,
         " TexCoord2 = vec4(TransformMatrix * OrientationMatrix * MultiTexCoord2).st;\n" : "";
 
     char *code;
-    if (asprintf(&code, template, tc->glsl_version, coord1_header, coord2_header,
-                 coord1_code, coord2_code) < 0)
+    if (asprintf(&code, template, renderer->glsl_version, coord1_header,
+                 coord2_header, coord1_code, coord2_code) < 0)
         return 0;
 
-    GLuint shader = tc->vt->CreateShader(GL_VERTEX_SHADER);
-    tc->vt->ShaderSource(shader, 1, (const char **) &code, NULL);
-    if (tc->b_dump_shaders)
-        msg_Dbg(tc->gl, "\n=== Vertex shader for fourcc: %4.4s ===\n%s\n",
-                (const char *)&tc->interop->fmt.i_chroma, code);
-    tc->vt->CompileShader(shader);
+    GLuint shader = vt->CreateShader(GL_VERTEX_SHADER);
+    vt->ShaderSource(shader, 1, (const char **) &code, NULL);
+    if (renderer->b_dump_shaders)
+        msg_Dbg(renderer->gl, "\n=== Vertex shader for fourcc: %4.4s ===\n%s\n",
+                (const char *) &renderer->interop->fmt.i_chroma, code);
+    vt->CompileShader(shader);
     free(code);
     return shader;
 }
@@ -289,15 +291,16 @@ static GLuint BuildVertexShader(const opengl_tex_converter_t *tc,
 static int
 opengl_link_program(struct prgm *prgm)
 {
-    opengl_tex_converter_t *tc = prgm->tc;
-    struct vlc_gl_interop *interop = tc->interop;
+    struct vlc_gl_renderer *renderer = prgm->renderer;
+    struct vlc_gl_interop *interop = renderer->interop;
+    const opengl_vtable_t *vt = renderer->vt;
 
-    GLuint vertex_shader = BuildVertexShader(tc, interop->tex_count);
+    GLuint vertex_shader = BuildVertexShader(renderer, interop->tex_count);
     if (!vertex_shader)
         return VLC_EGENERIC;
 
     GLuint fragment_shader =
-        opengl_fragment_shader_init(tc, interop->tex_target,
+        opengl_fragment_shader_init(renderer, interop->tex_target,
                                     interop->sw_fmt.i_chroma,
                                     interop->sw_fmt.space);
     if (!fragment_shader)
@@ -306,15 +309,15 @@ opengl_link_program(struct prgm *prgm)
     assert(interop->tex_target != 0 &&
            interop->tex_count > 0 &&
            interop->ops->update_textures != NULL &&
-           tc->pf_fetch_locations != NULL &&
-           tc->pf_prepare_shader != NULL);
+           renderer->pf_fetch_locations != NULL &&
+           renderer->pf_prepare_shader != NULL);
 
     GLuint shaders[] = { fragment_shader, vertex_shader };
 
     /* Check shaders messages */
     for (unsigned i = 0; i < 2; i++) {
         int infoLength;
-        tc->vt->GetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &infoLength);
+        vt->GetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &infoLength);
         if (infoLength <= 1)
             continue;
 
@@ -322,52 +325,52 @@ opengl_link_program(struct prgm *prgm)
         if (infolog != NULL)
         {
             int charsWritten;
-            tc->vt->GetShaderInfoLog(shaders[i], infoLength, &charsWritten,
-                                      infolog);
-            msg_Err(tc->gl, "shader %u: %s", i, infolog);
+            vt->GetShaderInfoLog(shaders[i], infoLength, &charsWritten,
+                                 infolog);
+            msg_Err(renderer->gl, "shader %u: %s", i, infolog);
             free(infolog);
         }
     }
 
-    prgm->id = tc->vt->CreateProgram();
-    tc->vt->AttachShader(prgm->id, fragment_shader);
-    tc->vt->AttachShader(prgm->id, vertex_shader);
-    tc->vt->LinkProgram(prgm->id);
+    prgm->id = vt->CreateProgram();
+    vt->AttachShader(prgm->id, fragment_shader);
+    vt->AttachShader(prgm->id, vertex_shader);
+    vt->LinkProgram(prgm->id);
 
-    tc->vt->DeleteShader(vertex_shader);
-    tc->vt->DeleteShader(fragment_shader);
+    vt->DeleteShader(vertex_shader);
+    vt->DeleteShader(fragment_shader);
 
     /* Check program messages */
     int infoLength = 0;
-    tc->vt->GetProgramiv(prgm->id, GL_INFO_LOG_LENGTH, &infoLength);
+    vt->GetProgramiv(prgm->id, GL_INFO_LOG_LENGTH, &infoLength);
     if (infoLength > 1)
     {
         char *infolog = malloc(infoLength);
         if (infolog != NULL)
         {
             int charsWritten;
-            tc->vt->GetProgramInfoLog(prgm->id, infoLength, &charsWritten,
-                                       infolog);
-            msg_Err(tc->gl, "shader program: %s", infolog);
+            vt->GetProgramInfoLog(prgm->id, infoLength, &charsWritten,
+                                  infolog);
+            msg_Err(renderer->gl, "shader program: %s", infolog);
             free(infolog);
         }
 
         /* If there is some message, better to check linking is ok */
         GLint link_status = GL_TRUE;
-        tc->vt->GetProgramiv(prgm->id, GL_LINK_STATUS, &link_status);
+        vt->GetProgramiv(prgm->id, GL_LINK_STATUS, &link_status);
         if (link_status == GL_FALSE)
         {
-            msg_Err(tc->gl, "Unable to use program");
+            msg_Err(renderer->gl, "Unable to use program");
             goto error;
         }
     }
 
     /* Fetch UniformLocations and AttribLocations */
 #define GET_LOC(type, x, str) do { \
-    x = tc->vt->Get##type##Location(prgm->id, str); \
+    x = vt->Get##type##Location(prgm->id, str); \
     assert(x != -1); \
     if (x == -1) { \
-        msg_Err(tc->gl, "Unable to Get"#type"Location(%s)", str); \
+        msg_Err(renderer->gl, "Unable to Get"#type"Location(%s)", str); \
         goto error; \
     } \
 } while (0)
@@ -393,18 +396,18 @@ opengl_link_program(struct prgm *prgm)
 #undef GET_LOC
 #undef GET_ULOC
 #undef GET_ALOC
-    int ret = prgm->tc->pf_fetch_locations(prgm->tc, prgm->id);
+    int ret = prgm->renderer->pf_fetch_locations(prgm->renderer, prgm->id);
     assert(ret == VLC_SUCCESS);
     if (ret != VLC_SUCCESS)
     {
-        msg_Err(tc->gl, "Unable to get locations from tex_conv");
+        msg_Err(renderer->gl, "Unable to get locations from tex_conv");
         goto error;
     }
 
     return VLC_SUCCESS;
 
 error:
-    tc->vt->DeleteProgram(prgm->id);
+    vt->DeleteProgram(prgm->id);
     prgm->id = 0;
     return VLC_EGENERIC;
 }
@@ -412,18 +415,18 @@ error:
 static void
 opengl_deinit_program(vout_display_opengl_t *vgl, struct prgm *prgm)
 {
-    opengl_tex_converter_t *tc = prgm->tc;
-    vlc_gl_interop_Delete(tc->interop);
+    struct vlc_gl_renderer *renderer = prgm->renderer;
+    vlc_gl_interop_Delete(renderer->interop);
     if (prgm->id != 0)
         vgl->vt.DeleteProgram(prgm->id);
 
 #ifdef HAVE_LIBPLACEBO
-    FREENULL(tc->uloc.pl_vars);
-    if (tc->pl_ctx)
-        pl_context_destroy(&tc->pl_ctx);
+    FREENULL(renderer->uloc.pl_vars);
+    if (renderer->pl_ctx)
+        pl_context_destroy(&renderer->pl_ctx);
 #endif
 
-    free(tc);
+    free(renderer);
 }
 
 static int
@@ -431,46 +434,46 @@ opengl_init_program(vout_display_opengl_t *vgl, vlc_video_context *context,
                     struct prgm *prgm, const video_format_t *fmt,
                     bool b_dump_shaders)
 {
-    opengl_tex_converter_t *tc = calloc(1, sizeof(*tc));
-    if (tc == NULL)
+    struct vlc_gl_renderer *renderer = calloc(1, sizeof(*renderer));
+    if (!renderer)
         return VLC_ENOMEM;
 
     struct vlc_gl_interop *interop =
         vlc_gl_interop_New(vgl->gl, &vgl->vt, context, fmt, false);
     if (!interop)
     {
-        free(tc);
+        free(renderer);
         return VLC_ENOMEM;
     }
 
-    tc->interop = interop;
+    renderer->interop = interop;
 
-    tc->gl = vgl->gl;
-    tc->vt = &vgl->vt;
-    tc->b_dump_shaders = b_dump_shaders;
+    renderer->gl = vgl->gl;
+    renderer->vt = &vgl->vt;
+    renderer->b_dump_shaders = b_dump_shaders;
 #if defined(USE_OPENGL_ES2)
-    tc->glsl_version = 100;
-    tc->glsl_precision_header = "precision highp float;\n";
+    renderer->glsl_version = 100;
+    renderer->glsl_precision_header = "precision highp float;\n";
 #else
-    tc->glsl_version = 120;
-    tc->glsl_precision_header = "";
+    renderer->glsl_version = 120;
+    renderer->glsl_precision_header = "";
 #endif
 
 #ifdef HAVE_LIBPLACEBO
     // Create the main libplacebo context
-    tc->pl_ctx = vlc_placebo_Create(VLC_OBJECT(vgl->gl));
-    if (tc->pl_ctx) {
+    renderer->pl_ctx = vlc_placebo_Create(VLC_OBJECT(vgl->gl));
+    if (renderer->pl_ctx) {
 #   if PL_API_VER >= 20
-        tc->pl_sh = pl_shader_alloc(tc->pl_ctx, NULL);
+        renderer->pl_sh = pl_shader_alloc(renderer->pl_ctx, NULL);
 #   elif PL_API_VER >= 6
-        tc->pl_sh = pl_shader_alloc(tc->pl_ctx, NULL, 0);
+        renderer->pl_sh = pl_shader_alloc(renderer->pl_ctx, NULL, 0);
 #   else
-        tc->pl_sh = pl_shader_alloc(tc->pl_ctx, NULL, 0, 0);
+        renderer->pl_sh = pl_shader_alloc(renderer->pl_ctx, NULL, 0, 0);
 #   endif
     }
 #endif
 
-    prgm->tc = tc;
+    prgm->renderer = renderer;
 
     int ret = opengl_link_program(prgm);
     if (ret != VLC_SUCCESS)
@@ -690,7 +693,7 @@ vout_display_opengl_t *vout_display_opengl_New(video_format_t *fmt,
 
     GL_ASSERT_NOERROR();
 
-    const struct vlc_gl_interop *interop = vgl->prgm.tc->interop;
+    const struct vlc_gl_interop *interop = vgl->prgm.renderer->interop;
     /* Update the fmt to main program one */
     vgl->fmt = interop->fmt;
     /* The orientation is handled by the orientation matrix */
@@ -713,7 +716,7 @@ vout_display_opengl_t *vout_display_opengl_New(video_format_t *fmt,
 
     if (!interop->handle_texs_gen)
     {
-        ret = vlc_gl_interop_GenerateTextures(vgl->prgm.tc->interop,
+        ret = vlc_gl_interop_GenerateTextures(interop,
                                               vgl->tex_width, vgl->tex_height,
                                               vgl->texture);
         if (ret != VLC_SUCCESS)
@@ -759,7 +762,7 @@ void vout_display_opengl_Delete(vout_display_opengl_t *vgl)
     vgl->vt.Finish();
     vgl->vt.Flush();
 
-    const struct vlc_gl_interop *interop = vgl->prgm.tc->interop;
+    const struct vlc_gl_interop *interop = vgl->prgm.renderer->interop;
     const size_t main_tex_count = interop->tex_count;
     const bool main_del_texs = !interop->handle_texs_gen;
 
@@ -857,8 +860,8 @@ int vout_display_opengl_Prepare(vout_display_opengl_t *vgl,
 {
     GL_ASSERT_NOERROR();
 
-    opengl_tex_converter_t *tc = vgl->prgm.tc;
-    const struct vlc_gl_interop *interop = tc->interop;
+    struct vlc_gl_renderer *renderer = vgl->prgm.renderer;
+    const struct vlc_gl_interop *interop = renderer->interop;
 
     /* Update the texture */
     int ret = interop->ops->update_textures(interop, vgl->texture, vgl->tex_width, vgl->tex_height,
@@ -1143,7 +1146,7 @@ static int SetupCoords(vout_display_opengl_t *vgl,
                        const float *left, const float *top,
                        const float *right, const float *bottom)
 {
-    const struct vlc_gl_interop *interop = vgl->prgm.tc->interop;
+    const struct vlc_gl_interop *interop = vgl->prgm.renderer->interop;
 
     GLfloat *vertexCoord, *textureCoord;
     GLushort *indices;
@@ -1206,9 +1209,9 @@ static int SetupCoords(vout_display_opengl_t *vgl,
 
 static void DrawWithShaders(vout_display_opengl_t *vgl, struct prgm *prgm)
 {
-    opengl_tex_converter_t *tc = prgm->tc;
-    const struct vlc_gl_interop *interop = tc->interop;
-    tc->pf_prepare_shader(tc, vgl->tex_width, vgl->tex_height, 1.0f);
+    struct vlc_gl_renderer *renderer = prgm->renderer;
+    const struct vlc_gl_interop *interop = renderer->interop;
+    renderer->pf_prepare_shader(renderer, vgl->tex_width, vgl->tex_height, 1.0f);
 
     for (unsigned j = 0; j < interop->tex_count; j++) {
         assert(vgl->texture[j] != 0);
@@ -1271,7 +1274,7 @@ static void TextureCropForStereo(vout_display_opengl_t *vgl,
                                  float *left, float *top,
                                  float *right, float *bottom)
 {
-    const struct vlc_gl_interop *interop = vgl->prgm.tc->interop;
+    const struct vlc_gl_interop *interop = vgl->prgm.renderer->interop;
 
     float stereoCoefs[2];
     float stereoOffsets[2];
@@ -1320,8 +1323,8 @@ int vout_display_opengl_Display(vout_display_opengl_t *vgl,
         float top[PICTURE_PLANE_MAX];
         float right[PICTURE_PLANE_MAX];
         float bottom[PICTURE_PLANE_MAX];
-        const opengl_tex_converter_t *tc = vgl->prgm.tc;
-        const struct vlc_gl_interop *interop = tc->interop;
+        const struct vlc_gl_renderer *renderer = vgl->prgm.renderer;
+        const struct vlc_gl_interop *interop = renderer->interop;
         for (unsigned j = 0; j < interop->tex_count; j++)
         {
             float scale_w = (float)interop->texs[j].w.num / interop->texs[j].w.den
index 72895f8..03f4f68 100644 (file)
@@ -29,7 +29,7 @@
 #ifndef VLC_OPENGL_VOUT_HELPER_H
 #define VLC_OPENGL_VOUT_HELPER_H
 
-#include "converter.h"
+#include "gl_common.h"
 
 #ifdef HAVE_LIBPLACEBO
 #include "../placebo_utils.h"