[vlc-devel] [PATCH 05/16] opengl: move vtable to vlc_gl_api
Rémi Denis-Courmont
remi at remlab.net
Tue Mar 17 17:49:52 CET 2020
Le tiistaina 17. maaliskuuta 2020, 18.26.38 EET Romain Vimont a écrit :
> Use a separate component for storing OpenGL API-specific utils (for now,
> only the vtable).
> ---
> modules/video_output/Makefile.am | 2 +
> modules/video_output/opengl/gl_api.c | 135 ++++++++++++++++++++
> modules/video_output/opengl/gl_api.h | 41 ++++++
> modules/video_output/opengl/vout_helper.c | 149 +++++-----------------
> 4 files changed, 209 insertions(+), 118 deletions(-)
> create mode 100644 modules/video_output/opengl/gl_api.c
> create mode 100644 modules/video_output/opengl/gl_api.h
>
> diff --git a/modules/video_output/Makefile.am
> b/modules/video_output/Makefile.am index cee3d447a9..a61d15f20f 100644
> --- a/modules/video_output/Makefile.am
> +++ b/modules/video_output/Makefile.am
> @@ -4,6 +4,8 @@ vout_LTLIBRARIES =
> EXTRA_DIST += video_output/README
>
> OPENGL_COMMONSOURCES = video_output/opengl/vout_helper.c \
> + video_output/opengl/gl_api.c \
> + video_output/opengl/gl_api.h \
> video_output/opengl/gl_common.h \
> video_output/opengl/gl_util.c \
> video_output/opengl/gl_util.h \
> diff --git a/modules/video_output/opengl/gl_api.c
> b/modules/video_output/opengl/gl_api.c new file mode 100644
> index 0000000000..69859a815e
> --- /dev/null
> +++ b/modules/video_output/opengl/gl_api.c
> @@ -0,0 +1,135 @@
> +/**************************************************************************
> *** + * gl_api.h
> +
> ***************************************************************************
> ** + * Copyright (C) 2020 VLC authors and VideoLAN
> + * Copyright (C) 2020 Videolabs
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License as published by
> + * the Free Software Foundation; either version 2.1 of the License, or + *
> (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program; if not, write to the Free Software Foundation,
> + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. +
> ***************************************************************************
> **/ +
> +#ifdef HAVE_CONFIG_H
> +# include "config.h"
> +#endif
> +
> +#include "gl_api.h"
> +
> +#include <vlc_common.h>
> +#include <vlc_opengl.h>
> +
> +#include "gl_common.h"
> +
> +int
> +vlc_gl_api_Init(struct vlc_gl_api *api, vlc_gl_t *gl)
> +{
> +#if defined(USE_OPENGL_ES2) || defined(HAVE_GL_CORE_SYMBOLS)
> +#define GET_PROC_ADDR_CORE(name) api->vt.name = gl##name
> +#else
> +#define GET_PROC_ADDR_CORE(name) GET_PROC_ADDR_EXT(name, true)
> +#endif
> +#define GET_PROC_ADDR_EXT(name, critical) do { \
> + api->vt.name = vlc_gl_GetProcAddress(gl, "gl"#name); \
> + if (api->vt.name == NULL && critical) { \
Seems more logical to check critical first.
> + msg_Err(gl, "gl"#name" symbol not found, bailing out"); \
Use %s.
> + return VLC_EGENERIC; \
> + } \
> +} while(0)
> +#if defined(USE_OPENGL_ES2)
> +#define GET_PROC_ADDR(name) GET_PROC_ADDR_CORE(name)
> +#define GET_PROC_ADDR_CORE_GL(name) GET_PROC_ADDR_EXT(name, false) /*
> optional for GLES */ +#else
> +#define GET_PROC_ADDR(name) GET_PROC_ADDR_EXT(name, true)
> +#define GET_PROC_ADDR_CORE_GL(name) GET_PROC_ADDR_CORE(name)
> +#endif
> +#define GET_PROC_ADDR_OPTIONAL(name) GET_PROC_ADDR_EXT(name, false) /* GL 3
> or more */ +
> + GET_PROC_ADDR_CORE(BindTexture);
> + GET_PROC_ADDR_CORE(BlendFunc);
> + GET_PROC_ADDR_CORE(Clear);
> + GET_PROC_ADDR_CORE(ClearColor);
> + GET_PROC_ADDR_CORE(DeleteTextures);
> + GET_PROC_ADDR_CORE(DepthMask);
> + GET_PROC_ADDR_CORE(Disable);
> + GET_PROC_ADDR_CORE(DrawArrays);
> + GET_PROC_ADDR_CORE(DrawElements);
> + GET_PROC_ADDR_CORE(Enable);
> + GET_PROC_ADDR_CORE(Finish);
> + GET_PROC_ADDR_CORE(Flush);
> + GET_PROC_ADDR_CORE(GenTextures);
> + GET_PROC_ADDR_CORE(GetError);
> + GET_PROC_ADDR_CORE(GetIntegerv);
> + GET_PROC_ADDR_CORE(GetString);
> + GET_PROC_ADDR_CORE(PixelStorei);
> + GET_PROC_ADDR_CORE(TexImage2D);
> + GET_PROC_ADDR_CORE(TexParameterf);
> + GET_PROC_ADDR_CORE(TexParameteri);
> + GET_PROC_ADDR_CORE(TexSubImage2D);
> + GET_PROC_ADDR_CORE(Viewport);
> +
> + GET_PROC_ADDR_CORE_GL(GetTexLevelParameteriv);
> + GET_PROC_ADDR_CORE_GL(TexEnvf);
> +
> + GET_PROC_ADDR(CreateShader);
> + GET_PROC_ADDR(ShaderSource);
> + GET_PROC_ADDR(CompileShader);
> + GET_PROC_ADDR(AttachShader);
> + GET_PROC_ADDR(DeleteShader);
> +
> + GET_PROC_ADDR(GetProgramiv);
> + GET_PROC_ADDR(GetShaderiv);
> + GET_PROC_ADDR(GetProgramInfoLog);
> + GET_PROC_ADDR(GetShaderInfoLog);
> +
> + GET_PROC_ADDR(GetUniformLocation);
> + GET_PROC_ADDR(GetAttribLocation);
> + GET_PROC_ADDR(VertexAttribPointer);
> + GET_PROC_ADDR(EnableVertexAttribArray);
> + GET_PROC_ADDR(UniformMatrix4fv);
> + GET_PROC_ADDR(UniformMatrix3fv);
> + GET_PROC_ADDR(UniformMatrix2fv);
> + GET_PROC_ADDR(Uniform4fv);
> + GET_PROC_ADDR(Uniform4f);
> + GET_PROC_ADDR(Uniform3f);
> + GET_PROC_ADDR(Uniform2f);
> + GET_PROC_ADDR(Uniform1f);
> + GET_PROC_ADDR(Uniform1i);
> +
> + GET_PROC_ADDR(CreateProgram);
> + GET_PROC_ADDR(LinkProgram);
> + GET_PROC_ADDR(UseProgram);
> + GET_PROC_ADDR(DeleteProgram);
> +
> + GET_PROC_ADDR(ActiveTexture);
> +
> + GET_PROC_ADDR(GenBuffers);
> + GET_PROC_ADDR(BindBuffer);
> + GET_PROC_ADDR(BufferData);
> + GET_PROC_ADDR(DeleteBuffers);
> +
> + GET_PROC_ADDR_OPTIONAL(GetFramebufferAttachmentParameteriv);
> +
> + GET_PROC_ADDR_OPTIONAL(BufferSubData);
> + GET_PROC_ADDR_OPTIONAL(BufferStorage);
> + GET_PROC_ADDR_OPTIONAL(MapBufferRange);
> + GET_PROC_ADDR_OPTIONAL(FlushMappedBufferRange);
> + GET_PROC_ADDR_OPTIONAL(UnmapBuffer);
> + GET_PROC_ADDR_OPTIONAL(FenceSync);
> + GET_PROC_ADDR_OPTIONAL(DeleteSync);
> + GET_PROC_ADDR_OPTIONAL(ClientWaitSync);
> +#undef GET_PROC_ADDR
> +
> + GL_ASSERT_NOERROR(&api->vt);
> +
> + return VLC_SUCCESS;
> +}
> diff --git a/modules/video_output/opengl/gl_api.h
> b/modules/video_output/opengl/gl_api.h new file mode 100644
> index 0000000000..86add17ce3
> --- /dev/null
> +++ b/modules/video_output/opengl/gl_api.h
> @@ -0,0 +1,41 @@
> +/**************************************************************************
> *** + * gl_api.h
> +
> ***************************************************************************
> ** + * Copyright (C) 2020 VLC authors and VideoLAN
> + * Copyright (C) 2020 Videolabs
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License as published by
> + * the Free Software Foundation; either version 2.1 of the License, or + *
> (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program; if not, write to the Free Software Foundation,
> + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. +
> ***************************************************************************
> **/ +
> +#ifndef VLC_GL_API_H
> +#define VLC_GL_API_H
> +
> +#ifdef HAVE_CONFIG_H
> +# include "config.h"
> +#endif
> +
> +#include <vlc_common.h>
> +#include <vlc_opengl.h>
> +
> +#include "gl_common.h"
> +
> +struct vlc_gl_api {
> + opengl_vtable_t vt;
> +};
> +
> +int
> +vlc_gl_api_Init(struct vlc_gl_api *api, vlc_gl_t *gl);
> +
> +#endif
> diff --git a/modules/video_output/opengl/vout_helper.c
> b/modules/video_output/opengl/vout_helper.c index 61f1321f69..b29de3534d
> 100644
> --- a/modules/video_output/opengl/vout_helper.c
> +++ b/modules/video_output/opengl/vout_helper.c
> @@ -39,6 +39,7 @@
> #include <vlc_vout.h>
> #include <vlc_viewpoint.h>
>
> +#include "gl_api.h"
> #include "gl_util.h"
> #include "vout_helper.h"
> #include "internal.h"
> @@ -48,7 +49,7 @@
> struct vout_display_opengl_t {
>
> vlc_gl_t *gl;
> - opengl_vtable_t vt;
> + struct vlc_gl_api api;
>
> struct vlc_gl_renderer *renderer;
> struct vlc_gl_sub_renderer *sub_renderer;
> @@ -100,106 +101,16 @@ vout_display_opengl_t
> *vout_display_opengl_New(video_format_t *fmt,
>
> vgl->gl = gl;
>
> -#if defined(USE_OPENGL_ES2) || defined(HAVE_GL_CORE_SYMBOLS)
> -#define GET_PROC_ADDR_CORE(name) vgl->vt.name = gl##name
> -#else
> -#define GET_PROC_ADDR_CORE(name) GET_PROC_ADDR_EXT(name, true)
> -#endif
> -#define GET_PROC_ADDR_EXT(name, critical) do { \
> - vgl->vt.name = vlc_gl_GetProcAddress(gl, "gl"#name); \
> - if (vgl->vt.name == NULL && critical) { \
> - msg_Err(gl, "gl"#name" symbol not found, bailing out"); \
> - free(vgl); \
> - return NULL; \
> - } \
> -} while(0)
> -#if defined(USE_OPENGL_ES2)
> -#define GET_PROC_ADDR(name) GET_PROC_ADDR_CORE(name)
> -#define GET_PROC_ADDR_CORE_GL(name) GET_PROC_ADDR_EXT(name, false) /*
> optional for GLES */ -#else
> -#define GET_PROC_ADDR(name) GET_PROC_ADDR_EXT(name, true)
> -#define GET_PROC_ADDR_CORE_GL(name) GET_PROC_ADDR_CORE(name)
> -#endif
> -#define GET_PROC_ADDR_OPTIONAL(name) GET_PROC_ADDR_EXT(name, false) /* GL 3
> or more */ -
> - GET_PROC_ADDR_CORE(BindTexture);
> - GET_PROC_ADDR_CORE(BlendFunc);
> - GET_PROC_ADDR_CORE(Clear);
> - GET_PROC_ADDR_CORE(ClearColor);
> - GET_PROC_ADDR_CORE(DeleteTextures);
> - GET_PROC_ADDR_CORE(DepthMask);
> - GET_PROC_ADDR_CORE(Disable);
> - GET_PROC_ADDR_CORE(DrawArrays);
> - GET_PROC_ADDR_CORE(DrawElements);
> - GET_PROC_ADDR_CORE(Enable);
> - GET_PROC_ADDR_CORE(Finish);
> - GET_PROC_ADDR_CORE(Flush);
> - GET_PROC_ADDR_CORE(GenTextures);
> - GET_PROC_ADDR_CORE(GetError);
> - GET_PROC_ADDR_CORE(GetIntegerv);
> - GET_PROC_ADDR_CORE(GetString);
> - GET_PROC_ADDR_CORE(PixelStorei);
> - GET_PROC_ADDR_CORE(TexImage2D);
> - GET_PROC_ADDR_CORE(TexParameterf);
> - GET_PROC_ADDR_CORE(TexParameteri);
> - GET_PROC_ADDR_CORE(TexSubImage2D);
> - GET_PROC_ADDR_CORE(Viewport);
> -
> - GET_PROC_ADDR_CORE_GL(GetTexLevelParameteriv);
> - GET_PROC_ADDR_CORE_GL(TexEnvf);
> -
> - GET_PROC_ADDR(CreateShader);
> - GET_PROC_ADDR(ShaderSource);
> - GET_PROC_ADDR(CompileShader);
> - GET_PROC_ADDR(AttachShader);
> - GET_PROC_ADDR(DeleteShader);
> -
> - GET_PROC_ADDR(GetProgramiv);
> - GET_PROC_ADDR(GetShaderiv);
> - GET_PROC_ADDR(GetProgramInfoLog);
> - GET_PROC_ADDR(GetShaderInfoLog);
> -
> - GET_PROC_ADDR(GetUniformLocation);
> - GET_PROC_ADDR(GetAttribLocation);
> - GET_PROC_ADDR(VertexAttribPointer);
> - GET_PROC_ADDR(EnableVertexAttribArray);
> - GET_PROC_ADDR(UniformMatrix4fv);
> - GET_PROC_ADDR(UniformMatrix3fv);
> - GET_PROC_ADDR(UniformMatrix2fv);
> - GET_PROC_ADDR(Uniform4fv);
> - GET_PROC_ADDR(Uniform4f);
> - GET_PROC_ADDR(Uniform3f);
> - GET_PROC_ADDR(Uniform2f);
> - GET_PROC_ADDR(Uniform1f);
> - GET_PROC_ADDR(Uniform1i);
> -
> - GET_PROC_ADDR(CreateProgram);
> - GET_PROC_ADDR(LinkProgram);
> - GET_PROC_ADDR(UseProgram);
> - GET_PROC_ADDR(DeleteProgram);
> -
> - GET_PROC_ADDR(ActiveTexture);
> -
> - GET_PROC_ADDR(GenBuffers);
> - GET_PROC_ADDR(BindBuffer);
> - GET_PROC_ADDR(BufferData);
> - GET_PROC_ADDR(DeleteBuffers);
> -
> - GET_PROC_ADDR_OPTIONAL(GetFramebufferAttachmentParameteriv);
> -
> - GET_PROC_ADDR_OPTIONAL(BufferSubData);
> - GET_PROC_ADDR_OPTIONAL(BufferStorage);
> - GET_PROC_ADDR_OPTIONAL(MapBufferRange);
> - GET_PROC_ADDR_OPTIONAL(FlushMappedBufferRange);
> - GET_PROC_ADDR_OPTIONAL(UnmapBuffer);
> - GET_PROC_ADDR_OPTIONAL(FenceSync);
> - GET_PROC_ADDR_OPTIONAL(DeleteSync);
> - GET_PROC_ADDR_OPTIONAL(ClientWaitSync);
> -#undef GET_PROC_ADDR
> -
> - GL_ASSERT_NOERROR(&vgl->vt);
> -
> - const char *extensions = (const char
> *)vgl->vt.GetString(GL_EXTENSIONS); + int ret =
> vlc_gl_api_Init(&vgl->api, gl);
> + if (ret != VLC_SUCCESS)
> + {
> + free(vgl);
> + return NULL;
> + }
> +
> + const opengl_vtable_t *vt = &vgl->api.vt;
> +
> + const char *extensions = (const char *) vt->GetString(GL_EXTENSIONS);
> assert(extensions);
> if (!extensions)
> {
> @@ -208,7 +119,7 @@ vout_display_opengl_t
> *vout_display_opengl_New(video_format_t *fmt, return NULL;
> }
> #if !defined(USE_OPENGL_ES2)
> - const unsigned char *ogl_version = vgl->vt.GetString(GL_VERSION);
> + const unsigned char *ogl_version = vt->GetString(GL_VERSION);
> bool supports_shaders = strverscmp((const char *)ogl_version, "2.0") >=
> 0; if (!supports_shaders)
> {
> @@ -221,7 +132,7 @@ vout_display_opengl_t
> *vout_display_opengl_New(video_format_t *fmt, /* Resize the format if it is
> greater than the maximum texture size * supported by the hardware */
> GLint max_tex_size;
> - vgl->vt.GetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size);
> + vt->GetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size);
>
> if ((GLint)fmt->i_width > max_tex_size ||
> (GLint)fmt->i_height > max_tex_size)
> @@ -241,7 +152,7 @@ vout_display_opengl_t
> *vout_display_opengl_New(video_format_t *fmt, bool b_dump_shaders =
> var_InheritInteger(gl, "verbose") >= 4;
>
> struct vlc_gl_renderer *renderer = vgl->renderer =
> - vlc_gl_renderer_New(gl, &vgl->vt, context, fmt, supports_npot,
> + vlc_gl_renderer_New(gl, vt, context, fmt, supports_npot,
> b_dump_shaders);
> if (!vgl->renderer)
> {
> @@ -251,10 +162,9 @@ vout_display_opengl_t
> *vout_display_opengl_New(video_format_t *fmt, return NULL;
> }
>
> - GL_ASSERT_NOERROR(&vgl->vt);
> + GL_ASSERT_NOERROR(vt);
>
> - vgl->sub_renderer =
> - vlc_gl_sub_renderer_New(gl, &vgl->vt, supports_npot);
> + vgl->sub_renderer = vlc_gl_sub_renderer_New(gl, vt, supports_npot);
> if (!vgl->sub_renderer)
> {
> msg_Err(gl, "Could not create sub renderer");
> @@ -263,7 +173,7 @@ vout_display_opengl_t
> *vout_display_opengl_New(video_format_t *fmt, return NULL;
> }
>
> - GL_ASSERT_NOERROR(&vgl->vt);
> + GL_ASSERT_NOERROR(vt);
>
> if (renderer->fmt.projection_mode != PROJECTION_MODE_RECTANGULAR
> && vout_display_opengl_SetViewpoint(vgl, viewpoint) != VLC_SUCCESS)
> @@ -277,22 +187,24 @@ vout_display_opengl_t
> *vout_display_opengl_New(video_format_t *fmt, *subpicture_chromas =
> gl_subpicture_chromas;
> }
>
> - GL_ASSERT_NOERROR(&vgl->vt);
> + GL_ASSERT_NOERROR(vt);
> return vgl;
> }
>
> void vout_display_opengl_Delete(vout_display_opengl_t *vgl)
> {
> - GL_ASSERT_NOERROR(&vgl->vt);
> + const opengl_vtable_t *vt = &vgl->api.vt;
> +
> + GL_ASSERT_NOERROR(vt);
>
> /* */
> - vgl->vt.Finish();
> - vgl->vt.Flush();
> + vt->Finish();
> + vt->Flush();
>
> vlc_gl_sub_renderer_Delete(vgl->sub_renderer);
> vlc_gl_renderer_Delete(vgl->renderer);
>
> - GL_ASSERT_NOERROR(&vgl->vt);
> + GL_ASSERT_NOERROR(vt);
>
> free(vgl);
> }
> @@ -312,26 +224,27 @@ void
> vout_display_opengl_SetWindowAspectRatio(vout_display_opengl_t *vgl, void
> vout_display_opengl_Viewport(vout_display_opengl_t *vgl, int x, int y,
> unsigned width, unsigned height) {
> - vgl->vt.Viewport(x, y, width, height);
> + const opengl_vtable_t *vt = &vgl->api.vt;
> + vt->Viewport(x, y, width, height);
> }
>
> int vout_display_opengl_Prepare(vout_display_opengl_t *vgl,
> picture_t *picture, subpicture_t
> *subpicture) {
> - GL_ASSERT_NOERROR(&vgl->vt);
> + GL_ASSERT_NOERROR(&vgl->api.vt);
>
> int ret = vlc_gl_renderer_Prepare(vgl->renderer, picture);
> if (ret != VLC_SUCCESS)
> return ret;
>
> ret = vlc_gl_sub_renderer_Prepare(vgl->sub_renderer, subpicture);
> - GL_ASSERT_NOERROR(&vgl->vt);
> + GL_ASSERT_NOERROR(&vgl->api.vt);
> return ret;
> }
> int vout_display_opengl_Display(vout_display_opengl_t *vgl,
> const video_format_t *source)
> {
> - GL_ASSERT_NOERROR(&vgl->vt);
> + GL_ASSERT_NOERROR(&vgl->api.vt);
>
> /* Why drawing here and not in Render()? Because this way, the
> OpenGL providers can call vout_display_opengl_Display to force
> redraw. @@ -348,7 +261,7 @@ int
> vout_display_opengl_Display(vout_display_opengl_t *vgl, /* Display */
> vlc_gl_Swap(vgl->gl);
>
> - GL_ASSERT_NOERROR(&vgl->vt);
> + GL_ASSERT_NOERROR(&vgl->api.vt);
>
> return VLC_SUCCESS;
> }
--
レミ・デニ-クールモン
http://www.remlab.net/
More information about the vlc-devel
mailing list