mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 01:00:37 +00:00
glsl: fixup external-oes shaders by mangling the required extension
Newer devices require using a different GLSL extension for accessing external-oes textures in a shader using the texture() functions. While the GL_OES_EGL_image_external_essl3 should supposedly be supported on a any GLES3 android device, the extension was defined after a lot of the older drivers were built so they will not know about it. Thus there are two possible interpretations of which of texture[2D]() should be supported for external-oes textures. Strict adherence to the GL_OES_EGL_image_external extension spec which uses texture2D() or following GLES3's pattern, also allowing texture() as a function for accessing external-oes textures This adds another mangling pass to convert #extension GL_OES_EGL_image_external : ... into #extension GL_OES_EGL_image_external_essl3 : ... on GLES3 and when the GL_OES_EGL_image_external_essl3 extension is supported. Only uses texture() when the GLES3 and the GL_OES_EGL_image_external_essl3 extension is supported for external-oes textures. Uses GLES2 + texture2D() + GL_OES_EGL_image_external in all other external-oes cases. https://bugzilla.gnome.org/show_bug.cgi?id=766993
This commit is contained in:
parent
28f0df681c
commit
d3f3787d64
4 changed files with 89 additions and 42 deletions
|
@ -1723,19 +1723,14 @@ _create_shader (GstGLColorConvert * convert)
|
||||||
gchar *version_str, *tmp, *tmp1;
|
gchar *version_str, *tmp, *tmp1;
|
||||||
const gchar *strings[2];
|
const gchar *strings[2];
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GstGLAPI gl_api;
|
|
||||||
gint gl_major, gl_minor;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
gl_api = gst_gl_context_get_gl_api (convert->context);
|
|
||||||
gst_gl_context_get_gl_version (convert->context, &gl_major, &gl_minor);
|
|
||||||
|
|
||||||
ret = gst_gl_shader_new (convert->context);
|
ret = gst_gl_shader_new (convert->context);
|
||||||
|
|
||||||
tmp =
|
tmp =
|
||||||
_gst_glsl_mangle_shader (text_vertex_shader, GL_VERTEX_SHADER,
|
_gst_glsl_mangle_shader (text_vertex_shader, GL_VERTEX_SHADER,
|
||||||
info->templ->target, convert->priv->from_texture_target, gl_api, gl_major,
|
info->templ->target, convert->priv->from_texture_target, convert->context,
|
||||||
gl_minor, &version, &profile);
|
&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);
|
||||||
|
@ -1842,8 +1837,8 @@ _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 = _gst_glsl_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, convert->context,
|
||||||
gl_major, gl_minor, &version, &profile);
|
&version, &profile);
|
||||||
g_free (tmp);
|
g_free (tmp);
|
||||||
|
|
||||||
strings[1] = info->frag_prog;
|
strings[1] = info->frag_prog;
|
||||||
|
|
|
@ -594,10 +594,51 @@ _gst_glsl_funcs_fill (GstGLSLFuncs * vtable, GstGLContext * context)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
_mangle_external_image_extension (const gchar * str, GstGLContext * context,
|
||||||
|
GstGLTextureTarget from, GstGLTextureTarget to, GstGLSLVersion version,
|
||||||
|
GstGLSLProfile profile)
|
||||||
|
{
|
||||||
|
GST_DEBUG ("is oes? %d, profile == ES? %d, version >= 300? %d, "
|
||||||
|
"have essl3? %d", to == GST_GL_TEXTURE_TARGET_EXTERNAL_OES,
|
||||||
|
profile == GST_GLSL_PROFILE_ES, version >= GST_GLSL_VERSION_300,
|
||||||
|
gst_gl_context_check_feature (context,
|
||||||
|
"GL_OES_EGL_image_external_essl3"));
|
||||||
|
|
||||||
|
/* replace GL_OES_EGL_image_external with GL_OES_EGL_image_external_essl3 where supported */
|
||||||
|
if (to == GST_GL_TEXTURE_TARGET_EXTERNAL_OES && profile == GST_GLSL_PROFILE_ES
|
||||||
|
&& version >= GST_GLSL_VERSION_300) {
|
||||||
|
if (gst_gl_context_check_feature (context,
|
||||||
|
"GL_OES_EGL_image_external_essl3")) {
|
||||||
|
GRegex *regex = g_regex_new (
|
||||||
|
/* '#extension ' with optional spacing */
|
||||||
|
"(#[ \\t]*extension[ \\t]+)"
|
||||||
|
/* what we're looking to replace */
|
||||||
|
"GL_OES_EGL_image_external"
|
||||||
|
/* ':' with optional spacing */
|
||||||
|
"([ \\t]*:[ \\t]*"
|
||||||
|
/* some word like require, disable, etc followed by spacing and a newline */
|
||||||
|
"\\S+[ \\t]*\\R)",
|
||||||
|
0, 0, NULL);
|
||||||
|
gchar *tmp = g_regex_replace (regex, str, -1, 0,
|
||||||
|
"\\1GL_OES_EGL_image_external_essl3\\2", 0, NULL);
|
||||||
|
g_regex_unref (regex);
|
||||||
|
return tmp;
|
||||||
|
} else {
|
||||||
|
GST_FIXME ("Undefined situation detected. GLES3 supported but "
|
||||||
|
"GL_OES_EGL_image_external_essl3 not supported. Falling back to the "
|
||||||
|
"older GL_OES_EGL_image_external extension");
|
||||||
|
return g_strdup (str);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return g_strdup (str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static gchar *
|
static gchar *
|
||||||
_mangle_texture_access (const gchar * str, GstGLTextureTarget from,
|
_mangle_texture_access (const gchar * str, GstGLContext * context,
|
||||||
GstGLTextureTarget to, GstGLAPI gl_api, guint gl_major, guint gl_minor)
|
GstGLTextureTarget from, GstGLTextureTarget to, GstGLSLVersion version,
|
||||||
|
GstGLSLProfile profile)
|
||||||
{
|
{
|
||||||
const gchar *from_str = NULL, *to_str = NULL;
|
const gchar *from_str = NULL, *to_str = NULL;
|
||||||
gchar *ret, *tmp;
|
gchar *ret, *tmp;
|
||||||
|
@ -611,8 +652,12 @@ _mangle_texture_access (const gchar * str, GstGLTextureTarget from,
|
||||||
if (from == GST_GL_TEXTURE_TARGET_EXTERNAL_OES)
|
if (from == GST_GL_TEXTURE_TARGET_EXTERNAL_OES)
|
||||||
from_str = "texture2D";
|
from_str = "texture2D";
|
||||||
|
|
||||||
if ((gl_api & GST_GL_API_OPENGL3) || (gl_api & GST_GL_API_GLES2
|
/* GL3 || gles3 but not when external-oes unless the image_external_essl3 extension is supported */
|
||||||
&& gl_major >= 3)) {
|
if (profile == GST_GLSL_PROFILE_CORE || (profile == GST_GLSL_PROFILE_ES
|
||||||
|
&& version >= GST_GLSL_VERSION_300
|
||||||
|
&& (to != GST_GL_TEXTURE_TARGET_EXTERNAL_OES
|
||||||
|
|| gst_gl_context_check_feature (context,
|
||||||
|
"GL_OES_EGL_image_external_essl3")))) {
|
||||||
to_str = "texture";
|
to_str = "texture";
|
||||||
} else {
|
} else {
|
||||||
if (to == GST_GL_TEXTURE_TARGET_2D)
|
if (to == GST_GL_TEXTURE_TARGET_2D)
|
||||||
|
@ -684,11 +729,11 @@ _mangle_sampler_type (const gchar * str, GstGLTextureTarget from,
|
||||||
|
|
||||||
static gchar *
|
static gchar *
|
||||||
_mangle_varying_attribute (const gchar * str, guint shader_type,
|
_mangle_varying_attribute (const gchar * str, guint shader_type,
|
||||||
GstGLAPI gl_api, guint gl_major, guint gl_minor)
|
GstGLSLVersion version, GstGLSLProfile profile)
|
||||||
{
|
{
|
||||||
if (shader_type == GL_VERTEX_SHADER) {
|
if (shader_type == GL_VERTEX_SHADER) {
|
||||||
if ((gl_api & GST_GL_API_OPENGL3) || (gl_api & GST_GL_API_GLES2
|
if (profile == GST_GLSL_PROFILE_CORE || (profile == GST_GLSL_PROFILE_ES
|
||||||
&& gl_major >= 3)) {
|
&& version >= GST_GLSL_VERSION_300)) {
|
||||||
gchar *tmp, *tmp2;
|
gchar *tmp, *tmp2;
|
||||||
GRegex *regex;
|
GRegex *regex;
|
||||||
|
|
||||||
|
@ -706,8 +751,8 @@ _mangle_varying_attribute (const gchar * str, guint shader_type,
|
||||||
return tmp2;
|
return tmp2;
|
||||||
}
|
}
|
||||||
} else if (shader_type == GL_FRAGMENT_SHADER) {
|
} else if (shader_type == GL_FRAGMENT_SHADER) {
|
||||||
if ((gl_api & GST_GL_API_OPENGL3) || (gl_api & GST_GL_API_GLES2
|
if (profile == GST_GLSL_PROFILE_CORE || (profile == GST_GLSL_PROFILE_ES
|
||||||
&& gl_major > 3)) {
|
&& version >= GST_GLSL_VERSION_300)) {
|
||||||
gchar *tmp;
|
gchar *tmp;
|
||||||
GRegex *regex;
|
GRegex *regex;
|
||||||
|
|
||||||
|
@ -743,9 +788,16 @@ _mangle_frag_color_data (const gchar * str)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_mangle_version_profile_from_gl_api (GstGLAPI gl_api, gint gl_major,
|
_mangle_version_profile_from_gl_api (GstGLContext * context,
|
||||||
gint gl_minor, GstGLSLVersion * version, GstGLSLProfile * profile)
|
GstGLTextureTarget from, GstGLTextureTarget to, GstGLSLVersion * version,
|
||||||
|
GstGLSLProfile * profile)
|
||||||
{
|
{
|
||||||
|
GstGLAPI gl_api;
|
||||||
|
gint gl_major, gl_minor;
|
||||||
|
|
||||||
|
gl_api = gst_gl_context_get_gl_api (context);
|
||||||
|
gst_gl_context_get_gl_version (context, &gl_major, &gl_minor);
|
||||||
|
|
||||||
*version = GST_GLSL_VERSION_NONE;
|
*version = GST_GLSL_VERSION_NONE;
|
||||||
*profile = GST_GLSL_PROFILE_NONE;
|
*profile = GST_GLSL_PROFILE_NONE;
|
||||||
|
|
||||||
|
@ -758,7 +810,11 @@ _mangle_version_profile_from_gl_api (GstGLAPI gl_api, gint gl_major,
|
||||||
*profile = GST_GLSL_PROFILE_NONE;
|
*profile = GST_GLSL_PROFILE_NONE;
|
||||||
}
|
}
|
||||||
} else if (gl_api & GST_GL_API_GLES2) {
|
} else if (gl_api & GST_GL_API_GLES2) {
|
||||||
if (gl_major >= 3) {
|
/* We don't know which texture function to use if we have GLES3 and
|
||||||
|
* don't have the essl3 extension */
|
||||||
|
if (gl_major >= 3 && (to != GST_GL_TEXTURE_TARGET_EXTERNAL_OES
|
||||||
|
|| gst_gl_context_check_feature (context,
|
||||||
|
"GL_OES_EGL_image_external_essl3"))) {
|
||||||
*version = GST_GLSL_VERSION_300;
|
*version = GST_GLSL_VERSION_300;
|
||||||
*profile = GST_GLSL_PROFILE_ES;
|
*profile = GST_GLSL_PROFILE_ES;
|
||||||
} else if (gl_major >= 2) {
|
} else if (gl_major >= 2) {
|
||||||
|
@ -773,21 +829,24 @@ _mangle_version_profile_from_gl_api (GstGLAPI gl_api, gint gl_major,
|
||||||
|
|
||||||
gchar *
|
gchar *
|
||||||
_gst_glsl_mangle_shader (const gchar * str, guint shader_type,
|
_gst_glsl_mangle_shader (const gchar * str, guint shader_type,
|
||||||
GstGLTextureTarget from, GstGLTextureTarget to, GstGLAPI gl_api,
|
GstGLTextureTarget from, GstGLTextureTarget to, GstGLContext * context,
|
||||||
gint gl_major, gint gl_minor, GstGLSLVersion * version,
|
GstGLSLVersion * version, GstGLSLProfile * profile)
|
||||||
GstGLSLProfile * profile)
|
|
||||||
{
|
{
|
||||||
gchar *tmp, *tmp2;
|
gchar *tmp, *tmp2;
|
||||||
|
|
||||||
_init_debug ();
|
_init_debug ();
|
||||||
|
|
||||||
_mangle_version_profile_from_gl_api (gl_api, gl_major, gl_minor, version,
|
g_return_val_if_fail (GST_IS_GL_CONTEXT (context), NULL);
|
||||||
profile);
|
|
||||||
tmp = _mangle_texture_access (str, from, to, gl_api, gl_major, gl_minor);
|
_mangle_version_profile_from_gl_api (context, from, to, version, profile);
|
||||||
|
tmp2 =
|
||||||
|
_mangle_external_image_extension (str, context, from, to, *version,
|
||||||
|
*profile);
|
||||||
|
tmp = _mangle_texture_access (tmp2, context, from, to, *version, *profile);
|
||||||
|
g_free (tmp2);
|
||||||
tmp2 = _mangle_sampler_type (tmp, from, to);
|
tmp2 = _mangle_sampler_type (tmp, from, to);
|
||||||
g_free (tmp);
|
g_free (tmp);
|
||||||
tmp =
|
tmp = _mangle_varying_attribute (tmp2, shader_type, *version, *profile);
|
||||||
_mangle_varying_attribute (tmp2, shader_type, gl_api, gl_major, gl_minor);
|
|
||||||
g_free (tmp2);
|
g_free (tmp2);
|
||||||
if (shader_type == GL_FRAGMENT_SHADER) {
|
if (shader_type == GL_FRAGMENT_SHADER) {
|
||||||
if ((*profile == GST_GLSL_PROFILE_ES && *version >= GST_GLSL_VERSION_300)
|
if ((*profile == GST_GLSL_PROFILE_ES && *version >= GST_GLSL_VERSION_300)
|
||||||
|
|
|
@ -60,8 +60,7 @@ G_GNUC_INTERNAL const gchar * _gst_glsl_shader_string_find_version (const gchar
|
||||||
|
|
||||||
G_GNUC_INTERNAL gchar *
|
G_GNUC_INTERNAL gchar *
|
||||||
_gst_glsl_mangle_shader (const gchar * str, guint shader_type, GstGLTextureTarget from,
|
_gst_glsl_mangle_shader (const gchar * str, guint shader_type, GstGLTextureTarget from,
|
||||||
GstGLTextureTarget to, GstGLAPI gl_api, gint gl_major, gint gl_minor,
|
GstGLTextureTarget to, GstGLContext * context, GstGLSLVersion * version, GstGLSLProfile * profile);
|
||||||
GstGLSLVersion * version, GstGLSLProfile * profile);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -1457,7 +1457,6 @@ _init_view_convert_fbo (GstGLViewConvert * viewconvert)
|
||||||
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;
|
||||||
|
@ -1574,8 +1573,8 @@ _get_shader_string (GstGLViewConvert * viewconvert, GstGLShader * shader,
|
||||||
|
|
||||||
tmp2 =
|
tmp2 =
|
||||||
_gst_glsl_mangle_shader (tmp, GL_FRAGMENT_SHADER,
|
_gst_glsl_mangle_shader (tmp, GL_FRAGMENT_SHADER,
|
||||||
GST_GL_TEXTURE_TARGET_2D, viewconvert->from_texture_target, gl_api,
|
GST_GL_TEXTURE_TARGET_2D, viewconvert->from_texture_target,
|
||||||
gl_major, gl_minor, &version, &profile);
|
viewconvert->context, &version, &profile);
|
||||||
|
|
||||||
return tmp2;
|
return tmp2;
|
||||||
}
|
}
|
||||||
|
@ -1730,21 +1729,16 @@ _init_view_convert (GstGLViewConvert * viewconvert)
|
||||||
{
|
{
|
||||||
GstGLSLVersion version;
|
GstGLSLVersion version;
|
||||||
GstGLSLProfile profile;
|
GstGLSLProfile profile;
|
||||||
GstGLAPI gl_api;
|
|
||||||
gint gl_major, gl_minor;
|
|
||||||
GstGLSLStage *vert, *frag;
|
GstGLSLStage *vert, *frag;
|
||||||
gchar *tmp, *tmp1, *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);
|
|
||||||
gst_gl_context_get_gl_version (viewconvert->context, &gl_major, &gl_minor);
|
|
||||||
|
|
||||||
tmp =
|
tmp =
|
||||||
_gst_glsl_mangle_shader
|
_gst_glsl_mangle_shader
|
||||||
(gst_gl_shader_string_vertex_mat4_vertex_transform, GL_VERTEX_SHADER,
|
(gst_gl_shader_string_vertex_mat4_vertex_transform, GL_VERTEX_SHADER,
|
||||||
GST_GL_TEXTURE_TARGET_2D, viewconvert->from_texture_target, gl_api,
|
GST_GL_TEXTURE_TARGET_2D, viewconvert->from_texture_target,
|
||||||
gl_major, gl_minor, &version, &profile);
|
viewconvert->context, &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);
|
||||||
|
@ -1767,7 +1761,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, gl_api, gl_major, gl_minor, version, profile);
|
in_mode, out_mode, version, profile);
|
||||||
strings[1] = fragment_source_str;
|
strings[1] = fragment_source_str;
|
||||||
|
|
||||||
frag =
|
frag =
|
||||||
|
|
Loading…
Reference in a new issue