[vlc-devel] [PATCH 3/4] gl: don't release buffers after the context is destroyed
Thomas Guillem
thomas at gllm.fr
Sun Sep 24 11:34:58 CEST 2017
---
modules/video_output/opengl/converter_sw.c | 60 +++++++++++-------------------
1 file changed, 21 insertions(+), 39 deletions(-)
diff --git a/modules/video_output/opengl/converter_sw.c b/modules/video_output/opengl/converter_sw.c
index e46d19ce07..cf342e4862 100644
--- a/modules/video_output/opengl/converter_sw.c
+++ b/modules/video_output/opengl/converter_sw.c
@@ -71,7 +71,7 @@
#define PBO_DISPLAY_COUNT 2 /* Double buffering */
struct picture_sys_t
{
- const opengl_tex_converter_t *tc;
+ vlc_gl_t *gl;
GLuint buffers[PICTURE_PLANE_MAX];
size_t bytes[PICTURE_PLANE_MAX];
GLsync fence;
@@ -93,17 +93,30 @@ struct priv
} persistent;
};
+static void
+pbo_picture_destroy(picture_t *pic)
+{
+ picture_sys_t *picsys = pic->p_sys;
+
+ /* Don't call glDeleteBuffers() here, since a picture can be destroyed from
+ * any threads after the vout is destroyed. Instead, release the reference
+ * to the GL context. All buffers will be destroyed when it reaches 0. */
+ vlc_gl_Destroy(picsys->gl);
+ free(picsys);
+ free(pic);
+}
+
static picture_t *
-pbo_picture_create(const opengl_tex_converter_t *tc,
- void (*pf_destroy)(picture_t *))
+pbo_picture_create(const opengl_tex_converter_t *tc)
{
picture_sys_t *picsys = calloc(1, sizeof(*picsys));
if (unlikely(picsys == NULL))
return NULL;
- picsys->tc = tc;
+ picsys->gl = tc->gl;
+
picture_resource_t rsc = {
.p_sys = picsys,
- .pf_destroy = pf_destroy,
+ .pf_destroy = pbo_picture_destroy,
};
picture_t *pic = picture_NewFromResource(&tc->fmt, &rsc);
@@ -112,6 +125,7 @@ pbo_picture_create(const opengl_tex_converter_t *tc,
free(picsys);
return NULL;
}
+ vlc_gl_Hold(picsys->gl);
if (picture_Setup(pic, &tc->fmt))
{
picture_Release(pic);
@@ -157,26 +171,13 @@ pbo_data_alloc(const opengl_tex_converter_t *tc, picture_t *pic)
return VLC_SUCCESS;
}
-static void
-picture_pbo_destroy_cb(picture_t *pic)
-{
- picture_sys_t *picsys = pic->p_sys;
- const opengl_tex_converter_t *tc = picsys->tc;
-
- if (picsys->buffers[0] != 0)
- tc->vt->DeleteBuffers(pic->i_planes, picsys->buffers);
- free(picsys);
- free(pic);
-}
-
static int
pbo_pics_alloc(const opengl_tex_converter_t *tc)
{
struct priv *priv = tc->priv;
for (size_t i = 0; i < PBO_DISPLAY_COUNT; ++i)
{
- picture_t *pic = priv->pbo.display_pics[i] =
- pbo_picture_create(tc, picture_pbo_destroy_cb);
+ picture_t *pic = priv->pbo.display_pics[i] = pbo_picture_create(tc);
if (pic == NULL)
goto error;
@@ -364,25 +365,6 @@ tc_persistent_update(const opengl_tex_converter_t *tc, GLuint *textures,
return VLC_SUCCESS;
}
-static void
-picture_persistent_destroy_cb(picture_t *pic)
-{
- picture_sys_t *picsys = pic->p_sys;
- const opengl_tex_converter_t *tc = picsys->tc;
-
- if (picsys->buffers[0] != 0)
- {
- for (int i = 0; i < pic->i_planes; ++i)
- {
- tc->vt->BindBuffer(GL_PIXEL_UNPACK_BUFFER, picsys->buffers[i]);
- tc->vt->UnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
- }
- tc->vt->DeleteBuffers(pic->i_planes, picsys->buffers);
- }
- free(picsys);
- free(pic);
-}
-
static picture_pool_t *
tc_persistent_get_pool(const opengl_tex_converter_t *tc, unsigned requested_count)
{
@@ -396,7 +378,7 @@ tc_persistent_get_pool(const opengl_tex_converter_t *tc, unsigned requested_coun
for (count = 0; count < requested_count; count++)
{
picture_t *pic = pictures[count] =
- pbo_picture_create(tc, picture_persistent_destroy_cb);
+ pbo_picture_create(tc);
if (pic == NULL)
break;
#ifndef NDEBUG
--
2.11.0
More information about the vlc-devel
mailing list