[vlc-commits] [Git][videolan/vlc][master] 2 commits: opengl: simplify TexSize multiplication

Romain Vimont (@rom1v) gitlab at videolan.org
Thu Sep 23 12:11:26 UTC 2021



Romain Vimont pushed to branch master at VideoLAN / VLC


Commits:
893aa567 by Romain Vimont at 2021-09-23T11:52:37+00:00
opengl: simplify TexSize multiplication

Multiply two vec2 directly instead of multiplying their components
separately.

- - - - -
499b7ef7 by Romain Vimont at 2021-09-23T11:52:37+00:00
opengl: simplify TexCoordsMaps in sampler

The input picture may contain padding, for two reasons:
 1. the rectangle defined by the picture_t offset and visible width and
    height may not cover the whole picture size;
 2. if the OpenGL API does not support NPOT textures, textures are
    created with power-of-two dimensions.

As a consequence, for sampling, the coordinates (between 0 and 1 in both
dimensions) must be transformed to take the padding into account.

These transformations were computed and performed per-plane. Therefore,
there were _n_ "TexCoordsMaps" matrices for a picture with _n_ planes.

However, these transformations are necessarily the same for all planes:
 1. the picture_t offset/sizes are defined for the whole picture (then
    scaled appropriately for each plane);
 2. since the ratio between different planes of the same pictures is
    always a power of two (e.g. in YUV 4:2:0, the size of U and V planes
    are half the size of the Y plane in both dimensions), this property
    holds even if we align the dimensions of each plane texture to the
    next power-of-two.

Therefore, use a single transformation matrix.

- - - - -


1 changed file:

- modules/video_output/opengl/sampler.c


Changes:

=====================================
modules/video_output/opengl/sampler.c
=====================================
@@ -48,7 +48,7 @@ struct vlc_gl_sampler_priv {
 
     struct {
         GLfloat OrientationMatrix[4*4];
-        GLfloat TexCoordsMaps[PICTURE_PLANE_MAX][3*3];
+        GLfloat TexCoordsMap[3*3];
     } var;
     struct {
         GLint Textures[PICTURE_PLANE_MAX];
@@ -58,7 +58,7 @@ struct vlc_gl_sampler_priv {
 
         GLint TransformMatrix;
         GLint OrientationMatrix;
-        GLint TexCoordsMaps[PICTURE_PLANE_MAX];
+        GLint TexCoordsMap;
     } uloc;
 
     bool yuv_color;
@@ -296,19 +296,18 @@ sampler_base_fetch_locations(struct vlc_gl_sampler *sampler, GLuint program)
         vt->GetUniformLocation(program, "OrientationMatrix");
     assert(priv->uloc.OrientationMatrix != -1);
 
+    priv->uloc.TexCoordsMap = vt->GetUniformLocation(program, "TexCoordsMap");
+    assert(priv->uloc.TexCoordsMap != -1);
+
     assert(sampler->tex_count < 10); /* to guarantee variable names length */
     for (unsigned int i = 0; i < sampler->tex_count; ++i)
     {
-        char name[sizeof("TexCoordsMaps[X]")];
+        char name[sizeof("Textures[X]")];
 
         snprintf(name, sizeof(name), "Textures[%1u]", i);
         priv->uloc.Textures[i] = vt->GetUniformLocation(program, name);
         assert(priv->uloc.Textures[i] != -1);
 
-        snprintf(name, sizeof(name), "TexCoordsMaps[%1u]", i);
-        priv->uloc.TexCoordsMaps[i] = vt->GetUniformLocation(program, name);
-        assert(priv->uloc.TexCoordsMaps[i] != -1);
-
         if (priv->tex_target == GL_TEXTURE_RECTANGLE)
         {
             snprintf(name, sizeof(name), "TexSizes[%1u]", i);
@@ -356,10 +355,11 @@ sampler_base_load(struct vlc_gl_sampler *sampler)
         vt->ActiveTexture(GL_TEXTURE0 + i);
         vt->BindTexture(priv->tex_target, priv->textures[i]);
 
-        vt->UniformMatrix3fv(priv->uloc.TexCoordsMaps[i], 1, GL_FALSE,
-                             priv->var.TexCoordsMaps[i]);
     }
 
+    vt->UniformMatrix3fv(priv->uloc.TexCoordsMap, 1, GL_FALSE,
+                         priv->var.TexCoordsMap);
+
     /* Return the expected transform matrix if interop == NULL */
     const GLfloat *tm = GetTransformMatrix(priv->interop);
     vt->UniformMatrix4fv(priv->uloc.TransformMatrix, 1, GL_FALSE, tm);
@@ -425,9 +425,8 @@ sampler_xyz12_fetch_locations(struct vlc_gl_sampler *sampler, GLuint program)
         vt->GetUniformLocation(program, "OrientationMatrix");
     assert(priv->uloc.OrientationMatrix != -1);
 
-    priv->uloc.TexCoordsMaps[0] =
-        vt->GetUniformLocation(program, "TexCoordsMaps[0]");
-    assert(priv->uloc.TexCoordsMaps[0] != -1);
+    priv->uloc.TexCoordsMap = vt->GetUniformLocation(program, "TexCoordsMap");
+    assert(priv->uloc.TexCoordsMap != -1);
 }
 
 static void
@@ -442,8 +441,8 @@ sampler_xyz12_load(struct vlc_gl_sampler *sampler)
     vt->ActiveTexture(GL_TEXTURE0);
     vt->BindTexture(priv->tex_target, priv->textures[0]);
 
-    vt->UniformMatrix3fv(priv->uloc.TexCoordsMaps[0], 1, GL_FALSE,
-                         priv->var.TexCoordsMaps[0]);
+    vt->UniformMatrix3fv(priv->uloc.TexCoordsMap, 1, GL_FALSE,
+                         priv->var.TexCoordsMap);
 
     /* Return the expected transform matrix if interop == NULL */
     const GLfloat *tm = GetTransformMatrix(priv->interop);
@@ -482,13 +481,11 @@ xyz12_shader_init(struct vlc_gl_sampler *sampler)
 
         "uniform mat4 TransformMatrix;\n"
         "uniform mat4 OrientationMatrix;\n"
-        "uniform mat3 TexCoordsMaps[1];\n"
+        "uniform mat3 TexCoordsMap;\n"
         "vec4 vlc_texture(vec2 pic_coords)\n"
         "{ "
         " vec4 v_in, v_out;"
-        /* Homogeneous (oriented) coordinates */
-        " vec3 pic_hcoords = vec3((TransformMatrix * OrientationMatrix * vec4(pic_coords, 0.0, 1.0)).st, 1.0);\n"
-        " vec2 tex_coords = (TexCoordsMaps[0] * pic_hcoords).st;\n"
+        " vec2 tex_coords = (TexCoordsMap * vec3((TransformMatrix * OrientationMatrix * vec4(pic_coords, 0.0, 1.0)).xy, 1.0)).xy;\n"
         " v_in  = texture2D(Textures[0], tex_coords);\n"
         " v_in = pow(v_in, xyz_gamma);"
         " v_out = matrix_xyz_rgb * v_in ;"
@@ -778,9 +775,8 @@ sampler_planes_fetch_locations(struct vlc_gl_sampler *sampler, GLuint program)
     priv->uloc.Textures[0] = vt->GetUniformLocation(program, "Texture");
     assert(priv->uloc.Textures[0] != -1);
 
-    priv->uloc.TexCoordsMaps[0] =
-        vt->GetUniformLocation(program, "TexCoordsMap");
-    assert(priv->uloc.TexCoordsMaps[0] != -1);
+    priv->uloc.TexCoordsMap = vt->GetUniformLocation(program, "TexCoordsMap");
+    assert(priv->uloc.TexCoordsMap != -1);
 
     if (priv->tex_target == GL_TEXTURE_RECTANGLE)
     {
@@ -803,13 +799,8 @@ sampler_planes_load(struct vlc_gl_sampler *sampler)
     vt->ActiveTexture(GL_TEXTURE0);
     vt->BindTexture(priv->tex_target, priv->textures[plane]);
 
-    /* Only one TexCoordMap matrix is necessary in the shader (its location is
-     * stored in uloc.TexCoordsMaps[0]), as there is only one plane per
-     * execution. However, for a single picture, there are several coords
-     * mapping matrices (one per plane), so the correct one
-     * (var.TexCoordsMaps[plane]) must be bound. */
-    vt->UniformMatrix3fv(priv->uloc.TexCoordsMaps[0], 1, GL_FALSE,
-                         priv->var.TexCoordsMaps[plane]);
+    vt->UniformMatrix3fv(priv->uloc.TexCoordsMap, 1, GL_FALSE,
+                         priv->var.TexCoordsMap);
 
     /* Return the expected transform matrix if interop == NULL */
     const GLfloat *tm = GetTransformMatrix(priv->interop);
@@ -851,15 +842,12 @@ sampler_planes_init(struct vlc_gl_sampler *sampler)
         ADD("uniform vec2 TexSize;\n");
 
     ADD("vec4 vlc_texture(vec2 pic_coords) {\n"
-        /* Homogeneous (oriented) coordinates */
-        "  vec3 pic_hcoords = vec3((TransformMatrix * OrientationMatrix * vec4(pic_coords, 0.0, 1.0)).st, 1.0);\n"
-        "  vec2 tex_coords = (TexCoordsMap * pic_hcoords).st;\n");
+        " vec2 tex_coords = (TexCoordsMap * vec3((TransformMatrix * OrientationMatrix * vec4(pic_coords, 0.0, 1.0)).xy, 1.0)).xy;\n");
 
     if (tex_target == GL_TEXTURE_RECTANGLE)
     {
         /* The coordinates are in texels values, not normalized */
-        ADD(" tex_coords = vec2(tex_coords.x * TexSize.x,\n"
-            "                   tex_coords.y * TexSize.y);\n");
+        ADD(" tex_coords = TexSize * tex_coords;\n");
     }
 
     ADDF("  return %s(Texture, tex_coords);\n", texture_fn);
@@ -944,7 +932,7 @@ opengl_fragment_shader_init(struct vlc_gl_sampler *sampler, GLenum tex_target,
     ADD("uniform mat4 TransformMatrix;\n"
         "uniform mat4 OrientationMatrix;\n");
     ADDF("uniform %s Textures[%u];\n", glsl_sampler, tex_count);
-    ADDF("uniform mat3 TexCoordsMaps[%u];\n", tex_count);
+    ADD("uniform mat3 TexCoordsMap;\n");
 
 #ifdef HAVE_LIBPLACEBO
     if (priv->pl_sh) {
@@ -1034,9 +1022,7 @@ opengl_fragment_shader_init(struct vlc_gl_sampler *sampler, GLenum tex_target,
         ADD("uniform mat4 ConvMatrix;\n");
 
     ADD("vec4 vlc_texture(vec2 pic_coords) {\n"
-        /* Homogeneous (oriented) coordinates */
-        " vec3 pic_hcoords = vec3((TransformMatrix * OrientationMatrix * vec4(pic_coords, 0.0, 1.0)).st, 1.0);\n"
-        " vec2 tex_coords;\n");
+        " vec2 tex_coords = (TexCoordsMap * vec3((TransformMatrix * OrientationMatrix * vec4(pic_coords, 0.0, 1.0)).xy, 1.0)).xy;\n");
 
     unsigned color_count;
     if (is_yuv) {
@@ -1048,14 +1034,15 @@ opengl_fragment_shader_init(struct vlc_gl_sampler *sampler, GLenum tex_target,
             const char *swizzle = swizzle_per_tex[i];
             assert(swizzle);
             size_t swizzle_count = strlen(swizzle);
-            ADDF(" tex_coords = (TexCoordsMaps[%u] * pic_hcoords).st;\n", i);
             if (tex_target == GL_TEXTURE_RECTANGLE)
             {
                 /* The coordinates are in texels values, not normalized */
-                ADDF(" tex_coords = vec2(tex_coords.x * TexSizes[%u].x,\n"
-                     "                   tex_coords.y * TexSizes[%u].y);\n", i, i);
+                ADDF(" texel = %s(Textures[%u], TexSizes[%u] * tex_coords);\n", lookup, i, i);
+            }
+            else
+            {
+                ADDF(" texel = %s(Textures[%u], tex_coords);\n", lookup, i);
             }
-            ADDF(" texel = %s(Textures[%u], tex_coords);\n", lookup, i);
             for (unsigned j = 0; j < swizzle_count; ++j)
             {
                 ADDF(" pixel[%u] = texel.%c;\n", color_idx, swizzle[j]);
@@ -1068,7 +1055,6 @@ opengl_fragment_shader_init(struct vlc_gl_sampler *sampler, GLenum tex_target,
     }
     else
     {
-        ADD(" tex_coords = (TexCoordsMaps[0] * pic_hcoords).st;\n");
         if (tex_target == GL_TEXTURE_RECTANGLE)
             ADD(" tex_coords *= TexSizes[0];\n");
 
@@ -1178,12 +1164,9 @@ CreateSampler(struct vlc_gl_interop *interop, struct vlc_gl_t *gl,
     unsigned tex_count = sampler->tex_count;
     assert(!interop || interop->tex_count == tex_count);
 
-    for (unsigned i = 0; i < tex_count; ++i)
-    {
-        /* This might be updated in UpdatePicture for non-direct samplers */
-        memcpy(&priv->var.TexCoordsMaps[i], MATRIX3_IDENTITY,
-               sizeof(MATRIX3_IDENTITY));
-    }
+    /* This might be updated in UpdatePicture for non-direct samplers */
+    memcpy(&priv->var.TexCoordsMap, MATRIX3_IDENTITY,
+           sizeof(MATRIX3_IDENTITY));
 
     if (interop)
     {
@@ -1275,74 +1258,74 @@ vlc_gl_sampler_UpdatePicture(struct vlc_gl_sampler *sampler, picture_t *picture)
      || source->i_visible_width != priv->last_source.i_visible_width
      || source->i_visible_height != priv->last_source.i_visible_height)
     {
-        memset(priv->var.TexCoordsMaps, 0, sizeof(priv->var.TexCoordsMaps));
-        for (unsigned j = 0; j < interop->tex_count; j++)
-        {
-            float scale_w = (float)interop->texs[j].w.num / interop->texs[j].w.den
-                          / priv->tex_widths[j];
-            float scale_h = (float)interop->texs[j].h.num / interop->texs[j].h.den
-                          / priv->tex_heights[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 = priv->var.TexCoordsMaps[j];
+        memset(priv->var.TexCoordsMap, 0, sizeof(priv->var.TexCoordsMap));
+
+        /* The transformation is the same for all planes, even with power-of-two
+         * textures. */
+        float scale_w = (float)interop->texs[0].w.num / interop->texs[0].w.den
+                      / priv->tex_widths[0];
+        float scale_h = (float)interop->texs[0].h.num / interop->texs[0].h.den
+                      / priv->tex_heights[0];
+
+        /* 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 = priv->var.TexCoordsMap;
 #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;
+        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
-        }
 
         priv->last_source.i_x_offset = source->i_x_offset;
         priv->last_source.i_y_offset = source->i_y_offset;



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/48d50cdf85df551772fd3778db2933cc7aa88e81...499b7ef7aab93826765cd0dc4bdd66bebe3b6bab

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/48d50cdf85df551772fd3778db2933cc7aa88e81...499b7ef7aab93826765cd0dc4bdd66bebe3b6bab
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list