[vlc-devel] [PATCH 04/27] opengl: use modules for OpenGL filters

Romain Vimont rom1v at videolabs.io
Thu Jun 25 14:22:51 CEST 2020


Load OpenGL filters from modules. Convert the existing renderer to a
module.
---
 modules/video_output/caopengllayer.m      |  3 +
 modules/video_output/ios.m                |  3 +
 modules/video_output/macosx.m             |  3 +
 modules/video_output/opengl/display.c     |  4 ++
 modules/video_output/opengl/filter.c      | 49 +++++++++++++--
 modules/video_output/opengl/filter.h      | 17 ++++++
 modules/video_output/opengl/filter_priv.h | 11 +++-
 modules/video_output/opengl/filters.c     | 38 ++++++++++--
 modules/video_output/opengl/filters.h     | 24 ++++++--
 modules/video_output/opengl/renderer.c    | 74 +++++++++++------------
 modules/video_output/opengl/renderer.h    | 32 +++-------
 modules/video_output/opengl/vout_helper.c | 33 +++++-----
 modules/video_output/win32/glwin32.c      |  3 +
 13 files changed, 198 insertions(+), 96 deletions(-)

diff --git a/modules/video_output/caopengllayer.m b/modules/video_output/caopengllayer.m
index 10fccdf90d..16e8de1c36 100644
--- a/modules/video_output/caopengllayer.m
+++ b/modules/video_output/caopengllayer.m
@@ -40,6 +40,7 @@
 #import <OpenGL/OpenGL.h>
 #import <dlfcn.h>               /* dlsym */
 
+#include "opengl/renderer.h"
 #include "opengl/vout_helper.h"
 
 #define OSX_SIERRA_AND_HIGHER (NSAppKitVersionNumber >= 1485)
@@ -56,6 +57,8 @@ vlc_module_begin()
     set_category(CAT_VIDEO)
     set_subcategory(SUBCAT_VIDEO_VOUT)
     set_callback_display(Open, 0)
+
+    add_opengl_submodule_renderer()
 vlc_module_end()
 
 static void PictureRender   (vout_display_t *vd, picture_t *pic, subpicture_t *subpicture,
diff --git a/modules/video_output/ios.m b/modules/video_output/ios.m
index 3bcf084d5c..637a140146 100644
--- a/modules/video_output/ios.m
+++ b/modules/video_output/ios.m
@@ -45,6 +45,7 @@
 #import <vlc_vout_display.h>
 #import <vlc_opengl.h>
 #import <vlc_dialog.h>
+#import "opengl/renderer.h"
 #import "opengl/vout_helper.h"
 
 /**
@@ -76,6 +77,8 @@ vlc_module_begin ()
 
     add_shortcut("vout_ios2", "vout_ios")
     add_glopts()
+
+    add_opengl_submodule_renderer()
 vlc_module_end ()
 
 @interface VLCOpenGLES2VideoView : UIView {
diff --git a/modules/video_output/macosx.m b/modules/video_output/macosx.m
index 5e0a10af6f..a714b59f6e 100644
--- a/modules/video_output/macosx.m
+++ b/modules/video_output/macosx.m
@@ -46,6 +46,7 @@
 #include <vlc_vout_display.h>
 #include <vlc_opengl.h>
 #include <vlc_dialog.h>
+#include "opengl/renderer.h"
 #include "opengl/vout_helper.h"
 
 /**
@@ -78,6 +79,8 @@ vlc_module_begin ()
     set_callback_display(Open, 300)
     add_shortcut ("macosx", "vout_macosx")
     add_glopts ()
+
+    add_opengl_submodule_renderer()
 vlc_module_end ()
 
 /**
diff --git a/modules/video_output/opengl/display.c b/modules/video_output/opengl/display.c
index f4e46f6f33..b7f6b44f15 100644
--- a/modules/video_output/opengl/display.c
+++ b/modules/video_output/opengl/display.c
@@ -33,6 +33,8 @@
 #include <vlc_opengl.h>
 #include "vout_helper.h"
 
+#include "renderer.h"
+
 /* Plugin callbacks */
 static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
                 video_format_t *fmtp, vlc_video_context *context);
@@ -66,6 +68,8 @@ vlc_module_begin ()
     add_module("gl", "opengl", NULL, GL_TEXT, PROVIDER_LONGTEXT)
 #endif
     add_glopts ()
+
+    add_opengl_submodule_renderer()
 vlc_module_end ()
 
 struct vout_display_sys_t
diff --git a/modules/video_output/opengl/filter.c b/modules/video_output/opengl/filter.c
index c889768479..110460e759 100644
--- a/modules/video_output/opengl/filter.c
+++ b/modules/video_output/opengl/filter.c
@@ -25,23 +25,64 @@
 
 #include "filter_priv.h"
 
+#include <assert.h>
+
+#include <vlc_common.h>
+#include <vlc_modules.h>
+
+#undef vlc_gl_filter_New
 struct vlc_gl_filter *
-vlc_gl_filter_New(void)
+vlc_gl_filter_New(vlc_object_t *parent, const struct vlc_gl_api *api)
 {
-    struct vlc_gl_filter_priv *priv = malloc(sizeof(*priv));
+    struct vlc_gl_filter_priv *priv = vlc_object_create(parent, sizeof(*priv));
     if (!priv)
         return NULL;
 
     struct vlc_gl_filter *filter = &priv->filter;
+    filter->api = api;
     filter->ops = NULL;
     filter->sys = NULL;
+    filter->module = NULL;
 
     return filter;
 }
 
+static int
+ActivateGLFilter(void *func, bool forced, va_list args)
+{
+    (void) forced;
+    vlc_gl_filter_open_fn *activate = func;
+    struct vlc_gl_filter *filter = va_arg(args, struct vlc_gl_filter *);
+    const config_chain_t *config = va_arg(args, config_chain_t *);
+    struct vlc_gl_sampler *sampler = va_arg(args, struct vlc_gl_sampler *);
+
+    return activate(filter, config, sampler);
+}
+
+#undef vlc_gl_filter_LoadModule
+int
+vlc_gl_filter_LoadModule(vlc_object_t *parent, const char *name,
+                         struct vlc_gl_filter *filter,
+                         const config_chain_t *config,
+                         struct vlc_gl_sampler *sampler)
+{
+    filter->module = vlc_module_load(parent, "opengl filter", name, true,
+                                     ActivateGLFilter, filter, config, sampler);
+    if (!filter->module)
+        return VLC_EGENERIC;
+
+    assert(filter->ops->draw);
+    return VLC_SUCCESS;
+}
+
 void
 vlc_gl_filter_Delete(struct vlc_gl_filter *filter)
 {
-    struct vlc_gl_filter_priv *priv = vlc_gl_filter_PRIV(filter);
-    free(priv);
+    if (filter->ops && filter->ops->close)
+        filter->ops->close(filter);
+
+    if (filter->module)
+        module_unneed(filter, filter->module);
+
+    vlc_object_delete(&filter->obj);
 }
diff --git a/modules/video_output/opengl/filter.h b/modules/video_output/opengl/filter.h
index f4b3f8bbf2..8d10002aaa 100644
--- a/modules/video_output/opengl/filter.h
+++ b/modules/video_output/opengl/filter.h
@@ -22,19 +22,36 @@
 #ifndef VLC_GL_FILTER_H
 #define VLC_GL_FILTER_H
 
+#include "sampler.h"
+
 struct vlc_gl_filter;
 
+typedef int
+vlc_gl_filter_open_fn(struct vlc_gl_filter *filter,
+                      const config_chain_t *config,
+                      struct vlc_gl_sampler *sampler);
+
 struct vlc_gl_filter_ops {
     /**
      * Draw the result of the filter to the current framebuffer
      */
     int (*draw)(struct vlc_gl_filter *filter);
+
+    /**
+     * Free filter resources
+     */
+    void (*close)(struct vlc_gl_filter *filter);
 };
 
 /**
  * OpenGL filter, in charge of a rendering pass.
  */
 struct vlc_gl_filter {
+    vlc_object_t obj;
+    module_t *module;
+
+    const struct vlc_gl_api *api;
+
     const struct vlc_gl_filter_ops *ops;
     void *sys;
 };
diff --git a/modules/video_output/opengl/filter_priv.h b/modules/video_output/opengl/filter_priv.h
index a1fe0b53b7..376249a636 100644
--- a/modules/video_output/opengl/filter_priv.h
+++ b/modules/video_output/opengl/filter_priv.h
@@ -37,7 +37,16 @@ struct vlc_gl_filter_priv {
     container_of(filter, struct vlc_gl_filter_priv, filter)
 
 struct vlc_gl_filter *
-vlc_gl_filter_New(void);
+vlc_gl_filter_New(vlc_object_t *parent, const struct vlc_gl_api *api);
+#define vlc_gl_filter_New(o, a) vlc_gl_filter_New(VLC_OBJECT(o), a)
+
+int
+vlc_gl_filter_LoadModule(vlc_object_t *parent, const char *name,
+                         struct vlc_gl_filter *filter,
+                         const config_chain_t *config,
+                         struct vlc_gl_sampler *sampler);
+#define vlc_gl_filter_LoadModule(o, a, b, c, d) \
+    vlc_gl_filter_LoadModule(VLC_OBJECT(o), a, b, c, d)
 
 void
 vlc_gl_filter_Delete(struct vlc_gl_filter *filter);
diff --git a/modules/video_output/opengl/filters.c b/modules/video_output/opengl/filters.c
index 99a325f3b8..b1732e21a9 100644
--- a/modules/video_output/opengl/filters.c
+++ b/modules/video_output/opengl/filters.c
@@ -29,18 +29,24 @@
 #include <vlc_list.h>
 
 #include "filter_priv.h"
+#include "renderer.h"
 
 struct vlc_gl_filters {
+    struct vlc_gl_t *gl;
+    const struct vlc_gl_api *api;
+
     struct vlc_list list; /**< list of vlc_gl_filter.node */
 };
 
 struct vlc_gl_filters *
-vlc_gl_filters_New(void)
+vlc_gl_filters_New(struct vlc_gl_t *gl, const struct vlc_gl_api *api)
 {
     struct vlc_gl_filters *filters = malloc(sizeof(*filters));
     if (!filters)
         return NULL;
 
+    filters->gl = gl;
+    filters->api = api;
     vlc_list_init(&filters->list);
     return filters;
 }
@@ -48,15 +54,39 @@ vlc_gl_filters_New(void)
 void
 vlc_gl_filters_Delete(struct vlc_gl_filters *filters)
 {
+    struct vlc_gl_filter_priv *priv;
+    vlc_list_foreach(priv, &filters->list, node)
+    {
+        struct vlc_gl_filter *filter = &priv->filter;
+        vlc_gl_filter_Delete(filter);
+    }
+
     free(filters);
 }
 
-void
-vlc_gl_filters_Append(struct vlc_gl_filters *filters,
-                      struct vlc_gl_filter *filter)
+struct vlc_gl_filter *
+vlc_gl_filters_Append(struct vlc_gl_filters *filters, const char *name,
+                      const config_chain_t *config,
+                      struct vlc_gl_sampler *sampler)
 {
+    struct vlc_gl_filter *filter = vlc_gl_filter_New(filters->gl, filters->api);
+    if (!filter)
+        return NULL;
+
+    int ret =
+        vlc_gl_filter_LoadModule(filters->gl, name, filter, config, sampler);
+    if (ret != VLC_SUCCESS)
+    {
+        /* Creation failed, do not call close() */
+        filter->ops = NULL;
+        vlc_gl_filter_Delete(filter);
+        return NULL;
+    }
+
     struct vlc_gl_filter_priv *priv = vlc_gl_filter_PRIV(filter);
     vlc_list_append(&priv->node, &filters->list);
+
+    return filter;
 }
 
 int
diff --git a/modules/video_output/opengl/filters.h b/modules/video_output/opengl/filters.h
index abe1b344a7..a6d6c2a27c 100644
--- a/modules/video_output/opengl/filters.h
+++ b/modules/video_output/opengl/filters.h
@@ -24,16 +24,22 @@
 
 #include <vlc_common.h>
 #include <vlc_list.h>
+#include <vlc_opengl.h>
 
 #include "filter.h"
+#include "gl_api.h"
+#include "sampler.h"
 
 struct vlc_gl_filters;
 
 /**
  * Create a new OpenGL filter chain
+ *
+ * \param gl the OpenGL context
+ * \param api the OpenGL api
  */
 struct vlc_gl_filters *
-vlc_gl_filters_New(void);
+vlc_gl_filters_New(struct vlc_gl_t *gl, const struct vlc_gl_api *api);
 
 /**
  * Delete the OpenGL filter chain
@@ -44,14 +50,20 @@ void
 vlc_gl_filters_Delete(struct vlc_gl_filters *filters);
 
 /**
- * Append a filter to the filter chain
+ * Create and append a filter loaded from a module to the filter chain
+ *
+ * The created filter is owned by the filter chain.
  *
  * \param filters the filter chain
- * \param filter the filter to append
+ * \param name the module name
+ * \param config the module configuration
+ * \param sampler the OpenGL sampler to use from the filter
+ * \return a weak reference to the filter (NULL on error)
  */
-void
-vlc_gl_filters_Append(struct vlc_gl_filters *filters,
-                      struct vlc_gl_filter *filter);
+struct vlc_gl_filter *
+vlc_gl_filters_Append(struct vlc_gl_filters *filters, const char *name,
+                      const config_chain_t *config,
+                      struct vlc_gl_sampler *sampler);
 
 /**
  * Draw by executing all the filters
diff --git a/modules/video_output/opengl/renderer.c b/modules/video_output/opengl/renderer.c
index 209d732764..aef1fb1234 100644
--- a/modules/video_output/opengl/renderer.c
+++ b/modules/video_output/opengl/renderer.c
@@ -37,7 +37,7 @@
 #include <vlc_es.h>
 #include <vlc_picture.h>
 
-#include "filter_priv.h"
+#include "filter.h"
 #include "gl_util.h"
 #include "internal.h"
 #include "vout_helper.h"
@@ -182,8 +182,10 @@ InitStereoMatrix(GLfloat matrix_out[static 3*3],
 #endif
 
 static char *
-BuildVertexShader(const struct vlc_gl_renderer *renderer)
+BuildVertexShader(struct vlc_gl_filter *filter)
 {
+    struct vlc_gl_renderer *renderer = filter->sys;
+
     /* Basic vertex shader */
     static const char *template =
         SHADER_VERSION
@@ -205,14 +207,15 @@ BuildVertexShader(const struct vlc_gl_renderer *renderer)
         return NULL;
 
     if (renderer->dump_shaders)
-        msg_Dbg(renderer->gl, "\n=== Vertex shader for fourcc: %4.4s ===\n%s\n",
+        msg_Dbg(filter, "\n=== Vertex shader for fourcc: %4.4s ===\n%s\n",
                 (const char *) &renderer->sampler->fmt->i_chroma, code);
     return code;
 }
 
 static char *
-BuildFragmentShader(struct vlc_gl_renderer *renderer)
+BuildFragmentShader(struct vlc_gl_filter *filter)
 {
+    struct vlc_gl_renderer *renderer = filter->sys;
     struct vlc_gl_sampler *sampler = renderer->sampler;
 
     static const char *template =
@@ -234,24 +237,25 @@ BuildFragmentShader(struct vlc_gl_renderer *renderer)
         return NULL;
 
     if (renderer->dump_shaders)
-        msg_Dbg(renderer->gl, "\n=== Fragment shader for fourcc: %4.4s, colorspace: %d ===\n%s\n",
-                              (const char *) &sampler->fmt->i_chroma,
-                              sampler->fmt->space, code);
+        msg_Dbg(filter, "\n=== Fragment shader for fourcc: %4.4s, colorspace: %d ===\n%s\n",
+                        (const char *) &sampler->fmt->i_chroma,
+                        sampler->fmt->space, code);
 
     return code;
 }
 
 static int
-opengl_link_program(struct vlc_gl_renderer *renderer)
+opengl_link_program(struct vlc_gl_filter *filter)
 {
+    struct vlc_gl_renderer *renderer = filter->sys;
     struct vlc_gl_sampler *sampler = renderer->sampler;
     const opengl_vtable_t *vt = renderer->vt;
 
-    char *vertex_shader = BuildVertexShader(renderer);
+    char *vertex_shader = BuildVertexShader(filter);
     if (!vertex_shader)
         return VLC_EGENERIC;
 
-    char *fragment_shader = BuildFragmentShader(renderer);
+    char *fragment_shader = BuildFragmentShader(filter);
     if (!fragment_shader)
     {
         free(vertex_shader);
@@ -263,7 +267,7 @@ opengl_link_program(struct vlc_gl_renderer *renderer)
            sampler->ops->load);
 
     GLuint program_id =
-        vlc_gl_BuildProgram(VLC_OBJECT(renderer->gl), vt,
+        vlc_gl_BuildProgram(VLC_OBJECT(filter), vt,
                             1, (const char **) &vertex_shader,
                             1, (const char **) &fragment_shader);
     free(vertex_shader);
@@ -276,7 +280,7 @@ opengl_link_program(struct vlc_gl_renderer *renderer)
     x = vt->Get##type##Location(program_id, str); \
     assert(x != -1); \
     if (x == -1) { \
-        msg_Err(renderer->gl, "Unable to Get"#type"Location(%s)", str); \
+        msg_Err(filter, "Unable to Get"#type"Location(%s)", str); \
         goto error; \
     } \
 } while (0)
@@ -305,13 +309,12 @@ error:
     return VLC_EGENERIC;
 }
 
-void
-vlc_gl_renderer_Delete(struct vlc_gl_renderer *renderer)
+static void
+Close(struct vlc_gl_filter *filter)
 {
+    struct vlc_gl_renderer *renderer = filter->sys;
     const opengl_vtable_t *vt = renderer->vt;
 
-    vlc_gl_filter_Delete(renderer->filter);
-
     vt->DeleteBuffers(1, &renderer->vertex_buffer_object);
     vt->DeleteBuffers(1, &renderer->index_buffer_object);
     vt->DeleteBuffers(1, &renderer->texture_buffer_object);
@@ -327,43 +330,38 @@ static int SetupCoords(struct vlc_gl_renderer *renderer);
 static int
 Draw(struct vlc_gl_filter *filter);
 
-struct vlc_gl_renderer *
-vlc_gl_renderer_New(vlc_gl_t *gl, const struct vlc_gl_api *api,
-                    struct vlc_gl_sampler *sampler)
+int
+vlc_gl_renderer_Open(struct vlc_gl_filter *filter,
+                     const config_chain_t *config,
+                     struct vlc_gl_sampler *sampler)
 {
-    const opengl_vtable_t *vt = &api->vt;
+    (void) config;
+
+    const opengl_vtable_t *vt = &filter->api->vt;
     const video_format_t *fmt = sampler->fmt;
 
     struct vlc_gl_renderer *renderer = calloc(1, sizeof(*renderer));
     if (!renderer)
-        return NULL;
-
-    struct vlc_gl_filter *filter = vlc_gl_filter_New();
-    if (!filter)
-    {
-        free(renderer);
-        return NULL;
-    }
+        return VLC_EGENERIC;
 
     static const struct vlc_gl_filter_ops filter_ops = {
         .draw = Draw,
+        .close = Close,
     };
     filter->ops = &filter_ops;
     filter->sys = renderer;
 
-    renderer->filter = filter;
     renderer->sampler = sampler;
 
-    renderer->gl = gl;
-    renderer->api = api;
+    renderer->api = filter->api;
     renderer->vt = vt;
-    renderer->dump_shaders = var_InheritInteger(gl, "verbose") >= 4;
+    renderer->dump_shaders = var_InheritInteger(filter, "verbose") >= 4;
 
-    int ret = opengl_link_program(renderer);
+    int ret = opengl_link_program(filter);
     if (ret != VLC_SUCCESS)
     {
-        vlc_gl_renderer_Delete(renderer);
-        return NULL;
+        free(renderer);
+        return ret;
     }
 
     InitStereoMatrix(renderer->var.StereoMatrix, fmt->multiview_mode);
@@ -384,11 +382,11 @@ vlc_gl_renderer_New(vlc_gl_t *gl, const struct vlc_gl_api *api,
     ret = SetupCoords(renderer);
     if (ret != VLC_SUCCESS)
     {
-        vlc_gl_renderer_Delete(renderer);
-        return NULL;
+        Close(filter);
+        return ret;
     }
 
-    return renderer;
+    return VLC_SUCCESS;
 }
 
 static void UpdateZ(struct vlc_gl_renderer *renderer)
diff --git a/modules/video_output/opengl/renderer.h b/modules/video_output/opengl/renderer.h
index 76f12b6070..38d5e122e9 100644
--- a/modules/video_output/opengl/renderer.h
+++ b/modules/video_output/opengl/renderer.h
@@ -36,21 +36,22 @@ struct pl_context;
 struct pl_shader;
 struct pl_shader_res;
 
+#define add_opengl_submodule_renderer() \
+    add_submodule() \
+    add_shortcut("renderer") \
+    set_shortname("renderer") \
+    set_capability("opengl filter", 0) \
+    set_callback(vlc_gl_renderer_Open)
+
 /**
  * OpenGL picture renderer
  */
 struct vlc_gl_renderer
 {
-    /* Pointer to object gl, set by the caller */
-    vlc_gl_t *gl;
-
     /* Set by the caller */
     const struct vlc_gl_api *api;
     const opengl_vtable_t *vt; /* for convenience, same as &api->vt */
 
-    /* vlc_gl_renderer "extends" vlc_gl_filter */
-    struct vlc_gl_filter *filter;
-
     /* True to dump shaders */
     bool dump_shaders;
 
@@ -93,24 +94,7 @@ struct vlc_gl_renderer
     float f_sar;
 };
 
-/**
- * Create a new renderer
- *
- * \param gl the GL context
- * \param api the OpenGL API
- * \param sampler the OpenGL sampler
- */
-struct vlc_gl_renderer *
-vlc_gl_renderer_New(vlc_gl_t *gl, const struct vlc_gl_api *api,
-                    struct vlc_gl_sampler *sampler);
-
-/**
- * Delete a renderer
- *
- * \param renderer the renderer
- */
-void
-vlc_gl_renderer_Delete(struct vlc_gl_renderer *renderer);
+vlc_gl_filter_open_fn vlc_gl_renderer_Open;
 
 int
 vlc_gl_renderer_SetViewpoint(struct vlc_gl_renderer *renderer,
diff --git a/modules/video_output/opengl/vout_helper.c b/modules/video_output/opengl/vout_helper.c
index bf990a67d9..8eed276d54 100644
--- a/modules/video_output/opengl/vout_helper.c
+++ b/modules/video_output/opengl/vout_helper.c
@@ -57,7 +57,7 @@ struct vout_display_opengl_t {
 
     struct vlc_gl_interop *interop;
     struct vlc_gl_sampler *sampler;
-    struct vlc_gl_renderer *renderer;
+    struct vlc_gl_renderer *renderer; /**< weak reference */
 
     struct vlc_gl_filters *filters;
 
@@ -151,28 +151,26 @@ vout_display_opengl_t *vout_display_opengl_New(video_format_t *fmt,
         goto delete_interop;
     }
 
-    vgl->renderer = vlc_gl_renderer_New(gl, api, vgl->sampler);
-    if (!vgl->renderer)
+    vgl->filters = vlc_gl_filters_New(gl, api);
+    if (!vgl->filters)
     {
-        msg_Warn(gl, "Could not create renderer for %4.4s",
-                 (const char *) &fmt->i_chroma);
+        msg_Err(gl, "Could not create filters");
         goto delete_sampler;
     }
 
-    GL_ASSERT_NOERROR(vt);
-
-    vgl->filters = vlc_gl_filters_New();
-    if (!vgl->filters)
+    /* The renderer is the only filter, for now */
+    struct vlc_gl_filter *renderer_filter =
+        vlc_gl_filters_Append(vgl->filters, "renderer", NULL, vgl->sampler);
+    if (!renderer_filter)
     {
-        msg_Err(gl, "Could not create filters");
-        goto delete_renderer;
+        msg_Warn(gl, "Could not create renderer for %4.4s",
+                 (const char *) &fmt->i_chroma);
+        goto delete_filters;
     }
 
-    /* Retrieve the "super-class" (renderer "extends" filter) */
-    struct vlc_gl_filter *renderer_filter = vgl->renderer->filter;
-
-    /* The renderer is the only filter, for now */
-    vlc_gl_filters_Append(vgl->filters, renderer_filter);
+    /* The renderer is a special filter: we need its concrete instance to
+     * forward SetViewpoint() */
+    vgl->renderer = renderer_filter->sys;
 
     vgl->sub_interop = vlc_gl_interop_NewForSubpictures(gl, api);
     if (!vgl->sub_interop)
@@ -212,8 +210,6 @@ delete_sub_interop:
     vlc_gl_interop_Delete(vgl->sub_interop);
 delete_filters:
     vlc_gl_filters_Delete(vgl->filters);
-delete_renderer:
-    vlc_gl_renderer_Delete(vgl->renderer);
 delete_sampler:
     vlc_gl_sampler_Delete(vgl->sampler);
 delete_interop:
@@ -238,7 +234,6 @@ void vout_display_opengl_Delete(vout_display_opengl_t *vgl)
     vlc_gl_interop_Delete(vgl->sub_interop);
 
     vlc_gl_filters_Delete(vgl->filters);
-    vlc_gl_renderer_Delete(vgl->renderer);
     vlc_gl_sampler_Delete(vgl->sampler);
     vlc_gl_interop_Delete(vgl->interop);
 
diff --git a/modules/video_output/win32/glwin32.c b/modules/video_output/win32/glwin32.c
index da893768c4..c09f543d84 100644
--- a/modules/video_output/win32/glwin32.c
+++ b/modules/video_output/win32/glwin32.c
@@ -34,6 +34,7 @@
 #include <versionhelpers.h>
 
 #define GLEW_STATIC
+#include "../opengl/renderer.h"
 #include "../opengl/vout_helper.h"
 
 #include "common.h"
@@ -53,6 +54,8 @@ vlc_module_begin()
     add_shortcut("glwin32", "opengl")
     set_callback_display(Open, 275)
     add_glopts()
+
+    add_opengl_submodule_renderer()
 vlc_module_end()
 
 /*****************************************************************************
-- 
2.27.0



More information about the vlc-devel mailing list