vlc | branch: master | Romain Vimont <[email protected]> | Mon Apr 12 17:58:55 2021 +0200| [199f3812b0c2c19f317df57bf60d3f4cd7b7373a] | committer: Alexandre Janniaux
opengl: determine shader version dynamically In the future, we would like OpenGL and OpenGL ES2 versions of a filter to be available without compiling it twice. Co-authored-by: Alexandre Janniaux <[email protected]> Signed-off-by: Alexandre Janniaux <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=199f3812b0c2c19f317df57bf60d3f4cd7b7373a --- modules/video_output/opengl/filter_draw.c | 58 +++++++------- modules/video_output/opengl/filter_mock.c | 128 +++++++++++++++++++----------- modules/video_output/opengl/renderer.c | 112 ++++++++++---------------- 3 files changed, 157 insertions(+), 141 deletions(-) diff --git a/modules/video_output/opengl/filter_draw.c b/modules/video_output/opengl/filter_draw.c index 60aeddc539..b921b3f0ee 100644 --- a/modules/video_output/opengl/filter_draw.c +++ b/modules/video_output/opengl/filter_draw.c @@ -97,16 +97,7 @@ vlc_gl_filter_draw_Open(struct vlc_gl_filter *filter, struct vlc_gl_sampler *sampler = vlc_gl_filter_GetSampler(filter); -#ifdef USE_OPENGL_ES2 -# define SHADER_VERSION "#version 100\n" -# define FRAGMENT_SHADER_PRECISION "precision highp float;\n" -#else -# define SHADER_VERSION "#version 120\n" -# define FRAGMENT_SHADER_PRECISION -#endif - - static const char *const VERTEX_SHADER = - SHADER_VERSION + static const char *const VERTEX_SHADER_BODY = "attribute vec2 vertex_pos;\n" "varying vec2 tex_coords;\n" "void main() {\n" @@ -115,8 +106,7 @@ vlc_gl_filter_draw_Open(struct vlc_gl_filter *filter, " (vertex_pos.y + 1.0) / 2.0);\n" "}\n"; - static const char *const VERTEX_SHADER_VFLIP = - SHADER_VERSION + static const char *const VERTEX_SHADER_BODY_VFLIP = "attribute vec2 vertex_pos;\n" "varying vec2 tex_coords;\n" "void main() {\n" @@ -125,11 +115,7 @@ vlc_gl_filter_draw_Open(struct vlc_gl_filter *filter, " (-vertex_pos.y + 1.0) / 2.0);\n" "}\n"; - static const char *const FRAGMENT_SHADER_TEMPLATE = - SHADER_VERSION - "%s\n" /* extensions */ - FRAGMENT_SHADER_PRECISION - "%s\n" /* vlc_texture definition */ + static const char *const FRAGMENT_SHADER_BODY = "varying vec2 tex_coords;\n" "void main() {\n" " gl_FragColor = vlc_texture(tex_coords);\n" @@ -138,24 +124,40 @@ vlc_gl_filter_draw_Open(struct vlc_gl_filter *filter, const char *extensions = sampler->shader.extensions ? sampler->shader.extensions : ""; - char *fragment_shader; - int ret = asprintf(&fragment_shader, FRAGMENT_SHADER_TEMPLATE, extensions, - sampler->shader.body); - if (ret < 0) - goto error; - const opengl_vtable_t *vt = &filter->api->vt; + const char *shader_version; + const char *shader_precision; + if (filter->api->is_gles) + { + shader_version = "#version 100\n"; + shader_precision = "precision highp float;\n"; + } + else + { + shader_version = "#version 120\n"; + shader_precision = ""; + } + config_ChainParse(filter, DRAW_CFG_PREFIX, filter_options, config); bool vflip = var_InheritBool(filter, DRAW_CFG_PREFIX "vflip"); - const char *vertex_shader = vflip ? VERTEX_SHADER_VFLIP : VERTEX_SHADER; + const char *vertex_shader[] = { + shader_version, + vflip ? VERTEX_SHADER_BODY_VFLIP : VERTEX_SHADER_BODY, + }; + const char *fragment_shader[] = { + shader_version, + extensions, + shader_precision, + sampler->shader.body, + FRAGMENT_SHADER_BODY, + }; + GLuint program_id = vlc_gl_BuildProgram(VLC_OBJECT(filter), vt, - 1, &vertex_shader, - 1, (const char **) &fragment_shader); - - free(fragment_shader); + ARRAY_SIZE(vertex_shader), vertex_shader, + ARRAY_SIZE(fragment_shader), fragment_shader); if (!program_id) goto error; diff --git a/modules/video_output/opengl/filter_mock.c b/modules/video_output/opengl/filter_mock.c index 41851fe35d..e6252f36b6 100644 --- a/modules/video_output/opengl/filter_mock.c +++ b/modules/video_output/opengl/filter_mock.c @@ -73,14 +73,6 @@ #include "gl_common.h" #include "gl_util.h" -#ifdef USE_OPENGL_ES2 -# define SHADER_VERSION "#version 100\n" -# define FRAGMENT_SHADER_PRECISION "precision mediump float;\n" -#else -# define SHADER_VERSION "#version 120\n" -# define FRAGMENT_SHADER_PRECISION -#endif - #define MOCK_CFG_PREFIX "mock-" static const char *const filter_options[] = { @@ -241,8 +233,7 @@ InitBlend(struct vlc_gl_filter *filter) struct sys *sys = filter->sys; const opengl_vtable_t *vt = &filter->api->vt; - static const char *const VERTEX_SHADER = - SHADER_VERSION + static const char *const VERTEX_SHADER_BODY = "attribute vec2 vertex_pos;\n" "attribute vec3 vertex_color;\n" "uniform mat4 rotation_matrix;\n" @@ -252,18 +243,39 @@ InitBlend(struct vlc_gl_filter *filter) " color = vertex_color;\n" "}\n"; - static const char *const FRAGMENT_SHADER = - SHADER_VERSION - FRAGMENT_SHADER_PRECISION + static const char *const FRAGMENT_SHADER_BODY = "varying vec3 color;\n" "void main() {\n" " gl_FragColor = vec4(color, 0.5);\n" "}\n"; + const char *shader_version; + const char *shader_precision; + if (filter->api->is_gles) + { + shader_version = "#version 100\n"; + shader_precision = "precision highp float;\n"; + } + else + { + shader_version = "#version 120\n"; + shader_precision = ""; + } + + const char *vertex_shader[] = { + shader_version, + VERTEX_SHADER_BODY, + }; + const char *fragment_shader[] = { + shader_version, + shader_precision, + FRAGMENT_SHADER_BODY, + }; + GLuint program_id = vlc_gl_BuildProgram(VLC_OBJECT(filter), vt, - 1, (const char **) &VERTEX_SHADER, - 1, (const char **) &FRAGMENT_SHADER); + ARRAY_SIZE(vertex_shader), vertex_shader, + ARRAY_SIZE(fragment_shader), fragment_shader); if (!program_id) return VLC_EGENERIC; @@ -316,8 +328,7 @@ InitMask(struct vlc_gl_filter *filter) struct vlc_gl_sampler *sampler = vlc_gl_filter_GetSampler(filter); - static const char *const VERTEX_SHADER = - SHADER_VERSION + static const char *const VERTEX_SHADER_BODY = "attribute vec2 vertex_pos;\n" "uniform mat4 rotation_matrix;\n" "varying vec2 tex_coords;\n" @@ -328,11 +339,7 @@ InitMask(struct vlc_gl_filter *filter) " gl_Position = pos\n;" "}\n"; - static const char *const FRAGMENT_SHADER_TEMPLATE = - SHADER_VERSION - "%s\n" /* extensions */ - FRAGMENT_SHADER_PRECISION - "%s\n" /* vlc_texture definition */ + static const char *const FRAGMENT_SHADER_BODY = "varying vec2 tex_coords;\n" "void main() {\n" " gl_FragColor = vlc_texture(tex_coords);\n" @@ -341,17 +348,35 @@ InitMask(struct vlc_gl_filter *filter) const char *extensions = sampler->shader.extensions ? sampler->shader.extensions : ""; - char *fragment_shader; - int ret = asprintf(&fragment_shader, FRAGMENT_SHADER_TEMPLATE, extensions, - sampler->shader.body); - if (ret < 0) - return VLC_EGENERIC; + const char *shader_version; + const char *shader_precision; + if (filter->api->is_gles) + { + shader_version = "#version 100\n"; + shader_precision = "precision highp float;\n"; + } + else + { + shader_version = "#version 120\n"; + shader_precision = ""; + } + + const char *vertex_shader[] = { + shader_version, + VERTEX_SHADER_BODY, + }; + const char *fragment_shader[] = { + shader_version, + extensions, + shader_precision, + sampler->shader.body, + FRAGMENT_SHADER_BODY, + }; GLuint program_id = vlc_gl_BuildProgram(VLC_OBJECT(filter), vt, - 1, (const char **) &VERTEX_SHADER, - 1, (const char **) &fragment_shader); - free(fragment_shader); + ARRAY_SIZE(vertex_shader), vertex_shader, + ARRAY_SIZE(fragment_shader), fragment_shader); if (!program_id) return VLC_EGENERIC; @@ -401,8 +426,7 @@ InitPlane(struct vlc_gl_filter *filter) struct vlc_gl_sampler *sampler = vlc_gl_filter_GetSampler(filter); - static const char *const VERTEX_SHADER = - SHADER_VERSION + static const char *const VERTEX_SHADER_BODY = "attribute vec2 vertex_pos;\n" "varying vec2 tex_coords;\n" "void main() {\n" @@ -411,11 +435,7 @@ InitPlane(struct vlc_gl_filter *filter) " (vertex_pos.y + 1.0) / 2.0);\n" "}\n"; - static const char *const FRAGMENT_SHADER_TEMPLATE = - SHADER_VERSION - "%s\n" /* extensions */ - FRAGMENT_SHADER_PRECISION - "%s\n" /* vlc_texture definition */ + static const char *const FRAGMENT_SHADER_BODY = "varying vec2 tex_coords;\n" "uniform int plane;\n" "void main() {\n" @@ -426,17 +446,35 @@ InitPlane(struct vlc_gl_filter *filter) const char *extensions = sampler->shader.extensions ? sampler->shader.extensions : ""; - char *fragment_shader; - int ret = asprintf(&fragment_shader, FRAGMENT_SHADER_TEMPLATE, extensions, - sampler->shader.body); - if (ret < 0) - return VLC_EGENERIC; + const char *shader_version; + const char *shader_precision; + if (filter->api->is_gles) + { + shader_version = "#version 100\n"; + shader_precision = "precision highp float;\n"; + } + else + { + shader_version = "#version 120\n"; + shader_precision = ""; + } + + const char *vertex_shader[] = { + shader_version, + VERTEX_SHADER_BODY, + }; + const char *fragment_shader[] = { + shader_version, + extensions, + shader_precision, + sampler->shader.body, + FRAGMENT_SHADER_BODY, + }; GLuint program_id = vlc_gl_BuildProgram(VLC_OBJECT(filter), vt, - 1, (const char **) &VERTEX_SHADER, - 1, (const char **) &fragment_shader); - free(fragment_shader); + ARRAY_SIZE(vertex_shader), vertex_shader, + ARRAY_SIZE(fragment_shader), fragment_shader); if (!program_id) return VLC_EGENERIC; diff --git a/modules/video_output/opengl/renderer.c b/modules/video_output/opengl/renderer.c index a6d1b65508..773571e2fe 100644 --- a/modules/video_output/opengl/renderer.c +++ b/modules/video_output/opengl/renderer.c @@ -170,25 +170,14 @@ InitStereoMatrix(GLfloat matrix_out[static 3*3], #undef ROW } -/* https://en.wikipedia.org/wiki/OpenGL_Shading_Language#Versions */ -#ifdef USE_OPENGL_ES2 -# define SHADER_VERSION "#version 100\n" - /* In OpenGL ES, the fragment language has no default precision qualifier for - * floating point types. */ -# define FRAGMENT_SHADER_PRECISION "precision highp float;\n" -#else -# define SHADER_VERSION "#version 120\n" -# define FRAGMENT_SHADER_PRECISION -#endif - -static char * -BuildVertexShader(struct vlc_gl_filter *filter) +static int +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; - /* Basic vertex shader */ - static const char *template = - SHADER_VERSION + static const char *const VERTEX_SHADER_BODY = "attribute vec2 PicCoordsIn;\n" "varying vec2 PicCoords;\n" "attribute vec3 VertexPosition;\n" @@ -200,29 +189,9 @@ BuildVertexShader(struct vlc_gl_filter *filter) " PicCoords = (StereoMatrix * vec3(PicCoordsIn, 1.0)).st;\n" " gl_Position = ProjectionMatrix * ZoomMatrix * ViewMatrix\n" " * vec4(VertexPosition, 1.0);\n" - "}"; - - char *code = strdup(template); - if (!code) - return NULL; - - if (renderer->dump_shaders) - 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_filter *filter) -{ - struct vlc_gl_renderer *renderer = filter->sys; - struct vlc_gl_sampler *sampler = renderer->sampler; + "}\n"; - static const char *template = - SHADER_VERSION - "%s" /* extensions */ - FRAGMENT_SHADER_PRECISION - "%s" /* vlc_texture definition */ + static const char *const FRAGMENT_SHADER_BODY = "varying vec2 PicCoords;\n" "void main() {\n" " gl_FragColor = vlc_texture(PicCoords);\n" @@ -231,35 +200,44 @@ BuildFragmentShader(struct vlc_gl_filter *filter) const char *extensions = sampler->shader.extensions ? sampler->shader.extensions : ""; - char *code; - int ret = asprintf(&code, template, extensions, sampler->shader.body); - if (ret < 0) - return NULL; - - if (renderer->dump_shaders) - 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_filter *filter) -{ - struct vlc_gl_renderer *renderer = filter->sys; - struct vlc_gl_sampler *sampler = renderer->sampler; - const opengl_vtable_t *vt = renderer->vt; + const char *shader_version; + const char *shader_precision; + if (filter->api->is_gles) + { + shader_version = "#version 100\n"; + shader_precision = "precision highp float;\n"; + } + else + { + shader_version = "#version 120\n"; + shader_precision = ""; + } - char *vertex_shader = BuildVertexShader(filter); - if (!vertex_shader) - return VLC_EGENERIC; + const char *vertex_shader[] = { + shader_version, + VERTEX_SHADER_BODY, + }; + const char *fragment_shader[] = { + shader_version, + extensions, + shader_precision, + sampler->shader.body, + FRAGMENT_SHADER_BODY, + }; - char *fragment_shader = BuildFragmentShader(filter); - if (!fragment_shader) + if (renderer->dump_shaders) { - free(vertex_shader); - return VLC_EGENERIC; + msg_Dbg(filter, "\n=== Vertex shader for fourcc: %4.4s ===\n", + (const char *) &renderer->sampler->fmt.i_chroma); + for (unsigned i = 0; i < ARRAY_SIZE(vertex_shader); ++i) + msg_Dbg(filter, "[%u] %s", i, vertex_shader[i]); + + msg_Dbg(filter, + "\n=== Fragment shader for fourcc: %4.4s, colorspace: %d ===\n", + (const char *) &renderer->sampler->fmt.i_chroma, + sampler->fmt.space); + for (unsigned i = 0; i < ARRAY_SIZE(fragment_shader); ++i) + msg_Dbg(filter, "[%u] %s", i, fragment_shader[i]); } assert(sampler->ops && @@ -268,10 +246,8 @@ opengl_link_program(struct vlc_gl_filter *filter) GLuint program_id = vlc_gl_BuildProgram(VLC_OBJECT(filter), vt, - 1, (const char **) &vertex_shader, - 1, (const char **) &fragment_shader); - free(vertex_shader); - free(fragment_shader); + ARRAY_SIZE(vertex_shader), vertex_shader, + ARRAY_SIZE(fragment_shader), fragment_shader); if (!program_id) return VLC_EGENERIC; _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
