mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-04 15:36:35 +00:00
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
This commit is contained in:
parent
64c320ca3c
commit
1066b2a860
4 changed files with 246 additions and 416 deletions
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include "gl.h"
|
#include "gl.h"
|
||||||
#include "gstglcolorconvert.h"
|
#include "gstglcolorconvert.h"
|
||||||
|
#include "gstglsl_private.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:gstglcolorconvert
|
* SECTION:gstglcolorconvert
|
||||||
|
@ -1710,209 +1711,6 @@ _unbind_buffer (GstGLColorConvert * convert)
|
||||||
gl->DisableVertexAttribArray (convert->priv->attr_texture);
|
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 *
|
static GstGLShader *
|
||||||
_create_shader (GstGLColorConvert * convert)
|
_create_shader (GstGLColorConvert * convert)
|
||||||
{
|
{
|
||||||
|
@ -1935,9 +1733,9 @@ _create_shader (GstGLColorConvert * convert)
|
||||||
ret = gst_gl_shader_new (convert->context);
|
ret = gst_gl_shader_new (convert->context);
|
||||||
|
|
||||||
tmp =
|
tmp =
|
||||||
_mangle_shader (text_vertex_shader, GL_VERTEX_SHADER, info->templ->target,
|
_gst_glsl_mangle_shader (text_vertex_shader, GL_VERTEX_SHADER,
|
||||||
convert->priv->from_texture_target, gl_api, gl_major, gl_minor, &version,
|
info->templ->target, convert->priv->from_texture_target, gl_api, gl_major,
|
||||||
&profile);
|
gl_minor, &version, &profile);
|
||||||
|
|
||||||
tmp1 = gst_glsl_version_profile_to_string (version, profile);
|
tmp1 = gst_glsl_version_profile_to_string (version, profile);
|
||||||
version_str = g_strdup_printf ("#version %s\n", tmp1);
|
version_str = g_strdup_printf ("#version %s\n", tmp1);
|
||||||
|
@ -2043,7 +1841,7 @@ _create_shader (GstGLColorConvert * convert)
|
||||||
}
|
}
|
||||||
g_string_append (str, "\n}");
|
g_string_append (str, "\n}");
|
||||||
tmp = g_string_free (str, FALSE);
|
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,
|
info->templ->target, convert->priv->from_texture_target, gl_api,
|
||||||
gl_major, gl_minor, &version, &profile);
|
gl_major, gl_minor, &version, &profile);
|
||||||
g_free (tmp);
|
g_free (tmp);
|
||||||
|
|
|
@ -551,3 +551,208 @@ _gst_glsl_funcs_fill (GstGLSLFuncs * vtable, GstGLContext * context)
|
||||||
vtable->initialized = TRUE;
|
vtable->initialized = TRUE;
|
||||||
return 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;
|
||||||
|
}
|
||||||
|
|
|
@ -58,6 +58,11 @@ typedef struct _GstGLSLFuncs
|
||||||
G_GNUC_INTERNAL gboolean _gst_glsl_funcs_fill (GstGLSLFuncs * vtable, GstGLContext * context);
|
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 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
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GST_GLSL_PRIVATE_H__ */
|
#endif /* __GST_GLSL_PRIVATE_H__ */
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "gstglviewconvert.h"
|
#include "gstglviewconvert.h"
|
||||||
|
#include "gstglsl_private.h"
|
||||||
#include <gst/video/gstvideoaffinetransformationmeta.h>
|
#include <gst/video/gstvideoaffinetransformationmeta.h>
|
||||||
|
|
||||||
#define USING_OPENGL(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 1, 0))
|
#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"
|
"#ifdef GL_ES\n"
|
||||||
"precision mediump float;\n"
|
"precision mediump float;\n"
|
||||||
"#endif\n"
|
"#endif\n"
|
||||||
"varying vec2 v_texcoord;\n"
|
|
||||||
"uniform sampler2D tex_l;\n"
|
"uniform sampler2D tex_l;\n"
|
||||||
"uniform sampler2D tex_r;\n"
|
"uniform sampler2D tex_r;\n"
|
||||||
"uniform float width;\n"
|
"uniform float width;\n"
|
||||||
|
@ -1453,205 +1453,11 @@ _init_view_convert_fbo (GstGLViewConvert * viewconvert)
|
||||||
return ret;
|
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 */
|
/* free after use */
|
||||||
static gchar *
|
static gchar *
|
||||||
_get_shader_string (GstGLViewConvert * viewconvert, GstGLShader * shader,
|
_get_shader_string (GstGLViewConvert * viewconvert, GstGLShader * shader,
|
||||||
GstVideoMultiviewMode in_mode, GstVideoMultiviewMode out_mode,
|
GstVideoMultiviewMode in_mode, GstVideoMultiviewMode out_mode,
|
||||||
|
GstGLAPI gl_api, gint gl_major, gint gl_minor,
|
||||||
GstGLSLVersion version, GstGLSLProfile profile)
|
GstGLSLVersion version, GstGLSLProfile profile)
|
||||||
{
|
{
|
||||||
const gchar *input_str, *output_str;
|
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, input_str);
|
||||||
g_string_append (str, output_str);
|
g_string_append (str, output_str);
|
||||||
g_string_append (str, "\n}");
|
g_string_append (str, "\n}");
|
||||||
tmp = g_string_free (str, FALSE);
|
tmp = g_string_free (str, FALSE);
|
||||||
|
|
||||||
tmp2 = _mangle_shader (tmp, GL_FRAGMENT_SHADER, GST_GL_TEXTURE_TARGET_2D,
|
tmp2 =
|
||||||
viewconvert->from_texture_target, version, profile);
|
_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;
|
return tmp2;
|
||||||
}
|
}
|
||||||
|
@ -1912,23 +1733,24 @@ _init_view_convert (GstGLViewConvert * viewconvert)
|
||||||
GstGLAPI gl_api;
|
GstGLAPI gl_api;
|
||||||
gint gl_major, gl_minor;
|
gint gl_major, gl_minor;
|
||||||
GstGLSLStage *vert, *frag;
|
GstGLSLStage *vert, *frag;
|
||||||
gchar *tmp, *version_str;
|
gchar *tmp, *tmp1, *version_str;
|
||||||
const gchar *strings[2];
|
const gchar *strings[2];
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
gl_api = gst_gl_context_get_gl_api (viewconvert->context);
|
gl_api = gst_gl_context_get_gl_api (viewconvert->context);
|
||||||
gst_gl_context_get_gl_version (viewconvert->context, &gl_major, &gl_minor);
|
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);
|
tmp =
|
||||||
version_str = g_strdup_printf ("#version %s\n", tmp);
|
_gst_glsl_mangle_shader
|
||||||
g_free (tmp);
|
(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;
|
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;
|
strings[1] = tmp;
|
||||||
vert =
|
vert =
|
||||||
gst_glsl_stage_new_with_strings (viewconvert->context,
|
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,
|
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;
|
strings[1] = fragment_source_str;
|
||||||
|
|
||||||
frag =
|
frag =
|
||||||
|
|
Loading…
Reference in a new issue