[vlc-devel] [PATCH 06/10] opengl: update pictures from sampler

Alexandre Janniaux ajanni at videolabs.io
Fri May 29 18:05:48 CEST 2020


Hi,

On Wed, May 20, 2020 at 04:08:17PM +0200, Romain Vimont wrote:
> The renderer should not know the interop, so it may not be responsible
> to upload the textures.

Nit, should probably be «be responsible for uploading» or
probably better «be in charge of uploading the textures».

Patch lgtm.

Regards,
--
Alexandre Janniaux
Videolabs


>
> Move the pictures update to sampler.
> ---
>  modules/video_output/opengl/renderer.c | 89 +-----------------------
>  modules/video_output/opengl/sampler.c  | 94 ++++++++++++++++++++++++++
>  modules/video_output/opengl/sampler.h  | 11 +++
>  3 files changed, 106 insertions(+), 88 deletions(-)
>
> diff --git a/modules/video_output/opengl/renderer.c b/modules/video_output/opengl/renderer.c
> index 983429badd58..b6c13ba55969 100644
> --- a/modules/video_output/opengl/renderer.c
> +++ b/modules/video_output/opengl/renderer.c
> @@ -783,94 +783,7 @@ int
>  vlc_gl_renderer_Prepare(struct vlc_gl_renderer *renderer, picture_t *picture)
>  {
>      struct vlc_gl_sampler *sampler = renderer->sampler;
> -    const struct vlc_gl_interop *interop = sampler->interop;
> -    const video_format_t *source = &picture->format;
> -
> -    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(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
> -                          / sampler->tex_width[j];
> -            float scale_h = (float)interop->texs[j].h.num / interop->texs[j].h.den
> -                          / sampler->tex_height[j];
> -
> -            /* Warning: if NPOT is not supported a larger texture is
> -               allocated. This will cause right and bottom coordinates to
> -               land on the edge of two texels with the texels to the
> -               right/bottom uninitialized by the call to
> -               glTexSubImage2D. This might cause a green line to appear on
> -               the right/bottom of the display.
> -               There are two possible solutions:
> -               - Manually mirror the edges of the texture.
> -               - Add a "-1" when computing right and bottom, however the
> -               last row/column might not be displayed at all.
> -            */
> -            float left   = (source->i_x_offset +                       0 ) * scale_w;
> -            float top    = (source->i_y_offset +                       0 ) * scale_h;
> -            float right  = (source->i_x_offset + source->i_visible_width ) * scale_w;
> -            float bottom = (source->i_y_offset + source->i_visible_height) * scale_h;
> -
> -            /**
> -             * This matrix converts from picture coordinates (in range [0; 1])
> -             * to textures coordinates where the picture is actually stored
> -             * (removing paddings).
> -             *
> -             *        texture           (in texture coordinates)
> -             *       +----------------+--- 0.0
> -             *       |                |
> -             *       |  +---------+---|--- top
> -             *       |  | picture |   |
> -             *       |  +---------+---|--- bottom
> -             *       |  .         .   |
> -             *       |  .         .   |
> -             *       +----------------+--- 1.0
> -             *       |  .         .   |
> -             *      0.0 left  right  1.0  (in texture coordinates)
> -             *
> -             * In particular:
> -             *  - (0.0, 0.0) is mapped to (left, top)
> -             *  - (1.0, 1.0) is mapped to (right, bottom)
> -             *
> -             * This is an affine 2D transformation, so the input coordinates
> -             * are given as a 3D vector in the form (x, y, 1), and the output
> -             * is (x', y', 1).
> -             *
> -             * The paddings are l (left), r (right), t (top) and b (bottom).
> -             *
> -             *               / (r-l)   0     l \
> -             *      matrix = |   0   (b-t)   t |
> -             *               \   0     0     1 /
> -             *
> -             * It is stored in column-major order.
> -             */
> -            GLfloat *matrix = sampler->var.TexCoordsMap[j];
> -#define COL(x) (x*3)
> -#define ROW(x) (x)
> -            matrix[COL(0) + ROW(0)] = right - left;
> -            matrix[COL(1) + ROW(1)] = bottom - top;
> -            matrix[COL(2) + ROW(0)] = left;
> -            matrix[COL(2) + ROW(1)] = top;
> -#undef COL
> -#undef ROW
> -        }
> -
> -        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, sampler->textures,
> -                                         sampler->tex_width,
> -                                         sampler->tex_height, picture,
> -                                         NULL);
> +    return vlc_gl_sampler_Update(sampler, picture);
>  }
>
>  int
> diff --git a/modules/video_output/opengl/sampler.c b/modules/video_output/opengl/sampler.c
> index 93cc24956e31..6f3ab54c49c2 100644
> --- a/modules/video_output/opengl/sampler.c
> +++ b/modules/video_output/opengl/sampler.c
> @@ -143,3 +143,97 @@ vlc_gl_sampler_Delete(struct vlc_gl_sampler *sampler)
>
>      free(sampler);
>  }
> +
> +int
> +vlc_gl_sampler_Update(struct vlc_gl_sampler *sampler, picture_t *picture)
> +{
> +    const struct vlc_gl_interop *interop = sampler->interop;
> +    const video_format_t *source = &picture->format;
> +
> +    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(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
> +                          / sampler->tex_width[j];
> +            float scale_h = (float)interop->texs[j].h.num / interop->texs[j].h.den
> +                          / sampler->tex_height[j];
> +
> +            /* Warning: if NPOT is not supported a larger texture is
> +               allocated. This will cause right and bottom coordinates to
> +               land on the edge of two texels with the texels to the
> +               right/bottom uninitialized by the call to
> +               glTexSubImage2D. This might cause a green line to appear on
> +               the right/bottom of the display.
> +               There are two possible solutions:
> +               - Manually mirror the edges of the texture.
> +               - Add a "-1" when computing right and bottom, however the
> +               last row/column might not be displayed at all.
> +            */
> +            float left   = (source->i_x_offset +                       0 ) * scale_w;
> +            float top    = (source->i_y_offset +                       0 ) * scale_h;
> +            float right  = (source->i_x_offset + source->i_visible_width ) * scale_w;
> +            float bottom = (source->i_y_offset + source->i_visible_height) * scale_h;
> +
> +            /**
> +             * This matrix converts from picture coordinates (in range [0; 1])
> +             * to textures coordinates where the picture is actually stored
> +             * (removing paddings).
> +             *
> +             *        texture           (in texture coordinates)
> +             *       +----------------+--- 0.0
> +             *       |                |
> +             *       |  +---------+---|--- top
> +             *       |  | picture |   |
> +             *       |  +---------+---|--- bottom
> +             *       |  .         .   |
> +             *       |  .         .   |
> +             *       +----------------+--- 1.0
> +             *       |  .         .   |
> +             *      0.0 left  right  1.0  (in texture coordinates)
> +             *
> +             * In particular:
> +             *  - (0.0, 0.0) is mapped to (left, top)
> +             *  - (1.0, 1.0) is mapped to (right, bottom)
> +             *
> +             * This is an affine 2D transformation, so the input coordinates
> +             * are given as a 3D vector in the form (x, y, 1), and the output
> +             * is (x', y', 1).
> +             *
> +             * The paddings are l (left), r (right), t (top) and b (bottom).
> +             *
> +             *               / (r-l)   0     l \
> +             *      matrix = |   0   (b-t)   t |
> +             *               \   0     0     1 /
> +             *
> +             * It is stored in column-major order.
> +             */
> +            GLfloat *matrix = sampler->var.TexCoordsMap[j];
> +#define COL(x) (x*3)
> +#define ROW(x) (x)
> +            matrix[COL(0) + ROW(0)] = right - left;
> +            matrix[COL(1) + ROW(1)] = bottom - top;
> +            matrix[COL(2) + ROW(0)] = left;
> +            matrix[COL(2) + ROW(1)] = top;
> +            matrix[COL(2) + ROW(2)] = 1;
> +#undef COL
> +#undef ROW
> +        }
> +
> +        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, sampler->textures,
> +                                         sampler->tex_width,
> +                                         sampler->tex_height, picture,
> +                                         NULL);
> +}
> diff --git a/modules/video_output/opengl/sampler.h b/modules/video_output/opengl/sampler.h
> index 93af7b1759d1..5afa9d2afd1d 100644
> --- a/modules/video_output/opengl/sampler.h
> +++ b/modules/video_output/opengl/sampler.h
> @@ -148,6 +148,17 @@ vlc_gl_sampler_New(struct vlc_gl_interop *interop);
>  void
>  vlc_gl_sampler_Delete(struct vlc_gl_sampler *sampler);
>
> +/**
> + * Update the input picture
> + *
> + * This changes the current input picture, available from the fragment shader.
> + *
> + * \param sampler the samplre
> + * \param picture the new current picture
> + */
> +int
> +vlc_gl_sampler_Update(struct vlc_gl_sampler *sampler, picture_t *picture);
> +
>  static inline int
>  vlc_gl_sampler_FetchLocations(struct vlc_gl_sampler *sampler, GLuint program)
>  {
> --
> 2.27.0.rc0
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel


More information about the vlc-devel mailing list