[vlc-devel] [PATCH v2 11/29] opengl: extract subpictures rendering

Romain Vimont rom1v at videolabs.io
Thu Feb 6 14:17:40 CET 2020


Move subpictures rendering to separate functions.
---
 modules/video_output/opengl/vout_helper.c | 189 ++++++++++++----------
 1 file changed, 108 insertions(+), 81 deletions(-)

diff --git a/modules/video_output/opengl/vout_helper.c b/modules/video_output/opengl/vout_helper.c
index 688717e78b..71646b5dde 100644
--- a/modules/video_output/opengl/vout_helper.c
+++ b/modules/video_output/opengl/vout_helper.c
@@ -958,30 +958,19 @@ void vout_display_opengl_Viewport(vout_display_opengl_t *vgl, int x, int y,
     vgl->vt.Viewport(x, y, width, height);
 }
 
-int vout_display_opengl_Prepare(vout_display_opengl_t *vgl,
-                                picture_t *picture, subpicture_t *subpicture)
+static int
+vout_display_opengl_PrepareSubPicture(vout_display_opengl_t *vgl,
+                                      subpicture_t *subpicture)
 {
     GL_ASSERT_NOERROR();
 
-    opengl_tex_converter_t *tc = vgl->prgm->tc;
+    opengl_tex_converter_t *tc = vgl->sub_prgm->tc;
     const struct vlc_gl_interop *interop = tc->interop;
 
-    /* Update the texture */
-    int ret = interop->ops->update_textures(interop, vgl->texture, vgl->tex_width, vgl->tex_height,
-                                            picture, NULL);
-    if (ret != VLC_SUCCESS)
-        return ret;
-
-    int         last_count = vgl->region_count;
+    int last_count = vgl->region_count;
     gl_region_t *last = vgl->region;
 
-    vgl->region_count = 0;
-    vgl->region       = NULL;
-
-    tc = vgl->sub_prgm->tc;
-    interop = tc->interop;
     if (subpicture) {
-
         int count = 0;
         for (subpicture_region_t *r = subpicture->p_region; r; r = r->p_next)
             count++;
@@ -991,7 +980,7 @@ int vout_display_opengl_Prepare(vout_display_opengl_t *vgl,
 
         int i = 0;
         for (subpicture_region_t *r = subpicture->p_region;
-             r && ret == VLC_SUCCESS; r = r->p_next, i++) {
+             r; r = r->p_next, i++) {
             gl_region_t *glr = &vgl->region[i];
 
             glr->width  = r->fmt.i_visible_width;
@@ -1030,26 +1019,52 @@ int vout_display_opengl_Prepare(vout_display_opengl_t *vgl,
             if (!glr->texture)
             {
                 /* Could not recycle a previous texture, generate a new one. */
-                ret = GenTextures(interop, &glr->width, &glr->height, &glr->texture);
+                int ret = GenTextures(interop, &glr->width, &glr->height, &glr->texture);
                 if (ret != VLC_SUCCESS)
-                    continue;
+                    break;
             }
             /* Use the visible pitch of the region */
             r->p_picture->p[0].i_visible_pitch = r->fmt.i_visible_width
                                                * r->p_picture->p[0].i_pixel_pitch;
-            ret = interop->ops->update_textures(interop, &glr->texture,
-                                                &glr->width, &glr->height,
-                                                r->p_picture, &pixels_offset);
+            int ret = interop->ops->update_textures(interop, &glr->texture,
+                                                    &glr->width, &glr->height,
+                                                    r->p_picture, &pixels_offset);
+            if (ret != VLC_SUCCESS)
+                break;
         }
     }
+    else
+    {
+        vgl->region_count = 0;
+        vgl->region = NULL;
+    }
+
     for (int i = 0; i < last_count; i++) {
         if (last[i].texture)
             DelTextures(interop, &last[i].texture);
     }
     free(last);
 
-    VLC_UNUSED(subpicture);
+    GL_ASSERT_NOERROR();
+
+    return VLC_SUCCESS;
+}
+
+int vout_display_opengl_Prepare(vout_display_opengl_t *vgl,
+                                picture_t *picture, subpicture_t *subpicture)
+{
+    GL_ASSERT_NOERROR();
+
+    opengl_tex_converter_t *tc = vgl->prgm->tc;
+    const struct vlc_gl_interop *interop = tc->interop;
 
+    /* Update the texture */
+    int ret = interop->ops->update_textures(interop, vgl->texture, vgl->tex_width, vgl->tex_height,
+                                            picture, NULL);
+    if (ret != VLC_SUCCESS)
+        return ret;
+
+    ret = vout_display_opengl_PrepareSubPicture(vgl, subpicture);
     GL_ASSERT_NOERROR();
     return ret;
 }
@@ -1482,67 +1497,11 @@ static void TextureCropForStereo(vout_display_opengl_t *vgl,
     }
 }
 
-int vout_display_opengl_Display(vout_display_opengl_t *vgl,
-                                const video_format_t *source)
+static int
+vout_display_opengl_DrawSubPicture(vout_display_opengl_t *vgl)
 {
     GL_ASSERT_NOERROR();
 
-    /* Why drawing here and not in Render()? Because this way, the
-       OpenGL providers can call vout_display_opengl_Display to force redraw.
-       Currently, the OS X provider uses it to get a smooth window resizing */
-    vgl->vt.Clear(GL_COLOR_BUFFER_BIT);
-
-    vgl->vt.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 left[PICTURE_PLANE_MAX];
-        float top[PICTURE_PLANE_MAX];
-        float right[PICTURE_PLANE_MAX];
-        float bottom[PICTURE_PLANE_MAX];
-        const opengl_tex_converter_t *tc = vgl->prgm->tc;
-        const struct vlc_gl_interop *interop = tc->interop;
-        for (unsigned j = 0; j < interop->tex_count; j++)
-        {
-            float scale_w = (float)interop->texs[j].w.num / interop->texs[j].w.den
-                          / vgl->tex_width[j];
-            float scale_h = (float)interop->texs[j].h.num / interop->texs[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;
-        }
-
-        TextureCropForStereo(vgl, left, top, right, bottom);
-        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
     struct prgm *prgm = vgl->sub_prgm;
     GLuint program = prgm->id;
     opengl_tex_converter_t *tc = prgm->tc;
@@ -1618,6 +1577,74 @@ int vout_display_opengl_Display(vout_display_opengl_t *vgl,
     }
     vgl->vt.Disable(GL_BLEND);
 
+    GL_ASSERT_NOERROR();
+
+    return VLC_SUCCESS;
+}
+
+int vout_display_opengl_Display(vout_display_opengl_t *vgl,
+                                const video_format_t *source)
+{
+    GL_ASSERT_NOERROR();
+
+    /* Why drawing here and not in Render()? Because this way, the
+       OpenGL providers can call vout_display_opengl_Display to force redraw.
+       Currently, the OS X provider uses it to get a smooth window resizing */
+    vgl->vt.Clear(GL_COLOR_BUFFER_BIT);
+
+    vgl->vt.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 left[PICTURE_PLANE_MAX];
+        float top[PICTURE_PLANE_MAX];
+        float right[PICTURE_PLANE_MAX];
+        float bottom[PICTURE_PLANE_MAX];
+        const opengl_tex_converter_t *tc = vgl->prgm->tc;
+        const struct vlc_gl_interop *interop = tc->interop;
+        for (unsigned j = 0; j < interop->tex_count; j++)
+        {
+            float scale_w = (float)interop->texs[j].w.num / interop->texs[j].w.den
+                          / vgl->tex_width[j];
+            float scale_h = (float)interop->texs[j].h.num / interop->texs[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;
+        }
+
+        TextureCropForStereo(vgl, left, top, right, bottom);
+        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);
+
+    int ret = vout_display_opengl_DrawSubPicture(vgl);
+    if (ret != VLC_SUCCESS)
+        return ret;
+
     /* Display */
     vlc_gl_Swap(vgl->gl);
 
-- 
2.25.0



More information about the vlc-devel mailing list