From 1066b2a860308dc3e14b485239876699dee89a22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 19 Apr 2016 19:43:03 +0300 Subject: [PATCH] glviewconvert: Port more things to GLES/GL 3 compatibility And move the shader mangling code into a single place instead of having a copy in glcolorconvert and glviewconvert. https://bugzilla.gnome.org/show_bug.cgi?id=765266 --- gst-libs/gst/gl/gstglcolorconvert.c | 212 +----------------------- gst-libs/gst/gl/gstglsl.c | 205 ++++++++++++++++++++++++ gst-libs/gst/gl/gstglsl_private.h | 5 + gst-libs/gst/gl/gstglviewconvert.c | 240 ++++------------------------ 4 files changed, 246 insertions(+), 416 deletions(-) diff --git a/gst-libs/gst/gl/gstglcolorconvert.c b/gst-libs/gst/gl/gstglcolorconvert.c index ae3d7fe8d9..ba717fadfe 100644 --- a/gst-libs/gst/gl/gstglcolorconvert.c +++ b/gst-libs/gst/gl/gstglcolorconvert.c @@ -27,6 +27,7 @@ #include "gl.h" #include "gstglcolorconvert.h" +#include "gstglsl_private.h" /** * SECTION:gstglcolorconvert @@ -1710,209 +1711,6 @@ _unbind_buffer (GstGLColorConvert * convert) gl->DisableVertexAttribArray (convert->priv->attr_texture); } -static gchar * -_mangle_texture_access (const gchar * str, GstGLTextureTarget from, - GstGLTextureTarget to, GstGLAPI gl_api, guint gl_major, guint gl_minor) -{ - const gchar *from_str = NULL, *to_str = NULL; - gchar *ret, *tmp; - gchar *regex_find; - GRegex *regex; - - if (from == GST_GL_TEXTURE_TARGET_2D) - from_str = "texture2D"; - if (from == GST_GL_TEXTURE_TARGET_RECTANGLE) - from_str = "texture2DRect"; - if (from == GST_GL_TEXTURE_TARGET_EXTERNAL_OES) - from_str = "texture2D"; - - if ((gl_api & GST_GL_API_OPENGL3) || (gl_api & GST_GL_API_GLES2 - && gl_major >= 3)) { - to_str = "texture"; - } else { - if (to == GST_GL_TEXTURE_TARGET_2D) - to_str = "texture2D"; - if (to == GST_GL_TEXTURE_TARGET_RECTANGLE) - to_str = "texture2DRect"; - if (to == GST_GL_TEXTURE_TARGET_EXTERNAL_OES) - to_str = "texture2D"; - } - - /* followed by any amount of whitespace then a bracket */ - regex_find = g_strdup_printf ("%s(?=\\s*\\()", from_str); - regex = g_regex_new (regex_find, 0, 0, NULL); - tmp = g_regex_replace_literal (regex, str, -1, 0, to_str, 0, NULL); - g_free (regex_find); - g_regex_unref (regex); - - if (tmp) { - ret = tmp; - } else { - GST_FIXME ("Couldn't mangle texture access successfully from %s to %s", - from_str, to_str); - ret = g_strdup (str); - } - - return ret; -} - -static gchar * -_mangle_sampler_type (const gchar * str, GstGLTextureTarget from, - GstGLTextureTarget to) -{ - const gchar *from_str = NULL, *to_str = NULL; - gchar *ret, *tmp; - gchar *regex_find; - GRegex *regex; - - if (from == GST_GL_TEXTURE_TARGET_2D) - from_str = "sampler2D"; - if (from == GST_GL_TEXTURE_TARGET_RECTANGLE) - from_str = "sampler2DRect"; - if (from == GST_GL_TEXTURE_TARGET_EXTERNAL_OES) - from_str = "samplerExternalOES"; - - if (to == GST_GL_TEXTURE_TARGET_2D) - to_str = "sampler2D"; - if (to == GST_GL_TEXTURE_TARGET_RECTANGLE) - to_str = "sampler2DRect"; - if (to == GST_GL_TEXTURE_TARGET_EXTERNAL_OES) - to_str = "samplerExternalOES"; - - /* followed by some whitespace */ - regex_find = g_strdup_printf ("%s(?=\\s)", from_str); - regex = g_regex_new (regex_find, 0, 0, NULL); - tmp = g_regex_replace_literal (regex, str, -1, 0, to_str, 0, NULL); - g_free (regex_find); - g_regex_unref (regex); - - if (tmp) { - ret = tmp; - } else { - GST_FIXME ("Couldn't mangle sampler type successfully from %s to %s", - from_str, to_str); - ret = g_strdup (str); - } - - return ret; -} - -static gchar * -_mangle_varying_attribute (const gchar * str, guint shader_type, - GstGLAPI gl_api, guint gl_major, guint gl_minor) -{ - if (shader_type == GL_VERTEX_SHADER) { - if ((gl_api & GST_GL_API_OPENGL3) || (gl_api & GST_GL_API_GLES2 - && gl_major >= 3)) { - gchar *tmp, *tmp2; - GRegex *regex; - - /* followed by some whitespace */ - regex = g_regex_new ("varying(?=\\s)", 0, 0, NULL); - tmp = g_regex_replace_literal (regex, str, -1, 0, "out", 0, NULL); - g_regex_unref (regex); - - /* followed by some whitespace */ - regex = g_regex_new ("attribute(?=\\s)", 0, 0, NULL); - tmp2 = g_regex_replace_literal (regex, tmp, -1, 0, "in", 0, NULL); - g_regex_unref (regex); - - g_free (tmp); - return tmp2; - } - } else if (shader_type == GL_FRAGMENT_SHADER) { - if ((gl_api & GST_GL_API_OPENGL3) || (gl_api & GST_GL_API_GLES2 - && gl_major > 3)) { - gchar *tmp; - GRegex *regex; - - /* followed by some whitespace */ - regex = g_regex_new ("varying(?=\\s)", 0, 0, NULL); - tmp = g_regex_replace_literal (regex, str, -1, 0, "in", 0, NULL); - g_regex_unref (regex); - - return tmp; - } - } - return g_strdup (str); -} - -static gchar * -_mangle_frag_color_data (const gchar * str) -{ - GRegex *regex; - gchar *ret, *tmp; - - regex = g_regex_new ("gl_FragColor", 0, 0, NULL); - ret = g_regex_replace_literal (regex, str, -1, 0, "fragColor", 0, NULL); - g_regex_unref (regex); - - tmp = ret; - /* search and replace 'gl_FragData[NUM]' into fragColor_NUM */ - regex = g_regex_new ("gl_FragData\\[(\\d+)\\]", 0, 0, NULL); - ret = g_regex_replace (regex, tmp, -1, 0, "fragColor_\\1", 0, NULL); - g_regex_unref (regex); - g_free (tmp); - - return ret; -} - -static void -_mangle_version_profile_from_gl_api (GstGLAPI gl_api, gint gl_major, - gint gl_minor, GstGLSLVersion * version, GstGLSLProfile * profile) -{ - *version = GST_GLSL_VERSION_NONE; - *profile = GST_GLSL_PROFILE_NONE; - - if (gl_api & GST_GL_API_OPENGL3) { - if (gl_major > 3 || gl_minor >= 3) { - *version = GST_GLSL_VERSION_330; - *profile = GST_GLSL_PROFILE_CORE; - } else { - *version = GST_GLSL_VERSION_150; - *profile = GST_GLSL_PROFILE_NONE; - } - } else if (gl_api & GST_GL_API_GLES2) { - if (gl_major >= 3) { - *version = GST_GLSL_VERSION_300; - *profile = GST_GLSL_PROFILE_ES; - } else if (gl_major >= 2) { - *version = GST_GLSL_VERSION_100; - *profile = GST_GLSL_PROFILE_ES; - } - } else if (gl_api & GST_GL_API_OPENGL) { - *version = GST_GLSL_VERSION_110; - *profile = GST_GLSL_PROFILE_COMPATIBILITY; - } -} - -static gchar * -_mangle_shader (const gchar * str, guint shader_type, GstGLTextureTarget from, - GstGLTextureTarget to, GstGLAPI gl_api, gint gl_major, gint gl_minor, - GstGLSLVersion * version, GstGLSLProfile * profile) -{ - gchar *tmp, *tmp2; - - _mangle_version_profile_from_gl_api (gl_api, gl_major, gl_minor, version, - profile); - tmp = _mangle_texture_access (str, from, to, gl_api, gl_major, gl_minor); - tmp2 = _mangle_sampler_type (tmp, from, to); - g_free (tmp); - tmp = - _mangle_varying_attribute (tmp2, shader_type, gl_api, gl_major, gl_minor); - g_free (tmp2); - if (shader_type == GL_FRAGMENT_SHADER) { - if ((*profile == GST_GLSL_PROFILE_ES && *version >= GST_GLSL_VERSION_300) - || (*profile == GST_GLSL_PROFILE_CORE - && *version >= GST_GLSL_VERSION_150)) { - tmp2 = _mangle_frag_color_data (tmp); - g_free (tmp); - tmp = tmp2; - } - } - return tmp; -} - static GstGLShader * _create_shader (GstGLColorConvert * convert) { @@ -1935,9 +1733,9 @@ _create_shader (GstGLColorConvert * convert) ret = gst_gl_shader_new (convert->context); tmp = - _mangle_shader (text_vertex_shader, GL_VERTEX_SHADER, info->templ->target, - convert->priv->from_texture_target, gl_api, gl_major, gl_minor, &version, - &profile); + _gst_glsl_mangle_shader (text_vertex_shader, GL_VERTEX_SHADER, + info->templ->target, convert->priv->from_texture_target, gl_api, gl_major, + gl_minor, &version, &profile); tmp1 = gst_glsl_version_profile_to_string (version, profile); version_str = g_strdup_printf ("#version %s\n", tmp1); @@ -2043,7 +1841,7 @@ _create_shader (GstGLColorConvert * convert) } g_string_append (str, "\n}"); tmp = g_string_free (str, FALSE); - info->frag_prog = _mangle_shader (tmp, GL_FRAGMENT_SHADER, + info->frag_prog = _gst_glsl_mangle_shader (tmp, GL_FRAGMENT_SHADER, info->templ->target, convert->priv->from_texture_target, gl_api, gl_major, gl_minor, &version, &profile); g_free (tmp); diff --git a/gst-libs/gst/gl/gstglsl.c b/gst-libs/gst/gl/gstglsl.c index 5074552905..daf4e35260 100644 --- a/gst-libs/gst/gl/gstglsl.c +++ b/gst-libs/gst/gl/gstglsl.c @@ -551,3 +551,208 @@ _gst_glsl_funcs_fill (GstGLSLFuncs * vtable, GstGLContext * context) vtable->initialized = TRUE; return TRUE; } + + +static gchar * +_mangle_texture_access (const gchar * str, GstGLTextureTarget from, + GstGLTextureTarget to, GstGLAPI gl_api, guint gl_major, guint gl_minor) +{ + const gchar *from_str = NULL, *to_str = NULL; + gchar *ret, *tmp; + gchar *regex_find; + GRegex *regex; + + if (from == GST_GL_TEXTURE_TARGET_2D) + from_str = "texture2D"; + if (from == GST_GL_TEXTURE_TARGET_RECTANGLE) + from_str = "texture2DRect"; + if (from == GST_GL_TEXTURE_TARGET_EXTERNAL_OES) + from_str = "texture2D"; + + if ((gl_api & GST_GL_API_OPENGL3) || (gl_api & GST_GL_API_GLES2 + && gl_major >= 3)) { + to_str = "texture"; + } else { + if (to == GST_GL_TEXTURE_TARGET_2D) + to_str = "texture2D"; + if (to == GST_GL_TEXTURE_TARGET_RECTANGLE) + to_str = "texture2DRect"; + if (to == GST_GL_TEXTURE_TARGET_EXTERNAL_OES) + to_str = "texture2D"; + } + + /* followed by any amount of whitespace then a bracket */ + regex_find = g_strdup_printf ("%s(?=\\s*\\()", from_str); + regex = g_regex_new (regex_find, 0, 0, NULL); + tmp = g_regex_replace_literal (regex, str, -1, 0, to_str, 0, NULL); + g_free (regex_find); + g_regex_unref (regex); + + if (tmp) { + ret = tmp; + } else { + GST_FIXME ("Couldn't mangle texture access successfully from %s to %s", + from_str, to_str); + ret = g_strdup (str); + } + + return ret; +} + +static gchar * +_mangle_sampler_type (const gchar * str, GstGLTextureTarget from, + GstGLTextureTarget to) +{ + const gchar *from_str = NULL, *to_str = NULL; + gchar *ret, *tmp; + gchar *regex_find; + GRegex *regex; + + if (from == GST_GL_TEXTURE_TARGET_2D) + from_str = "sampler2D"; + if (from == GST_GL_TEXTURE_TARGET_RECTANGLE) + from_str = "sampler2DRect"; + if (from == GST_GL_TEXTURE_TARGET_EXTERNAL_OES) + from_str = "samplerExternalOES"; + + if (to == GST_GL_TEXTURE_TARGET_2D) + to_str = "sampler2D"; + if (to == GST_GL_TEXTURE_TARGET_RECTANGLE) + to_str = "sampler2DRect"; + if (to == GST_GL_TEXTURE_TARGET_EXTERNAL_OES) + to_str = "samplerExternalOES"; + + /* followed by some whitespace */ + regex_find = g_strdup_printf ("%s(?=\\s)", from_str); + regex = g_regex_new (regex_find, 0, 0, NULL); + tmp = g_regex_replace_literal (regex, str, -1, 0, to_str, 0, NULL); + g_free (regex_find); + g_regex_unref (regex); + + if (tmp) { + ret = tmp; + } else { + GST_FIXME ("Couldn't mangle sampler type successfully from %s to %s", + from_str, to_str); + ret = g_strdup (str); + } + + return ret; +} + +static gchar * +_mangle_varying_attribute (const gchar * str, guint shader_type, + GstGLAPI gl_api, guint gl_major, guint gl_minor) +{ + if (shader_type == GL_VERTEX_SHADER) { + if ((gl_api & GST_GL_API_OPENGL3) || (gl_api & GST_GL_API_GLES2 + && gl_major >= 3)) { + gchar *tmp, *tmp2; + GRegex *regex; + + /* followed by some whitespace */ + regex = g_regex_new ("varying(?=\\s)", 0, 0, NULL); + tmp = g_regex_replace_literal (regex, str, -1, 0, "out", 0, NULL); + g_regex_unref (regex); + + /* followed by some whitespace */ + regex = g_regex_new ("attribute(?=\\s)", 0, 0, NULL); + tmp2 = g_regex_replace_literal (regex, tmp, -1, 0, "in", 0, NULL); + g_regex_unref (regex); + + g_free (tmp); + return tmp2; + } + } else if (shader_type == GL_FRAGMENT_SHADER) { + if ((gl_api & GST_GL_API_OPENGL3) || (gl_api & GST_GL_API_GLES2 + && gl_major > 3)) { + gchar *tmp; + GRegex *regex; + + /* followed by some whitespace */ + regex = g_regex_new ("varying(?=\\s)", 0, 0, NULL); + tmp = g_regex_replace_literal (regex, str, -1, 0, "in", 0, NULL); + g_regex_unref (regex); + + return tmp; + } + } + return g_strdup (str); +} + +static gchar * +_mangle_frag_color_data (const gchar * str) +{ + GRegex *regex; + gchar *ret, *tmp; + + regex = g_regex_new ("gl_FragColor", 0, 0, NULL); + ret = g_regex_replace_literal (regex, str, -1, 0, "fragColor", 0, NULL); + g_regex_unref (regex); + + tmp = ret; + /* search and replace 'gl_FragData[NUM]' into fragColor_NUM */ + regex = g_regex_new ("gl_FragData\\[(\\d+)\\]", 0, 0, NULL); + ret = g_regex_replace (regex, tmp, -1, 0, "fragColor_\\1", 0, NULL); + g_regex_unref (regex); + g_free (tmp); + + return ret; +} + +static void +_mangle_version_profile_from_gl_api (GstGLAPI gl_api, gint gl_major, + gint gl_minor, GstGLSLVersion * version, GstGLSLProfile * profile) +{ + *version = GST_GLSL_VERSION_NONE; + *profile = GST_GLSL_PROFILE_NONE; + + if (gl_api & GST_GL_API_OPENGL3) { + if (gl_major > 3 || gl_minor >= 3) { + *version = GST_GLSL_VERSION_330; + *profile = GST_GLSL_PROFILE_CORE; + } else { + *version = GST_GLSL_VERSION_150; + *profile = GST_GLSL_PROFILE_NONE; + } + } else if (gl_api & GST_GL_API_GLES2) { + if (gl_major >= 3) { + *version = GST_GLSL_VERSION_300; + *profile = GST_GLSL_PROFILE_ES; + } else if (gl_major >= 2) { + *version = GST_GLSL_VERSION_100; + *profile = GST_GLSL_PROFILE_ES; + } + } else if (gl_api & GST_GL_API_OPENGL) { + *version = GST_GLSL_VERSION_110; + *profile = GST_GLSL_PROFILE_COMPATIBILITY; + } +} + +gchar * +_gst_glsl_mangle_shader (const gchar * str, guint shader_type, + GstGLTextureTarget from, GstGLTextureTarget to, GstGLAPI gl_api, + gint gl_major, gint gl_minor, GstGLSLVersion * version, + GstGLSLProfile * profile) +{ + gchar *tmp, *tmp2; + + _mangle_version_profile_from_gl_api (gl_api, gl_major, gl_minor, version, + profile); + tmp = _mangle_texture_access (str, from, to, gl_api, gl_major, gl_minor); + tmp2 = _mangle_sampler_type (tmp, from, to); + g_free (tmp); + tmp = + _mangle_varying_attribute (tmp2, shader_type, gl_api, gl_major, gl_minor); + g_free (tmp2); + if (shader_type == GL_FRAGMENT_SHADER) { + if ((*profile == GST_GLSL_PROFILE_ES && *version >= GST_GLSL_VERSION_300) + || (*profile == GST_GLSL_PROFILE_CORE + && *version >= GST_GLSL_VERSION_150)) { + tmp2 = _mangle_frag_color_data (tmp); + g_free (tmp); + tmp = tmp2; + } + } + return tmp; +} diff --git a/gst-libs/gst/gl/gstglsl_private.h b/gst-libs/gst/gl/gstglsl_private.h index c1be677ae4..49c6b382bd 100644 --- a/gst-libs/gst/gl/gstglsl_private.h +++ b/gst-libs/gst/gl/gstglsl_private.h @@ -58,6 +58,11 @@ typedef struct _GstGLSLFuncs G_GNUC_INTERNAL gboolean _gst_glsl_funcs_fill (GstGLSLFuncs * vtable, GstGLContext * context); G_GNUC_INTERNAL const gchar * _gst_glsl_shader_string_find_version (const gchar * str); +G_GNUC_INTERNAL gchar * +_gst_glsl_mangle_shader (const gchar * str, guint shader_type, GstGLTextureTarget from, + GstGLTextureTarget to, GstGLAPI gl_api, gint gl_major, gint gl_minor, + GstGLSLVersion * version, GstGLSLProfile * profile); + G_END_DECLS #endif /* __GST_GLSL_PRIVATE_H__ */ diff --git a/gst-libs/gst/gl/gstglviewconvert.c b/gst-libs/gst/gl/gstglviewconvert.c index ec335e1e62..be940aab60 100644 --- a/gst-libs/gst/gl/gstglviewconvert.c +++ b/gst-libs/gst/gl/gstglviewconvert.c @@ -31,6 +31,7 @@ #endif #include "gstglviewconvert.h" +#include "gstglsl_private.h" #include #define USING_OPENGL(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 1, 0)) @@ -159,7 +160,6 @@ static const gchar *fragment_header = "#ifdef GL_ES\n" "precision mediump float;\n" "#endif\n" - "varying vec2 v_texcoord;\n" "uniform sampler2D tex_l;\n" "uniform sampler2D tex_r;\n" "uniform float width;\n" @@ -1453,205 +1453,11 @@ _init_view_convert_fbo (GstGLViewConvert * viewconvert) return ret; } -static gchar * -_mangle_texture_access (const gchar * str, GstGLTextureTarget from, - GstGLTextureTarget to) -{ - const gchar *from_str = NULL, *to_str = NULL; - gchar *ret, *tmp; - gchar *regex_find; - GRegex *regex; - - if (from == GST_GL_TEXTURE_TARGET_2D) - from_str = "texture2D"; - if (from == GST_GL_TEXTURE_TARGET_RECTANGLE) - from_str = "texture2DRect"; - if (from == GST_GL_TEXTURE_TARGET_EXTERNAL_OES) - from_str = "texture2D"; - - if (to == GST_GL_TEXTURE_TARGET_2D) - to_str = "texture2D"; - if (to == GST_GL_TEXTURE_TARGET_RECTANGLE) - to_str = "texture2DRect"; - if (to == GST_GL_TEXTURE_TARGET_EXTERNAL_OES) - to_str = "texture2D"; - - /* followed by any amount of whitespace then a bracket */ - regex_find = g_strdup_printf ("%s(?=\\s*\\()", from_str); - regex = g_regex_new (regex_find, 0, 0, NULL); - tmp = g_regex_replace_literal (regex, str, -1, 0, to_str, 0, NULL); - g_free (regex_find); - g_regex_unref (regex); - - if (tmp) { - ret = tmp; - } else { - GST_FIXME ("Couldn't mangle texture access successfully from %s to %s", - from_str, to_str); - ret = g_strdup (str); - } - - return ret; -} - -static gchar * -_mangle_sampler_type (const gchar * str, GstGLTextureTarget from, - GstGLTextureTarget to) -{ - const gchar *from_str = NULL, *to_str = NULL; - gchar *ret, *tmp; - gchar *regex_find; - GRegex *regex; - - if (from == GST_GL_TEXTURE_TARGET_2D) - from_str = "sampler2D"; - if (from == GST_GL_TEXTURE_TARGET_RECTANGLE) - from_str = "sampler2DRect"; - if (from == GST_GL_TEXTURE_TARGET_EXTERNAL_OES) - from_str = "samplerExternalOES"; - - if (to == GST_GL_TEXTURE_TARGET_2D) - to_str = "sampler2D"; - if (to == GST_GL_TEXTURE_TARGET_RECTANGLE) - to_str = "sampler2DRect"; - if (to == GST_GL_TEXTURE_TARGET_EXTERNAL_OES) - to_str = "samplerExternalOES"; - - /* followed by some whitespace */ - regex_find = g_strdup_printf ("%s(?=\\s)", from_str); - regex = g_regex_new (regex_find, 0, 0, NULL); - tmp = g_regex_replace_literal (regex, str, -1, 0, to_str, 0, NULL); - g_free (regex_find); - g_regex_unref (regex); - - if (tmp) { - ret = tmp; - } else { - GST_FIXME ("Couldn't mangle sampler type successfully from %s to %s", - from_str, to_str); - ret = g_strdup (str); - } - - return ret; -} - -static gchar * -_mangle_varying_attribute (const gchar * str, guint shader_type, - GstGLSLVersion version, GstGLSLProfile profile) -{ - if (shader_type == GL_VERTEX_SHADER) { - if (profile == GST_GLSL_PROFILE_CORE || (profile == GST_GLSL_PROFILE_ES - && version >= GST_GLSL_VERSION_300)) { - gchar *tmp, *tmp2; - GRegex *regex; - - /* followed by some whitespace */ - regex = g_regex_new ("varying(?=\\s)", 0, 0, NULL); - tmp = g_regex_replace_literal (regex, str, -1, 0, "out", 0, NULL); - g_regex_unref (regex); - - /* followed by some whitespace */ - regex = g_regex_new ("attribute(?=\\s)", 0, 0, NULL); - tmp2 = g_regex_replace_literal (regex, tmp, -1, 0, "in", 0, NULL); - g_regex_unref (regex); - - g_free (tmp); - return tmp2; - } - } else if (shader_type == GL_FRAGMENT_SHADER) { - if (profile == GST_GLSL_PROFILE_CORE || (profile == GST_GLSL_PROFILE_ES - && version >= GST_GLSL_VERSION_300)) { - gchar *tmp; - GRegex *regex; - - /* followed by some whitespace */ - regex = g_regex_new ("varying(?=\\s)", 0, 0, NULL); - tmp = g_regex_replace_literal (regex, str, -1, 0, "in", 0, NULL); - g_regex_unref (regex); - - return tmp; - } - } - return g_strdup (str); -} - -static gchar * -_mangle_frag_color_data (const gchar * str) -{ - GRegex *regex; - gchar *ret, *tmp; - - regex = g_regex_new ("gl_FragColor", 0, 0, NULL); - ret = g_regex_replace_literal (regex, str, -1, 0, "fragColor", 0, NULL); - g_regex_unref (regex); - - tmp = ret; - /* search and replace 'gl_FragData[NUM]' into fragColor_NUM */ - regex = g_regex_new ("gl_FragData\\[(\\d+)\\]", 0, 0, NULL); - ret = g_regex_replace (regex, tmp, -1, 0, "fragColor_\\1", 0, NULL); - g_regex_unref (regex); - g_free (tmp); - - return ret; -} - -static void -_mangle_version_profile_from_gl_api (GstGLAPI gl_api, gint gl_major, - gint gl_minor, GstGLSLVersion * version, GstGLSLProfile * profile) -{ - *version = GST_GLSL_VERSION_NONE; - *profile = GST_GLSL_PROFILE_NONE; - - if (gl_api & GST_GL_API_OPENGL3) { - if (gl_major > 3 || gl_minor >= 3) { - *version = GST_GLSL_VERSION_330; - *profile = GST_GLSL_PROFILE_CORE; - } else { - *version = GST_GLSL_VERSION_150; - *profile = GST_GLSL_PROFILE_NONE; - } - } else if (gl_api & GST_GL_API_GLES2) { - if (gl_major >= 3) { - *version = GST_GLSL_VERSION_300; - *profile = GST_GLSL_PROFILE_ES; - } else if (gl_major >= 2) { - *version = GST_GLSL_VERSION_100; - *profile = GST_GLSL_PROFILE_ES; - } - } else if (gl_api & GST_GL_API_OPENGL) { - *version = GST_GLSL_VERSION_110; - *profile = GST_GLSL_PROFILE_COMPATIBILITY; - } -} - -static gchar * -_mangle_shader (const gchar * str, guint shader_type, GstGLTextureTarget from, - GstGLTextureTarget to, GstGLSLVersion version, GstGLSLProfile profile) -{ - gchar *tmp, *tmp2; - - tmp2 = _mangle_sampler_type (str, from, to); - tmp = _mangle_texture_access (tmp2, from, to); - g_free (tmp2); - tmp2 = _mangle_varying_attribute (tmp, shader_type, version, profile); - g_free (tmp); - if (shader_type == GL_FRAGMENT_SHADER) { - if ((profile == GST_GLSL_PROFILE_ES && version >= GST_GLSL_VERSION_300) - || (profile == GST_GLSL_PROFILE_CORE - && version >= GST_GLSL_VERSION_150)) { - tmp = _mangle_frag_color_data (tmp2); - g_free (tmp2); - tmp2 = tmp; - } - } - - return tmp2; -} - /* free after use */ static gchar * _get_shader_string (GstGLViewConvert * viewconvert, GstGLShader * shader, GstVideoMultiviewMode in_mode, GstVideoMultiviewMode out_mode, + GstGLAPI gl_api, gint gl_major, gint gl_minor, GstGLSLVersion version, GstGLSLProfile profile) { const gchar *input_str, *output_str; @@ -1747,14 +1553,29 @@ _get_shader_string (GstGLViewConvert * viewconvert, GstGLShader * shader, } } - g_string_append (str, "\nvoid main() {\nvec4 l, r;\n"); + { + const gchar *varying = NULL; + + if ((profile == GST_GLSL_PROFILE_ES && version >= GST_GLSL_VERSION_300) + || (profile == GST_GLSL_PROFILE_CORE + && version >= GST_GLSL_VERSION_150)) { + varying = "in"; + } else { + varying = "varying"; + } + g_string_append_printf (str, + "\n%s vec2 v_texcoord;\nvoid main() {\nvec4 l, r;\n", varying); + } + g_string_append (str, input_str); g_string_append (str, output_str); g_string_append (str, "\n}"); tmp = g_string_free (str, FALSE); - tmp2 = _mangle_shader (tmp, GL_FRAGMENT_SHADER, GST_GL_TEXTURE_TARGET_2D, - viewconvert->from_texture_target, version, profile); + tmp2 = + _gst_glsl_mangle_shader (tmp, GL_FRAGMENT_SHADER, + GST_GL_TEXTURE_TARGET_2D, viewconvert->from_texture_target, gl_api, + gl_major, gl_minor, &version, &profile); return tmp2; } @@ -1912,23 +1733,24 @@ _init_view_convert (GstGLViewConvert * viewconvert) GstGLAPI gl_api; gint gl_major, gl_minor; GstGLSLStage *vert, *frag; - gchar *tmp, *version_str; + gchar *tmp, *tmp1, *version_str; const gchar *strings[2]; GError *error = NULL; gl_api = gst_gl_context_get_gl_api (viewconvert->context); gst_gl_context_get_gl_version (viewconvert->context, &gl_major, &gl_minor); - _mangle_version_profile_from_gl_api (gl_api, gl_major, gl_minor, &version, - &profile); - tmp = gst_glsl_version_profile_to_string (version, profile); - version_str = g_strdup_printf ("#version %s\n", tmp); - g_free (tmp); + tmp = + _gst_glsl_mangle_shader + (gst_gl_shader_string_vertex_mat4_texture_transform, GL_VERTEX_SHADER, + GST_GL_TEXTURE_TARGET_2D, viewconvert->from_texture_target, gl_api, + gl_major, gl_minor, &version, &profile); + + tmp1 = gst_glsl_version_profile_to_string (version, profile); + version_str = g_strdup_printf ("#version %s\n", tmp1); + g_free (tmp1); strings[0] = version_str; - tmp = _mangle_shader (gst_gl_shader_string_vertex_mat4_texture_transform, - GL_VERTEX_SHADER, GST_GL_TEXTURE_TARGET_2D, - viewconvert->from_texture_target, version, profile); strings[1] = tmp; vert = gst_glsl_stage_new_with_strings (viewconvert->context, @@ -1945,7 +1767,7 @@ _init_view_convert (GstGLViewConvert * viewconvert) } fragment_source_str = _get_shader_string (viewconvert, viewconvert->shader, - in_mode, out_mode, version, profile); + in_mode, out_mode, gl_api, gl_major, gl_minor, version, profile); strings[1] = fragment_source_str; frag =