Skip to content

Commit

Permalink
opengl: determine shader version dynamically
Browse files Browse the repository at this point in the history
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 <ajanni@videolabs.io>
Signed-off-by: Alexandre Janniaux <ajanni@videolabs.io>
  • Loading branch information
rom1v and alexandre-janniaux committed Apr 20, 2021
1 parent 0b339ba commit 199f381
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 141 deletions.
58 changes: 30 additions & 28 deletions modules/video_output/opengl/filter_draw.c
Expand Up @@ -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"
Expand All @@ -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"
Expand All @@ -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"
Expand All @@ -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;

Expand Down
128 changes: 83 additions & 45 deletions modules/video_output/opengl/filter_mock.c
Expand Up @@ -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[] = {
Expand Down Expand Up @@ -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"
Expand All @@ -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;
Expand Down Expand Up @@ -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"
Expand All @@ -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"
Expand All @@ -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;

Expand Down Expand Up @@ -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"
Expand All @@ -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"
Expand All @@ -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;

Expand Down

0 comments on commit 199f381

Please sign in to comment.