[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