[vlc-devel] [PATCH 01/17] opengl: extract renderer fields to sampler

Romain Vimont rom1v at videolabs.io
Thu Apr 2 14:24:14 CEST 2020


Move the fields necessary to retrieve a picture pixel from its
coordinates.
---
 modules/video_output/Makefile.am              |   1 +
 .../video_output/opengl/fragment_shaders.c    |  84 +++++++------
 modules/video_output/opengl/renderer.c        | 115 ++++++++++--------
 modules/video_output/opengl/renderer.h        |  36 +-----
 modules/video_output/opengl/sampler.h         |  90 ++++++++++++++
 5 files changed, 206 insertions(+), 120 deletions(-)
 create mode 100644 modules/video_output/opengl/sampler.h

diff --git a/modules/video_output/Makefile.am b/modules/video_output/Makefile.am
index a61d15f20f..1d25ea91a8 100644
--- a/modules/video_output/Makefile.am
+++ b/modules/video_output/Makefile.am
@@ -15,6 +15,7 @@ OPENGL_COMMONSOURCES = video_output/opengl/vout_helper.c \
 	video_output/opengl/interop.c video_output/opengl/interop_sw.c \
 	video_output/opengl/renderer.c \
 	video_output/opengl/renderer.h \
+	video_output/opengl/sampler.h \
 	video_output/opengl/sub_renderer.c \
 	video_output/opengl/sub_renderer.h
 if HAVE_LIBPLACEBO
diff --git a/modules/video_output/opengl/fragment_shaders.c b/modules/video_output/opengl/fragment_shaders.c
index 117020cbe7..afcc52c865 100644
--- a/modules/video_output/opengl/fragment_shaders.c
+++ b/modules/video_output/opengl/fragment_shaders.c
@@ -35,6 +35,7 @@
 #include <vlc_memstream.h>
 #include "interop.h"
 #include "internal.h"
+#include "sampler.h"
 #include "vout_helper.h"
 
 static const float MATRIX_COLOR_RANGE_LIMITED[4*3] = {
@@ -132,9 +133,11 @@ renderer_yuv_base_init(struct vlc_gl_renderer *renderer, vlc_fourcc_t chroma,
                        const vlc_chroma_description_t *desc,
                        video_color_space_t yuv_space)
 {
+    struct vlc_gl_sampler *sampler = renderer->sampler;
+
     /* The current implementation always converts from limited to full range. */
     const video_color_range_t range = COLOR_RANGE_LIMITED;
-    float *matrix = renderer->conv_matrix;
+    float *matrix = sampler->conv_matrix;
     init_conv_matrix(matrix, yuv_space, range);
 
     if (desc->pixel_size == 2)
@@ -167,7 +170,7 @@ renderer_yuv_base_init(struct vlc_gl_renderer *renderer, vlc_fourcc_t chroma,
         }
     }
 
-    renderer->yuv_color = true;
+    sampler->yuv_color = true;
 
     /* Some formats require to swap the U and V components.
      *
@@ -205,13 +208,14 @@ static int
 renderer_base_fetch_locations(struct vlc_gl_renderer *renderer, GLuint program)
 {
     struct vlc_gl_interop *interop = renderer->interop;
+    struct vlc_gl_sampler *sampler = renderer->sampler;
     const opengl_vtable_t *vt = renderer->vt;
 
-    if (renderer->yuv_color)
+    if (sampler->yuv_color)
     {
-        renderer->uloc.ConvMatrix = vt->GetUniformLocation(program,
-                                                           "ConvMatrix");
-        if (renderer->uloc.ConvMatrix == -1)
+        sampler->uloc.ConvMatrix = vt->GetUniformLocation(program,
+                                                          "ConvMatrix");
+        if (sampler->uloc.ConvMatrix == -1)
             return VLC_EGENERIC;
     }
 
@@ -219,27 +223,27 @@ renderer_base_fetch_locations(struct vlc_gl_renderer *renderer, GLuint program)
     {
         char name[sizeof("TextureX")];
         snprintf(name, sizeof(name), "Texture%1u", i);
-        renderer->uloc.Texture[i] = vt->GetUniformLocation(program, name);
-        if (renderer->uloc.Texture[i] == -1)
+        sampler->uloc.Texture[i] = vt->GetUniformLocation(program, name);
+        if (sampler->uloc.Texture[i] == -1)
             return VLC_EGENERIC;
         if (interop->tex_target == GL_TEXTURE_RECTANGLE)
         {
             snprintf(name, sizeof(name), "TexSize%1u", i);
-            renderer->uloc.TexSize[i] = vt->GetUniformLocation(program, name);
-            if (renderer->uloc.TexSize[i] == -1)
+            sampler->uloc.TexSize[i] = vt->GetUniformLocation(program, name);
+            if (sampler->uloc.TexSize[i] == -1)
                 return VLC_EGENERIC;
         }
     }
 
-    renderer->uloc.FillColor = vt->GetUniformLocation(program, "FillColor");
-    if (renderer->uloc.FillColor == -1)
+    sampler->uloc.FillColor = vt->GetUniformLocation(program, "FillColor");
+    if (sampler->uloc.FillColor == -1)
         return VLC_EGENERIC;
 
 #ifdef HAVE_LIBPLACEBO
-    const struct pl_shader_res *res = renderer->pl_sh_res;
+    const struct pl_shader_res *res = sampler->pl_sh_res;
     for (int i = 0; res && i < res->num_variables; i++) {
         struct pl_shader_var sv = res->variables[i];
-        renderer->uloc.pl_vars[i] = vt->GetUniformLocation(program, sv.var.name);
+        sampler->uloc.pl_vars[i] = vt->GetUniformLocation(program, sv.var.name);
     }
 #endif
 
@@ -253,28 +257,29 @@ renderer_base_prepare_shader(const struct vlc_gl_renderer *renderer,
 {
     (void) tex_width; (void) tex_height;
     const struct vlc_gl_interop *interop = renderer->interop;
+    struct vlc_gl_sampler *sampler = renderer->sampler;
     const opengl_vtable_t *vt = renderer->vt;
 
-    if (renderer->yuv_color)
-        vt->UniformMatrix4fv(renderer->uloc.ConvMatrix, 1, GL_FALSE,
-                             renderer->conv_matrix);
+    if (sampler->yuv_color)
+        vt->UniformMatrix4fv(sampler->uloc.ConvMatrix, 1, GL_FALSE,
+                             sampler->conv_matrix);
 
     for (unsigned i = 0; i < interop->tex_count; ++i)
-        vt->Uniform1i(renderer->uloc.Texture[i], i);
+        vt->Uniform1i(sampler->uloc.Texture[i], i);
 
-    vt->Uniform4f(renderer->uloc.FillColor, 1.0f, 1.0f, 1.0f, alpha);
+    vt->Uniform4f(sampler->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)
-            vt->Uniform2f(renderer->uloc.TexSize[i], tex_width[i],
+            vt->Uniform2f(sampler->uloc.TexSize[i], tex_width[i],
                           tex_height[i]);
     }
 
 #ifdef HAVE_LIBPLACEBO
-    const struct pl_shader_res *res = renderer->pl_sh_res;
+    const struct pl_shader_res *res = sampler->pl_sh_res;
     for (int i = 0; res && i < res->num_variables; i++) {
-        GLint loc = renderer->uloc.pl_vars[i];
+        GLint loc = sampler->uloc.pl_vars[i];
         if (loc == -1) // uniform optimized out
             continue;
 
@@ -309,8 +314,10 @@ static int
 renderer_xyz12_fetch_locations(struct vlc_gl_renderer *renderer, GLuint program)
 {
     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;
+    struct vlc_gl_sampler *sampler = renderer->sampler;
+
+    sampler->uloc.Texture[0] = vt->GetUniformLocation(program, "Texture0");
+    return sampler->uloc.Texture[0] != -1 ? VLC_SUCCESS : VLC_EGENERIC;
 }
 
 static void
@@ -320,7 +327,9 @@ renderer_xyz12_prepare_shader(const struct vlc_gl_renderer *renderer,
 {
     (void) tex_width; (void) tex_height; (void) alpha;
     const opengl_vtable_t *vt = renderer->vt;
-    vt->Uniform1i(renderer->uloc.Texture[0], 0);
+    struct vlc_gl_sampler *sampler = renderer->sampler;
+
+    vt->Uniform1i(sampler->uloc.Texture[0], 0);
 }
 
 static char *
@@ -431,6 +440,7 @@ 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 = renderer->interop;
+    struct vlc_gl_sampler *sampler = renderer->sampler;
 
     const char *swizzle_per_tex[PICTURE_PLANE_MAX] = { NULL, };
     const bool is_yuv = vlc_fourcc_IsYUV(chroma);
@@ -453,19 +463,19 @@ opengl_fragment_shader_init(struct vlc_gl_renderer *renderer, GLenum tex_target,
             return NULL;
     }
 
-    const char *sampler, *lookup;
+    const char *sampler_name, *lookup;
     switch (tex_target)
     {
         case GL_TEXTURE_EXTERNAL_OES:
-            sampler = "samplerExternalOES";
+            sampler_name = "samplerExternalOES";
             lookup = "texture2D";
             break;
         case GL_TEXTURE_2D:
-            sampler = "sampler2D";
+            sampler_name = "sampler2D";
             lookup  = "texture2D";
             break;
         case GL_TEXTURE_RECTANGLE:
-            sampler = "sampler2DRect";
+            sampler_name = "sampler2DRect";
             lookup  = "texture2DRect";
             break;
         default:
@@ -483,11 +493,11 @@ opengl_fragment_shader_init(struct vlc_gl_renderer *renderer, GLenum tex_target,
         "uniform mat4 OrientationMatrix;\n");
     for (unsigned i = 0; i < interop->tex_count; ++i)
         ADDF("uniform %s Texture%u;\n"
-             "uniform mat3 TexCoordsMap%u;\n", sampler, i, i);
+             "uniform mat3 TexCoordsMap%u;\n", sampler_name, i, i);
 
 #ifdef HAVE_LIBPLACEBO
-    if (renderer->pl_sh) {
-        struct pl_shader *sh = renderer->pl_sh;
+    if (sampler->pl_sh) {
+        struct pl_shader *sh = sampler->pl_sh;
         struct pl_color_map_params color_params = pl_color_map_default_params;
         color_params.intent = var_InheritInteger(renderer->gl, "rendering-intent");
         color_params.tone_mapping_algo = var_InheritInteger(renderer->gl, "tone-mapping");
@@ -539,11 +549,11 @@ opengl_fragment_shader_init(struct vlc_gl_renderer *renderer, GLenum tex_target,
             });
         }
 
-        const struct pl_shader_res *res = renderer->pl_sh_res = pl_shader_finalize(sh);
+        const struct pl_shader_res *res = sampler->pl_sh_res = pl_shader_finalize(sh);
         pl_shader_obj_destroy(&dither_state);
 
-        FREENULL(renderer->uloc.pl_vars);
-        renderer->uloc.pl_vars = calloc(res->num_variables, sizeof(GLint));
+        FREENULL(sampler->uloc.pl_vars);
+        sampler->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);
@@ -618,8 +628,8 @@ opengl_fragment_shader_init(struct vlc_gl_renderer *renderer, GLenum tex_target,
     assert(yuv_space == COLOR_SPACE_UNDEF || color_count == 3);
 
 #ifdef HAVE_LIBPLACEBO
-    if (renderer->pl_sh_res) {
-        const struct pl_shader_res *res = renderer->pl_sh_res;
+    if (sampler->pl_sh_res) {
+        const struct pl_shader_res *res = sampler->pl_sh_res;
         assert(res->input  == PL_SHADER_SIG_COLOR);
         assert(res->output == PL_SHADER_SIG_COLOR);
         ADDF(" result = %s(result);\n", res->name);
diff --git a/modules/video_output/opengl/renderer.c b/modules/video_output/opengl/renderer.c
index ae4179be4a..593f6e0437 100644
--- a/modules/video_output/opengl/renderer.c
+++ b/modules/video_output/opengl/renderer.c
@@ -318,6 +318,7 @@ static int
 opengl_link_program(struct vlc_gl_renderer *renderer)
 {
     struct vlc_gl_interop *interop = renderer->interop;
+    struct vlc_gl_sampler *sampler = renderer->sampler;
     const opengl_vtable_t *vt = renderer->vt;
 
     char *vertex_shader = BuildVertexShader(renderer);
@@ -357,8 +358,6 @@ opengl_link_program(struct vlc_gl_renderer *renderer)
 } while (0)
 #define GET_ULOC(x, str) GET_LOC(Uniform, renderer->uloc.x, str)
 #define GET_ALOC(x, str) GET_LOC(Attrib, renderer->aloc.x, str)
-    GET_ULOC(TransformMatrix, "TransformMatrix");
-    GET_ULOC(OrientationMatrix, "OrientationMatrix");
     GET_ULOC(StereoMatrix, "StereoMatrix");
     GET_ULOC(ProjectionMatrix, "ProjectionMatrix");
     GET_ULOC(ViewMatrix, "ViewMatrix");
@@ -367,19 +366,23 @@ opengl_link_program(struct vlc_gl_renderer *renderer)
     GET_ALOC(PicCoordsIn, "PicCoordsIn");
     GET_ALOC(VertexPosition, "VertexPosition");
 
-    GET_ULOC(TexCoordsMap[0], "TexCoordsMap0");
+#define GET_SAMPLER_ULOC(x, str) GET_LOC(Uniform, sampler->uloc.x, str)
+    GET_SAMPLER_ULOC(TransformMatrix, "TransformMatrix");
+    GET_SAMPLER_ULOC(OrientationMatrix, "OrientationMatrix");
+    GET_SAMPLER_ULOC(TexCoordsMap[0], "TexCoordsMap0");
     /* MultiTexCoord 1 and 2 can be optimized out if not used */
     if (interop->tex_count > 1)
-        GET_ULOC(TexCoordsMap[1], "TexCoordsMap1");
+        GET_SAMPLER_ULOC(TexCoordsMap[1], "TexCoordsMap1");
     else
-        renderer->uloc.TexCoordsMap[1] = -1;
+        sampler->uloc.TexCoordsMap[1] = -1;
     if (interop->tex_count > 2)
-        GET_ULOC(TexCoordsMap[2], "TexCoordsMap2");
+        GET_SAMPLER_ULOC(TexCoordsMap[2], "TexCoordsMap2");
     else
-        renderer->uloc.TexCoordsMap[2] = -1;
+        sampler->uloc.TexCoordsMap[2] = -1;
 #undef GET_LOC
 #undef GET_ULOC
 #undef GET_ALOC
+#undef GET_SAMPLER_ULOC
     int ret = renderer->pf_fetch_locations(renderer, program_id);
     assert(ret == VLC_SUCCESS);
     if (ret != VLC_SUCCESS)
@@ -402,6 +405,7 @@ void
 vlc_gl_renderer_Delete(struct vlc_gl_renderer *renderer)
 {
     struct vlc_gl_interop *interop = renderer->interop;
+    struct vlc_gl_sampler *sampler = renderer->sampler;
     const opengl_vtable_t *vt = renderer->vt;
 
     vt->DeleteBuffers(1, &renderer->vertex_buffer_object);
@@ -409,18 +413,19 @@ vlc_gl_renderer_Delete(struct vlc_gl_renderer *renderer)
     vt->DeleteBuffers(1, &renderer->texture_buffer_object);
 
     if (!interop->handle_texs_gen)
-        vt->DeleteTextures(interop->tex_count, renderer->textures);
+        vt->DeleteTextures(interop->tex_count, sampler->textures);
 
     vlc_gl_interop_Delete(interop);
     if (renderer->program_id != 0)
         vt->DeleteProgram(renderer->program_id);
 
 #ifdef HAVE_LIBPLACEBO
-    FREENULL(renderer->uloc.pl_vars);
-    if (renderer->pl_ctx)
-        pl_context_destroy(&renderer->pl_ctx);
+    FREENULL(sampler->uloc.pl_vars);
+    if (sampler->pl_ctx)
+        pl_context_destroy(&sampler->pl_ctx);
 #endif
 
+    free(renderer->sampler);
     free(renderer);
 }
 
@@ -433,15 +438,25 @@ vlc_gl_renderer_New(vlc_gl_t *gl, const struct vlc_gl_api *api,
 {
     const opengl_vtable_t *vt = &api->vt;
 
+    struct vlc_gl_sampler *sampler = calloc(1, sizeof(*sampler));
+    if (!sampler)
+        return NULL;
+
     struct vlc_gl_renderer *renderer = calloc(1, sizeof(*renderer));
     if (!renderer)
+    {
+        free(sampler);
         return NULL;
+    }
+
+    renderer->sampler = sampler;
 
     struct vlc_gl_interop *interop =
         vlc_gl_interop_New(gl, api, context, fmt, false);
     if (!interop)
     {
         free(renderer);
+        free(sampler);
         return NULL;
     }
 
@@ -461,14 +476,14 @@ vlc_gl_renderer_New(vlc_gl_t *gl, const struct vlc_gl_api *api,
 
 #ifdef HAVE_LIBPLACEBO
     // Create the main libplacebo context
-    renderer->pl_ctx = vlc_placebo_Create(VLC_OBJECT(gl));
-    if (renderer->pl_ctx) {
+    sampler->pl_ctx = vlc_placebo_Create(VLC_OBJECT(gl));
+    if (sampler->pl_ctx) {
 #   if PL_API_VER >= 20
-        renderer->pl_sh = pl_shader_alloc(renderer->pl_ctx, NULL);
+        sampler->pl_sh = pl_shader_alloc(sampler->pl_ctx, NULL);
 #   elif PL_API_VER >= 6
-        renderer->pl_sh = pl_shader_alloc(renderer->pl_ctx, NULL, 0);
+        sampler->pl_sh = pl_shader_alloc(sampler->pl_ctx, NULL, 0);
 #   else
-        renderer->pl_sh = pl_shader_alloc(renderer->pl_ctx, NULL, 0, 0);
+        sampler->pl_sh = pl_shader_alloc(sampler->pl_ctx, NULL, 0, 0);
 #   endif
     }
 #endif
@@ -483,7 +498,7 @@ vlc_gl_renderer_New(vlc_gl_t *gl, const struct vlc_gl_api *api,
     InitStereoMatrix(renderer->var.StereoMatrix, interop->fmt.multiview_mode);
 
     getOrientationTransformMatrix(interop->fmt.orientation,
-                                  renderer->var.OrientationMatrix);
+                                  sampler->var.OrientationMatrix);
     getViewpointMatrixes(renderer, interop->fmt.projection_mode);
 
     /* Update the fmt to main program one */
@@ -498,19 +513,19 @@ vlc_gl_renderer_New(vlc_gl_t *gl, const struct vlc_gl_api *api,
         const GLsizei h = renderer->fmt.i_visible_height * interop->texs[j].h.num
                         / interop->texs[j].h.den;
         if (api->supports_npot) {
-            renderer->tex_width[j]  = w;
-            renderer->tex_height[j] = h;
+            sampler->tex_width[j]  = w;
+            sampler->tex_height[j] = h;
         } else {
-            renderer->tex_width[j]  = vlc_align_pot(w);
-            renderer->tex_height[j] = vlc_align_pot(h);
+            sampler->tex_width[j]  = vlc_align_pot(w);
+            sampler->tex_height[j] = vlc_align_pot(h);
         }
     }
 
     if (!interop->handle_texs_gen)
     {
-        ret = vlc_gl_interop_GenerateTextures(interop, renderer->tex_width,
-                                              renderer->tex_height,
-                                              renderer->textures);
+        ret = vlc_gl_interop_GenerateTextures(interop, sampler->tex_width,
+                                              sampler->tex_height,
+                                              sampler->textures);
         if (ret != VLC_SUCCESS)
         {
             vlc_gl_renderer_Delete(renderer);
@@ -902,17 +917,18 @@ static int SetupCoords(struct vlc_gl_renderer *renderer)
 static void DrawWithShaders(struct vlc_gl_renderer *renderer)
 {
     const struct vlc_gl_interop *interop = renderer->interop;
+    struct vlc_gl_sampler *sampler = renderer->sampler;
     const opengl_vtable_t *vt = renderer->vt;
-    renderer->pf_prepare_shader(renderer, renderer->tex_width,
-                                renderer->tex_height, 1.0f);
+    renderer->pf_prepare_shader(renderer, sampler->tex_width,
+                                sampler->tex_height, 1.0f);
 
     for (unsigned j = 0; j < interop->tex_count; j++) {
-        assert(renderer->textures[j] != 0);
+        assert(sampler->textures[j] != 0);
         vt->ActiveTexture(GL_TEXTURE0+j);
-        vt->BindTexture(interop->tex_target, renderer->textures[j]);
+        vt->BindTexture(interop->tex_target, sampler->textures[j]);
 
-        vt->UniformMatrix3fv(renderer->uloc.TexCoordsMap[j], 1, GL_FALSE,
-                             renderer->var.TexCoordsMap[j]);
+        vt->UniformMatrix3fv(sampler->uloc.TexCoordsMap[j], 1, GL_FALSE,
+                             sampler->var.TexCoordsMap[j]);
     }
 
     vt->BindBuffer(GL_ARRAY_BUFFER, renderer->texture_buffer_object);
@@ -931,10 +947,10 @@ static void DrawWithShaders(struct vlc_gl_renderer *renderer)
     if (!tm)
         tm = identity;
 
-    vt->UniformMatrix4fv(renderer->uloc.TransformMatrix, 1, GL_FALSE, tm);
+    vt->UniformMatrix4fv(sampler->uloc.TransformMatrix, 1, GL_FALSE, tm);
 
-    vt->UniformMatrix4fv(renderer->uloc.OrientationMatrix, 1, GL_FALSE,
-                         renderer->var.OrientationMatrix);
+    vt->UniformMatrix4fv(sampler->uloc.OrientationMatrix, 1, GL_FALSE,
+                         sampler->var.OrientationMatrix);
     vt->UniformMatrix3fv(renderer->uloc.StereoMatrix, 1, GL_FALSE,
                          renderer->var.StereoMatrix);
     vt->UniformMatrix4fv(renderer->uloc.ProjectionMatrix, 1, GL_FALSE,
@@ -951,21 +967,22 @@ int
 vlc_gl_renderer_Prepare(struct vlc_gl_renderer *renderer, picture_t *picture)
 {
     const struct vlc_gl_interop *interop = renderer->interop;
+    struct vlc_gl_sampler *sampler = renderer->sampler;
     const video_format_t *source = &picture->format;
 
-    if (source->i_x_offset != renderer->last_source.i_x_offset
-     || source->i_y_offset != renderer->last_source.i_y_offset
-     || source->i_visible_width != renderer->last_source.i_visible_width
-     || source->i_visible_height != renderer->last_source.i_visible_height)
+    if (source->i_x_offset != sampler->last_source.i_x_offset
+     || source->i_y_offset != sampler->last_source.i_y_offset
+     || source->i_visible_width != sampler->last_source.i_visible_width
+     || source->i_visible_height != sampler->last_source.i_visible_height)
     {
-        memset(renderer->var.TexCoordsMap, 0,
-               sizeof(renderer->var.TexCoordsMap));
+        memset(sampler->var.TexCoordsMap, 0,
+               sizeof(sampler->var.TexCoordsMap));
         for (unsigned j = 0; j < interop->tex_count; j++)
         {
             float scale_w = (float)interop->texs[j].w.num / interop->texs[j].w.den
-                          / renderer->tex_width[j];
+                          / sampler->tex_width[j];
             float scale_h = (float)interop->texs[j].h.num / interop->texs[j].h.den
-                          / renderer->tex_height[j];
+                          / sampler->tex_height[j];
 
             /* Warning: if NPOT is not supported a larger texture is
                allocated. This will cause right and bottom coordinates to
@@ -1016,7 +1033,7 @@ vlc_gl_renderer_Prepare(struct vlc_gl_renderer *renderer, picture_t *picture)
              *
              * It is stored in column-major order.
              */
-            GLfloat *matrix = renderer->var.TexCoordsMap[j];
+            GLfloat *matrix = sampler->var.TexCoordsMap[j];
 #define COL(x) (x*3)
 #define ROW(x) (x)
             matrix[COL(0) + ROW(0)] = right - left;
@@ -1027,16 +1044,16 @@ vlc_gl_renderer_Prepare(struct vlc_gl_renderer *renderer, picture_t *picture)
 #undef ROW
         }
 
-        renderer->last_source.i_x_offset = source->i_x_offset;
-        renderer->last_source.i_y_offset = source->i_y_offset;
-        renderer->last_source.i_visible_width = source->i_visible_width;
-        renderer->last_source.i_visible_height = source->i_visible_height;
+        sampler->last_source.i_x_offset = source->i_x_offset;
+        sampler->last_source.i_y_offset = source->i_y_offset;
+        sampler->last_source.i_visible_width = source->i_visible_width;
+        sampler->last_source.i_visible_height = source->i_visible_height;
     }
 
     /* Update the texture */
-    return interop->ops->update_textures(interop, renderer->textures,
-                                         renderer->tex_width,
-                                         renderer->tex_height, picture,
+    return interop->ops->update_textures(interop, sampler->textures,
+                                         sampler->tex_width,
+                                         sampler->tex_height, picture,
                                          NULL);
 }
 
diff --git a/modules/video_output/opengl/renderer.h b/modules/video_output/opengl/renderer.h
index 8151045eb4..0f6e3dcef8 100644
--- a/modules/video_output/opengl/renderer.h
+++ b/modules/video_output/opengl/renderer.h
@@ -29,6 +29,7 @@
 #include "gl_api.h"
 #include "gl_common.h"
 #include "interop.h"
+#include "sampler.h"
 
 struct pl_context;
 struct pl_shader;
@@ -42,9 +43,6 @@ 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;
-
     /* Set by the caller */
     const struct vlc_gl_api *api;
     const opengl_vtable_t *vt; /* for convenience, same as &api->vt */
@@ -61,30 +59,17 @@ struct vlc_gl_renderer
     GLuint program_id;
 
     struct {
-        GLfloat OrientationMatrix[16];
         GLfloat ProjectionMatrix[16];
         GLfloat StereoMatrix[3*3];
         GLfloat ZoomMatrix[16];
         GLfloat ViewMatrix[16];
-
-        GLfloat TexCoordsMap[PICTURE_PLANE_MAX][3*3];
     } var;
 
     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 */
-
-        GLint TransformMatrix;
-        GLint OrientationMatrix;
         GLint StereoMatrix;
         GLint ProjectionMatrix;
         GLint ViewMatrix;
         GLint ZoomMatrix;
-
-        GLint TexCoordsMap[PICTURE_PLANE_MAX];
     } uloc;
 
     struct {
@@ -92,33 +77,16 @@ struct vlc_gl_renderer
         GLint VertexPosition;
     } aloc;
 
-    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;
+    struct vlc_gl_sampler *sampler;
 
     video_format_t fmt;
 
-    GLsizei tex_width[PICTURE_PLANE_MAX];
-    GLsizei tex_height[PICTURE_PLANE_MAX];
-
-    GLuint textures[PICTURE_PLANE_MAX];
-
     unsigned nb_indices;
     GLuint vertex_buffer_object;
     GLuint index_buffer_object;
     GLuint texture_buffer_object;
 
-    struct {
-        unsigned int i_x_offset;
-        unsigned int i_y_offset;
-        unsigned int i_visible_width;
-        unsigned int i_visible_height;
-    } last_source;
-
     /* View point */
     vlc_viewpoint_t vp;
     float f_teta;
diff --git a/modules/video_output/opengl/sampler.h b/modules/video_output/opengl/sampler.h
new file mode 100644
index 0000000000..e4286a2011
--- /dev/null
+++ b/modules/video_output/opengl/sampler.h
@@ -0,0 +1,90 @@
+/*****************************************************************************
+ * sampler.h
+ *****************************************************************************
+ * Copyright (C) 2020 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_SAMPLER_H
+#define VLC_GL_SAMPLER_H
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_opengl.h>
+#include <vlc_picture.h>
+
+#include "gl_common.h"
+
+/**
+ * The purpose of a sampler is to provide pixel values of a VLC input picture,
+ * stored in any format.
+ *
+ * Concretely, a GLSL function:
+ *
+ *     vec4 vlc_texture(vec2 coords)
+ *
+ * returns the RGBA values for the given coordinates.
+ *
+ * Contrary to the standard GLSL function:
+ *
+ *     vec4 texture2D(sampler2D sampler, vec2 coords)
+ *
+ * it does not take a sampler2D as parameter. The role of the sampler is to
+ * abstract the input picture from the renderer, so the input picture is
+ * implicitly available.
+ */
+struct vlc_gl_sampler {
+    struct {
+        GLfloat OrientationMatrix[4*4];
+        GLfloat TexCoordsMap[PICTURE_PLANE_MAX][3*3];
+    } var;
+    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 */
+
+        GLint TransformMatrix;
+        GLint OrientationMatrix;
+        GLint TexCoordsMap[PICTURE_PLANE_MAX];
+    } uloc;
+
+    bool yuv_color;
+    GLfloat conv_matrix[4*4];
+
+    /* libplacebo context */
+    struct pl_context *pl_ctx;
+    struct pl_shader *pl_sh;
+    const struct pl_shader_res *pl_sh_res;
+
+    GLsizei tex_width[PICTURE_PLANE_MAX];
+    GLsizei tex_height[PICTURE_PLANE_MAX];
+
+    GLuint textures[PICTURE_PLANE_MAX];
+
+    struct {
+        unsigned int i_x_offset;
+        unsigned int i_y_offset;
+        unsigned int i_visible_width;
+        unsigned int i_visible_height;
+    } last_source;
+};
+
+#endif
-- 
2.26.0



More information about the vlc-devel mailing list