[vlc-commits] opengl: calculate and upload coordinates when needed

Thomas Guillem git at videolan.org
Thu Jan 26 12:47:47 CET 2017


vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Thu Jan 26 11:47:46 2017 +0100| [6642391625494180098cac6c8c472343b4fecab2] | committer: Thomas Guillem

opengl: calculate and upload coordinates when needed

SetupCoords() is called only when the source changes.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=6642391625494180098cac6c8c472343b4fecab2
---

 modules/video_output/opengl/vout_helper.c | 132 +++++++++++++++++++-----------
 1 file changed, 86 insertions(+), 46 deletions(-)

diff --git a/modules/video_output/opengl/vout_helper.c b/modules/video_output/opengl/vout_helper.c
index 075a1f1..8ac8cc1 100644
--- a/modules/video_output/opengl/vout_helper.c
+++ b/modules/video_output/opengl/vout_helper.c
@@ -127,6 +127,7 @@ struct vout_display_opengl_t {
     struct prgm *prgm; /* Main program */
     struct prgm *sub_prgm; /* Subpicture program */
 
+    unsigned nb_indices;
     GLuint vertex_buffer_object;
     GLuint index_buffer_object;
     GLuint texture_buffer_object[PICTURE_PLANE_MAX];
@@ -134,6 +135,13 @@ struct vout_display_opengl_t {
     GLuint *subpicture_buffer_object;
     int    subpicture_buffer_object_count;
 
+    struct {
+        unsigned int i_x_offset;
+        unsigned int i_y_offset;
+        unsigned int i_visible_width;
+        unsigned int i_visible_height;
+    } last_source;
+
     /* Non-power-of-2 texture size support */
     bool supports_npot;
 
@@ -1231,16 +1239,10 @@ static int BuildRectangle(unsigned nbPlanes,
     return VLC_SUCCESS;
 }
 
-static void DrawWithShaders(vout_display_opengl_t *vgl,
-                            const float *left, const float *top,
-                            const float *right, const float *bottom,
-                            struct prgm *prgm)
+static int SetupCoords(vout_display_opengl_t *vgl,
+                       const float *left, const float *top,
+                       const float *right, const float *bottom)
 {
-    GLuint program = prgm->id;
-    opengl_tex_converter_t *tc = &prgm->tc;
-    vgl->api.UseProgram(program);
-    tc->pf_prepare_shader(tc, 1.0f);
-
     GLfloat *vertexCoord, *textureCoord;
     GLushort *indices;
     unsigned nbVertices, nbIndices;
@@ -1274,7 +1276,36 @@ static void DrawWithShaders(vout_display_opengl_t *vgl,
     }
 
     if (i_ret != VLC_SUCCESS)
-        return;
+        return i_ret;
+
+    for (unsigned j = 0; j < vgl->chroma->plane_count; j++)
+    {
+        vgl->api.BindBuffer(GL_ARRAY_BUFFER, vgl->texture_buffer_object[j]);
+        vgl->api.BufferData(GL_ARRAY_BUFFER, nbVertices * 2 * sizeof(GLfloat),
+                        textureCoord + j * nbVertices * 2, GL_STATIC_DRAW);
+    }
+
+    vgl->api.BindBuffer(GL_ARRAY_BUFFER, vgl->vertex_buffer_object);
+    vgl->api.BufferData(GL_ARRAY_BUFFER, nbVertices * 3 * sizeof(GLfloat),
+                        vertexCoord, GL_STATIC_DRAW);
+
+    vgl->api.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, vgl->index_buffer_object);
+    vgl->api.BufferData(GL_ELEMENT_ARRAY_BUFFER, nbIndices * sizeof(GLushort),
+                        indices, GL_STATIC_DRAW);
+
+    free(textureCoord);
+    free(vertexCoord);
+    free(indices);
+
+    vgl->nb_indices = nbIndices;
+
+    return VLC_SUCCESS;
+}
+
+static void DrawWithShaders(vout_display_opengl_t *vgl, struct prgm *prgm)
+{
+    opengl_tex_converter_t *tc = &prgm->tc;
+    tc->pf_prepare_shader(tc, 1.0f);
 
     for (unsigned j = 0; j < vgl->chroma->plane_count; j++) {
         assert(vgl->texture[j] != 0);
@@ -1283,21 +1314,15 @@ static void DrawWithShaders(vout_display_opengl_t *vgl,
         glBindTexture(tc->tex_target, vgl->texture[j]);
 
         vgl->api.BindBuffer(GL_ARRAY_BUFFER, vgl->texture_buffer_object[j]);
-        vgl->api.BufferData(GL_ARRAY_BUFFER, nbVertices * 2 * sizeof(GLfloat),
-                        textureCoord + j * nbVertices * 2, GL_STATIC_DRAW);
 
         assert(prgm->aloc.MultiTexCoord[j] != -1);
         vgl->api.EnableVertexAttribArray(prgm->aloc.MultiTexCoord[j]);
         vgl->api.VertexAttribPointer(prgm->aloc.MultiTexCoord[j], 2, GL_FLOAT,
                                      0, 0, 0);
     }
-    free(textureCoord);
+
     vgl->api.BindBuffer(GL_ARRAY_BUFFER, vgl->vertex_buffer_object);
-    vgl->api.BufferData(GL_ARRAY_BUFFER, nbVertices * 3 * sizeof(GLfloat), vertexCoord, GL_STATIC_DRAW);
-    free(vertexCoord);
     vgl->api.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, vgl->index_buffer_object);
-    vgl->api.BufferData(GL_ELEMENT_ARRAY_BUFFER, nbIndices * sizeof(GLushort), indices, GL_STATIC_DRAW);
-    free(indices);
     vgl->api.EnableVertexAttribArray(prgm->aloc.VertexPosition);
     vgl->api.VertexAttribPointer(prgm->aloc.VertexPosition, 3, GL_FLOAT, 0, 0, 0);
 
@@ -1314,7 +1339,7 @@ static void DrawWithShaders(vout_display_opengl_t *vgl,
     vgl->api.UniformMatrix4fv(prgm->uloc.ZoomMatrix, 1, GL_FALSE,
                               prgm->var.ZoomMatrix);
 
-    glDrawElements(GL_TRIANGLES, nbIndices, GL_UNSIGNED_SHORT, 0);
+    glDrawElements(GL_TRIANGLES, vgl->nb_indices, GL_UNSIGNED_SHORT, 0);
 }
 
 int vout_display_opengl_Display(vout_display_opengl_t *vgl,
@@ -1325,36 +1350,51 @@ int vout_display_opengl_Display(vout_display_opengl_t *vgl,
        Currently, the OS X provider uses it to get a smooth window resizing */
     glClear(GL_COLOR_BUFFER_BIT);
 
-    /* Draw the picture */
-    float left[PICTURE_PLANE_MAX];
-    float top[PICTURE_PLANE_MAX];
-    float right[PICTURE_PLANE_MAX];
-    float bottom[PICTURE_PLANE_MAX];
-    for (unsigned j = 0; j < vgl->chroma->plane_count; j++)
+    vgl->api.UseProgram(vgl->prgm->id);
+
+    if (source->i_x_offset != vgl->last_source.i_x_offset
+     || source->i_y_offset != vgl->last_source.i_y_offset
+     || source->i_visible_width != vgl->last_source.i_visible_width
+     || source->i_visible_height != vgl->last_source.i_visible_height)
     {
-        float scale_w = (float)vgl->chroma->p[j].w.num / vgl->chroma->p[j].w.den
-                      / vgl->tex_width[j];
-        float scale_h = (float)vgl->chroma->p[j].h.num / vgl->chroma->p[j].h.den
-                      / vgl->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.
-        */
-        left[j]   = (source->i_x_offset +                       0 ) * scale_w;
-        top[j]    = (source->i_y_offset +                       0 ) * scale_h;
-        right[j]  = (source->i_x_offset + source->i_visible_width ) * scale_w;
-        bottom[j] = (source->i_y_offset + source->i_visible_height) * scale_h;
-    }
+        float left[PICTURE_PLANE_MAX];
+        float top[PICTURE_PLANE_MAX];
+        float right[PICTURE_PLANE_MAX];
+        float bottom[PICTURE_PLANE_MAX];
+        for (unsigned j = 0; j < vgl->chroma->plane_count; j++)
+        {
+            float scale_w = (float)vgl->chroma->p[j].w.num / vgl->chroma->p[j].w.den
+                          / vgl->tex_width[j];
+            float scale_h = (float)vgl->chroma->p[j].h.num / vgl->chroma->p[j].h.den
+                          / vgl->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.
+            */
+            left[j]   = (source->i_x_offset +                       0 ) * scale_w;
+            top[j]    = (source->i_y_offset +                       0 ) * scale_h;
+            right[j]  = (source->i_x_offset + source->i_visible_width ) * scale_w;
+            bottom[j] = (source->i_y_offset + source->i_visible_height) * scale_h;
+        }
 
-    DrawWithShaders(vgl, left, top, right, bottom, vgl->prgm);
+        int ret = SetupCoords(vgl, left, top, right, bottom);
+        if (ret != VLC_SUCCESS)
+            return ret;
+
+        vgl->last_source.i_x_offset = source->i_x_offset;
+        vgl->last_source.i_y_offset = source->i_y_offset;
+        vgl->last_source.i_visible_width = source->i_visible_width;
+        vgl->last_source.i_visible_height = source->i_visible_height;
+    }
+    DrawWithShaders(vgl, vgl->prgm);
 
     /* Draw the subpictures */
     // Change the program for overlays



More information about the vlc-commits mailing list