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

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


The renderer should not know the interop, so it may not be responsible
to upload the textures.

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



More information about the vlc-devel mailing list