[vlc-commits] [Git][videolan/vlc][master] 6 commits: opengl: Move assert

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Sat Nov 13 10:57:51 UTC 2021



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
05889e3a by Romain Vimont at 2021-11-13T10:44:11+00:00
opengl: Move assert

The assertion about tex_count == 0 actually checked that
InitFramebuffersOut() has not already been called.

Move it to the function itself for clarity.

- - - - -
dbb8d310 by Romain Vimont at 2021-11-13T10:44:11+00:00
opengl: move framebuffer init to filter.c

Initialization of framebuffers is related to a single vlc_gl_filter.

Move it to filter.c.

- - - - -
ca64494e by Romain Vimont at 2021-11-13T10:44:11+00:00
opengl: move plane size computation to filter.c

The plane sizes are specific to a filter.

- - - - -
c814eec9 by Romain Vimont at 2021-11-13T10:44:11+00:00
opengl: fix leaks on error

On error, framebuffers and textures were not destroyed on all code
paths.

- - - - -
50700437 by Romain Vimont at 2021-11-13T10:44:11+00:00
opengl: remove useless forward declaration

- - - - -
7d15e8a8 by Romain Vimont at 2021-11-13T10:44:11+00:00
opengl: move renderer Open() down

This avoids forward static functions declarations.

- - - - -


4 changed files:

- modules/video_output/opengl/filter.c
- modules/video_output/opengl/filter_priv.h
- modules/video_output/opengl/filters.c
- modules/video_output/opengl/renderer.c


Changes:

=====================================
modules/video_output/opengl/filter.c
=====================================
@@ -96,6 +96,24 @@ vlc_gl_filter_LoadModule(vlc_object_t *parent, const char *name,
     return VLC_SUCCESS;
 }
 
+static void
+DeleteFramebuffersOut(struct vlc_gl_filter_priv *priv)
+{
+    const opengl_vtable_t *vt = &priv->filter.api->vt;
+
+    vt->DeleteFramebuffers(priv->tex_count, priv->framebuffers_out);
+    vt->DeleteTextures(priv->tex_count, priv->textures_out);
+}
+
+static void
+DeleteFramebufferMSAA(struct vlc_gl_filter_priv *priv)
+{
+    const opengl_vtable_t *vt = &priv->filter.api->vt;
+
+    vt->DeleteFramebuffers(1, &priv->framebuffer_msaa);
+    vt->DeleteRenderbuffers(1, &priv->renderbuffer_msaa);
+}
+
 void
 vlc_gl_filter_Delete(struct vlc_gl_filter *filter)
 {
@@ -114,19 +132,185 @@ vlc_gl_filter_Delete(struct vlc_gl_filter *filter)
         vlc_gl_filter_Delete(subfilter);
     }
 
-    const opengl_vtable_t *vt = &filter->api->vt;
-
     if (priv->tex_count)
+        DeleteFramebuffersOut(priv);
+
+    if (filter->config.msaa_level)
+        DeleteFramebufferMSAA(priv);
+
+    vlc_object_delete(&filter->obj);
+}
+
+static int
+InitPlane(struct vlc_gl_filter_priv *priv, unsigned plane, GLsizei width,
+          GLsizei height)
+{
+    const opengl_vtable_t *vt = &priv->filter.api->vt;
+
+    GLuint framebuffer = priv->framebuffers_out[plane];
+    GLuint texture = priv->textures_out[plane];
+
+    vt->BindTexture(GL_TEXTURE_2D, texture);
+    vt->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
+                   GL_UNSIGNED_BYTE, NULL);
+    vt->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    vt->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+    /* iOS needs GL_CLAMP_TO_EDGE or power-of-two textures */
+    vt->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    vt->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+    /* Create a framebuffer and attach the texture */
+    vt->BindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+    vt->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                             GL_TEXTURE_2D, texture, 0);
+
+    GLenum status = vt->CheckFramebufferStatus(GL_FRAMEBUFFER);
+    if (status != GL_FRAMEBUFFER_COMPLETE)
+        return VLC_EGENERIC;
+
+    return VLC_SUCCESS;
+}
+
+static int
+InitFramebuffersOut(struct vlc_gl_filter_priv *priv)
+{
+    assert(priv->size_out.width > 0 && priv->size_out.height > 0);
+
+    /* Not initialized yet */
+    assert(priv->tex_count == 0);
+
+    const opengl_vtable_t *vt = &priv->filter.api->vt;
+
+    struct vlc_gl_filter *filter = &priv->filter;
+    if (filter->config.filter_planes)
     {
-        vt->DeleteFramebuffers(priv->tex_count, priv->framebuffers_out);
-        vt->DeleteTextures(priv->tex_count, priv->textures_out);
+        struct vlc_gl_format *glfmt = &priv->glfmt_in;
+
+        priv->tex_count = glfmt->tex_count;
+        vt->GenFramebuffers(priv->tex_count, priv->framebuffers_out);
+        vt->GenTextures(priv->tex_count, priv->textures_out);
+
+        for (unsigned i = 0; i < glfmt->tex_count; ++i)
+        {
+            memcpy(priv->tex_widths, priv->plane_widths,
+                   priv->tex_count * sizeof(*priv->tex_widths));
+            memcpy(priv->tex_heights, priv->plane_heights,
+                   priv->tex_count * sizeof(*priv->tex_heights));
+            /* Init one framebuffer and texture for each plane */
+            int ret =
+                InitPlane(priv, i, priv->tex_widths[i], priv->tex_heights[i]);
+            if (ret != VLC_SUCCESS)
+            {
+                DeleteFramebuffersOut(priv);
+                return ret;
+            }
+        }
     }
+    else
+    {
+        priv->tex_count = 1;
 
-    if (filter->config.msaa_level)
+        /* Create a texture having the expected size */
+
+        vt->GenFramebuffers(1, priv->framebuffers_out);
+        vt->GenTextures(1, priv->textures_out);
+
+        priv->tex_widths[0] = priv->size_out.width;
+        priv->tex_heights[0] = priv->size_out.height;
+
+        int ret = InitPlane(priv, 0, priv->tex_widths[0], priv->tex_heights[0]);
+        if (ret != VLC_SUCCESS)
+        {
+            DeleteFramebuffersOut(priv);
+            return ret;
+        }
+    }
+
+    return VLC_SUCCESS;
+}
+
+static int
+InitFramebufferMSAA(struct vlc_gl_filter_priv *priv, unsigned msaa_level)
+{
+    assert(msaa_level);
+    assert(priv->size_out.width > 0 && priv->size_out.height > 0);
+
+    const opengl_vtable_t *vt = &priv->filter.api->vt;
+
+    vt->GenRenderbuffers(1, &priv->renderbuffer_msaa);
+    vt->BindRenderbuffer(GL_RENDERBUFFER, priv->renderbuffer_msaa);
+    vt->RenderbufferStorageMultisample(GL_RENDERBUFFER, msaa_level,
+                                       GL_RGBA8,
+                                       priv->size_out.width,
+                                       priv->size_out.height);
+
+    vt->GenFramebuffers(1, &priv->framebuffer_msaa);
+    vt->BindFramebuffer(GL_FRAMEBUFFER, priv->framebuffer_msaa);
+    vt->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                                GL_RENDERBUFFER, priv->renderbuffer_msaa);
+
+    GLenum status = vt->CheckFramebufferStatus(GL_FRAMEBUFFER);
+    if (status != GL_FRAMEBUFFER_COMPLETE)
     {
-        vt->DeleteFramebuffers(1, &priv->framebuffer_msaa);
-        vt->DeleteRenderbuffers(1, &priv->renderbuffer_msaa);
+        DeleteFramebufferMSAA(priv);
+        return VLC_EGENERIC;
     }
 
-    vlc_object_delete(&filter->obj);
+    return VLC_SUCCESS;
+}
+
+int
+vlc_gl_filter_InitFramebuffers(struct vlc_gl_filter *filter, bool has_out)
+{
+    struct vlc_gl_filter_priv *priv = vlc_gl_filter_PRIV(filter);
+
+    unsigned msaa_level = priv->filter.config.msaa_level;
+    if (msaa_level)
+    {
+        int ret = InitFramebufferMSAA(priv, msaa_level);
+        if (ret != VLC_SUCCESS)
+            return ret;
+    }
+
+    /* Every non-blend filter needs its own framebuffer, except the last one */
+    if (has_out)
+    {
+        int ret = InitFramebuffersOut(priv);
+        if (ret != VLC_SUCCESS)
+        {
+            DeleteFramebufferMSAA(priv);
+            return ret;
+        }
+    }
+
+    return VLC_SUCCESS;
+}
+
+void
+vlc_gl_filter_InitPlaneSizes(struct vlc_gl_filter *filter)
+{
+    struct vlc_gl_filter_priv *priv = vlc_gl_filter_PRIV(filter);
+
+    if (filter->config.filter_planes)
+    {
+        struct vlc_gl_format *glfmt = &priv->glfmt_in;
+
+        priv->plane_count = glfmt->tex_count;
+        for (unsigned i = 0; i < glfmt->tex_count; ++i)
+        {
+            priv->plane_widths[i] = priv->size_out.width
+                                  * glfmt->tex_widths[i]
+                                  / glfmt->tex_widths[0];
+            priv->plane_heights[i] = priv->size_out.height
+                                   * glfmt->tex_heights[i]
+                                   / glfmt->tex_heights[0];
+        }
+    }
+    else
+    {
+        priv->plane_count = 1;
+        priv->plane_widths[0] = priv->size_out.width;
+        priv->plane_heights[0] = priv->size_out.height;
+    }
 }


=====================================
modules/video_output/opengl/filter_priv.h
=====================================
@@ -87,4 +87,11 @@ vlc_gl_filter_LoadModule(vlc_object_t *parent, const char *name,
 void
 vlc_gl_filter_Delete(struct vlc_gl_filter *filter);
 
+int
+vlc_gl_filter_InitFramebuffers(struct vlc_gl_filter *filter, bool is_last);
+
+/** Recompute plane count, widths and heights after size_out have changed */
+void
+vlc_gl_filter_InitPlaneSizes(struct vlc_gl_filter *filter);
+
 #endif


=====================================
modules/video_output/opengl/filters.c
=====================================
@@ -176,113 +176,6 @@ vlc_gl_filters_Delete(struct vlc_gl_filters *filters)
     free(filters);
 }
 
-static int
-InitPlane(struct vlc_gl_filter_priv *priv, unsigned plane, GLsizei width,
-          GLsizei height)
-{
-    const opengl_vtable_t *vt = &priv->filter.api->vt;
-
-    GLuint framebuffer = priv->framebuffers_out[plane];
-    GLuint texture = priv->textures_out[plane];
-
-    vt->BindTexture(GL_TEXTURE_2D, texture);
-    vt->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
-                   GL_UNSIGNED_BYTE, NULL);
-    vt->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    vt->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
-    /* iOS needs GL_CLAMP_TO_EDGE or power-of-two textures */
-    vt->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    vt->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
-    /* Create a framebuffer and attach the texture */
-    vt->BindFramebuffer(GL_FRAMEBUFFER, framebuffer);
-    vt->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                             GL_TEXTURE_2D, texture, 0);
-
-    GLenum status = vt->CheckFramebufferStatus(GL_FRAMEBUFFER);
-    if (status != GL_FRAMEBUFFER_COMPLETE)
-        return VLC_EGENERIC;
-
-    return VLC_SUCCESS;
-}
-
-static int
-InitFramebuffersOut(struct vlc_gl_filter_priv *priv)
-{
-    assert(priv->size_out.width > 0 && priv->size_out.height > 0);
-
-    const opengl_vtable_t *vt = &priv->filter.api->vt;
-
-    struct vlc_gl_filter *filter = &priv->filter;
-    if (filter->config.filter_planes)
-    {
-        struct vlc_gl_format *glfmt = &priv->glfmt_in;
-
-        priv->tex_count = glfmt->tex_count;
-        vt->GenFramebuffers(priv->tex_count, priv->framebuffers_out);
-        vt->GenTextures(priv->tex_count, priv->textures_out);
-
-        for (unsigned i = 0; i < glfmt->tex_count; ++i)
-        {
-            memcpy(priv->tex_widths, priv->plane_widths,
-                   priv->tex_count * sizeof(*priv->tex_widths));
-            memcpy(priv->tex_heights, priv->plane_heights,
-                   priv->tex_count * sizeof(*priv->tex_heights));
-            /* Init one framebuffer and texture for each plane */
-            int ret =
-                InitPlane(priv, i, priv->tex_widths[i], priv->tex_heights[i]);
-            if (ret != VLC_SUCCESS)
-                return ret;
-        }
-    }
-    else
-    {
-        priv->tex_count = 1;
-
-        /* Create a texture having the expected size */
-
-        vt->GenFramebuffers(1, priv->framebuffers_out);
-        vt->GenTextures(1, priv->textures_out);
-
-        priv->tex_widths[0] = priv->size_out.width;
-        priv->tex_heights[0] = priv->size_out.height;
-
-        int ret = InitPlane(priv, 0, priv->tex_widths[0], priv->tex_heights[0]);
-        if (ret != VLC_SUCCESS)
-            return ret;
-    }
-
-    return VLC_SUCCESS;
-}
-
-static int
-InitFramebufferMSAA(struct vlc_gl_filter_priv *priv, unsigned msaa_level)
-{
-    assert(msaa_level);
-    assert(priv->size_out.width > 0 && priv->size_out.height > 0);
-
-    const opengl_vtable_t *vt = &priv->filter.api->vt;
-
-    vt->GenRenderbuffers(1, &priv->renderbuffer_msaa);
-    vt->BindRenderbuffer(GL_RENDERBUFFER, priv->renderbuffer_msaa);
-    vt->RenderbufferStorageMultisample(GL_RENDERBUFFER, msaa_level,
-                                       GL_RGBA8,
-                                       priv->size_out.width,
-                                       priv->size_out.height);
-
-    vt->GenFramebuffers(1, &priv->framebuffer_msaa);
-    vt->BindFramebuffer(GL_FRAMEBUFFER, priv->framebuffer_msaa);
-    vt->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                                GL_RENDERBUFFER, priv->renderbuffer_msaa);
-
-    GLenum status = vt->CheckFramebufferStatus(GL_FRAMEBUFFER);
-    if (status != GL_FRAMEBUFFER_COMPLETE)
-        return VLC_EGENERIC;
-
-    return VLC_SUCCESS;
-}
-
 struct vlc_gl_filter *
 vlc_gl_filters_Append(struct vlc_gl_filters *filters, const char *name,
                       const config_chain_t *config)
@@ -381,25 +274,7 @@ vlc_gl_filters_Append(struct vlc_gl_filters *filters, const char *name,
     }
     else
     {
-        if (filter->config.filter_planes)
-        {
-            priv->plane_count = glfmt->tex_count;
-            for (unsigned i = 0; i < glfmt->tex_count; ++i)
-            {
-                priv->plane_widths[i] = priv->size_out.width
-                                      * glfmt->tex_widths[i]
-                                      / glfmt->tex_widths[0];
-                priv->plane_heights[i] = priv->size_out.height
-                                       * glfmt->tex_heights[i]
-                                       / glfmt->tex_heights[0];
-            }
-        }
-        else
-        {
-            priv->plane_count = 1;
-            priv->plane_widths[0] = priv->size_out.width;
-            priv->plane_heights[0] = priv->size_out.height;
-        }
+        vlc_gl_filter_InitPlaneSizes(filter);
 
         /* Append to the main filter list */
         vlc_list_append(&priv->node, &filters->list);
@@ -463,26 +338,15 @@ vlc_gl_filters_InitFramebuffers(struct vlc_gl_filters *filters)
 
     vlc_list_foreach(priv, &filters->list, node)
     {
-        unsigned msaa_level = priv->filter.config.msaa_level;
-        if (msaa_level)
-        {
-            int ret = InitFramebufferMSAA(priv, msaa_level);
-            if (ret != VLC_SUCCESS)
-                return ret;
-        }
+        struct vlc_gl_filter *filter = &priv->filter;
 
         bool is_last = vlc_list_is_last(&priv->node, &filters->list);
-        if (!is_last)
-        {
-            /* It was the last non-blend filter before we append this one */
-            assert(priv->tex_count == 0);
-
-            /* Every non-blend filter needs its own framebuffer, except the last
-             * one */
-            int ret = InitFramebuffersOut(priv);
-            if (ret != VLC_SUCCESS)
-                return ret;
-        }
+        /* Every non-blend filter needs its own framebuffer, except the last
+         * one */
+        bool has_out = !is_last;
+        int ret = vlc_gl_filter_InitFramebuffers(filter, has_out);
+        if (ret != VLC_SUCCESS)
+            return ret;
     }
 
     /* Restore bindings */


=====================================
modules/video_output/opengl/renderer.c
=====================================
@@ -303,71 +303,6 @@ Close(struct vlc_gl_filter *filter)
     free(renderer);
 }
 
-static int SetupCoords(struct vlc_gl_renderer *renderer,
-                       const struct vlc_gl_picture *pic);
-
-static int
-Draw(struct vlc_gl_filter *filter, const struct vlc_gl_picture *pic,
-     const struct vlc_gl_input_meta *meta);
-
-int
-vlc_gl_renderer_Open(struct vlc_gl_filter *filter,
-                     const config_chain_t *config,
-                     const struct vlc_gl_format *glfmt,
-                     struct vlc_gl_tex_size *size_out)
-{
-    (void) config;
-    (void) size_out;
-
-    const opengl_vtable_t *vt = &filter->api->vt;
-
-    struct vlc_gl_sampler *sampler =
-        vlc_gl_sampler_New(filter->gl, filter->api, glfmt, false);
-    if (!sampler)
-        return VLC_EGENERIC;
-
-    struct vlc_gl_renderer *renderer = calloc(1, sizeof(*renderer));
-    if (!renderer)
-    {
-        vlc_gl_sampler_Delete(sampler);
-        return VLC_EGENERIC;
-    }
-
-    static const struct vlc_gl_filter_ops filter_ops = {
-        .draw = Draw,
-        .close = Close,
-    };
-    filter->ops = &filter_ops;
-    filter->sys = renderer;
-
-    renderer->sampler = sampler;
-
-    renderer->api = filter->api;
-    renderer->vt = vt;
-    renderer->dump_shaders = var_InheritInteger(filter, "verbose") >= 4;
-
-    int ret = opengl_link_program(filter);
-    if (ret != VLC_SUCCESS)
-    {
-        free(renderer);
-        return ret;
-    }
-
-    const video_format_t *fmt = &sampler->glfmt.fmt;
-    InitStereoMatrix(renderer->var.StereoMatrix, fmt->multiview_mode);
-
-    getViewpointMatrixes(renderer, fmt->projection_mode);
-
-    vt->GenBuffers(1, &renderer->vertex_buffer_object);
-    vt->GenBuffers(1, &renderer->index_buffer_object);
-    vt->GenBuffers(1, &renderer->texture_buffer_object);
-
-    /* The coords will be initialized on first draw */
-    renderer->valid_coords = false;
-
-    return VLC_SUCCESS;
-}
-
 static void UpdateZ(struct vlc_gl_renderer *renderer)
 {
     /* Do trigonometry to calculate the minimal z value
@@ -798,3 +733,61 @@ Draw(struct vlc_gl_filter *filter, const struct vlc_gl_picture *pic,
 
     return VLC_SUCCESS;
 }
+
+int
+vlc_gl_renderer_Open(struct vlc_gl_filter *filter,
+                     const config_chain_t *config,
+                     const struct vlc_gl_format *glfmt,
+                     struct vlc_gl_tex_size *size_out)
+{
+    (void) config;
+    (void) size_out;
+
+    const opengl_vtable_t *vt = &filter->api->vt;
+
+    struct vlc_gl_sampler *sampler =
+        vlc_gl_sampler_New(filter->gl, filter->api, glfmt, false);
+    if (!sampler)
+        return VLC_EGENERIC;
+
+    struct vlc_gl_renderer *renderer = calloc(1, sizeof(*renderer));
+    if (!renderer)
+    {
+        vlc_gl_sampler_Delete(sampler);
+        return VLC_EGENERIC;
+    }
+
+    static const struct vlc_gl_filter_ops filter_ops = {
+        .draw = Draw,
+        .close = Close,
+    };
+    filter->ops = &filter_ops;
+    filter->sys = renderer;
+
+    renderer->sampler = sampler;
+
+    renderer->api = filter->api;
+    renderer->vt = vt;
+    renderer->dump_shaders = var_InheritInteger(filter, "verbose") >= 4;
+
+    int ret = opengl_link_program(filter);
+    if (ret != VLC_SUCCESS)
+    {
+        free(renderer);
+        return ret;
+    }
+
+    const video_format_t *fmt = &sampler->glfmt.fmt;
+    InitStereoMatrix(renderer->var.StereoMatrix, fmt->multiview_mode);
+
+    getViewpointMatrixes(renderer, fmt->projection_mode);
+
+    vt->GenBuffers(1, &renderer->vertex_buffer_object);
+    vt->GenBuffers(1, &renderer->index_buffer_object);
+    vt->GenBuffers(1, &renderer->texture_buffer_object);
+
+    /* The coords will be initialized on first draw */
+    renderer->valid_coords = false;
+
+    return VLC_SUCCESS;
+}



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/c32d801a882773c0f6b22999afcd3c3a297f76f8...7d15e8a8396143de94bcb6e39d8e2c748e1e94aa

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/c32d801a882773c0f6b22999afcd3c3a297f76f8...7d15e8a8396143de94bcb6e39d8e2c748e1e94aa
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list