[vlc-devel] [PATCH 05/16] opengl: move vtable to vlc_gl_api

Romain Vimont rom1v at videolabs.io
Tue Mar 17 17:53:25 CET 2020


On 3/17/20 5:49 PM, Rémi Denis-Courmont wrote:
> 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.

This is just a code move.

> 
>> +        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;
>>   }
> 
> 


More information about the vlc-devel mailing list