From: Matthew Waters Date: Wed, 15 Jun 2016 02:47:05 +0000 (+1000) Subject: glsl: fixup external-oes shaders by mangling the required extension X-Git-Tag: 1.19.3~511^2~1989^2~305 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=dfd6565b4be5917f45ea7822a0dbffaac0cd127c;p=platform%2Fupstream%2Fgstreamer.git 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 --- diff --git a/gst-libs/gst/gl/gstglcolorconvert.c b/gst-libs/gst/gl/gstglcolorconvert.c index ba717fa..c518bc9 100644 --- a/gst-libs/gst/gl/gstglcolorconvert.c +++ b/gst-libs/gst/gl/gstglcolorconvert.c @@ -1723,19 +1723,14 @@ _create_shader (GstGLColorConvert * convert) gchar *version_str, *tmp, *tmp1; const gchar *strings[2]; GError *error = NULL; - GstGLAPI gl_api; - gint gl_major, gl_minor; 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); tmp = _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); + info->templ->target, convert->priv->from_texture_target, convert->context, + &version, &profile); tmp1 = gst_glsl_version_profile_to_string (version, profile); version_str = g_strdup_printf ("#version %s\n", tmp1); @@ -1842,8 +1837,8 @@ _create_shader (GstGLColorConvert * convert) g_string_append (str, "\n}"); tmp = g_string_free (str, FALSE); 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); + info->templ->target, convert->priv->from_texture_target, convert->context, + &version, &profile); g_free (tmp); strings[1] = info->frag_prog; diff --git a/gst-libs/gst/gl/gstglsl.c b/gst-libs/gst/gl/gstglsl.c index dca6edf..e3fe9c5 100644 --- a/gst-libs/gst/gl/gstglsl.c +++ b/gst-libs/gst/gl/gstglsl.c @@ -594,10 +594,51 @@ _gst_glsl_funcs_fill (GstGLSLFuncs * vtable, GstGLContext * context) 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 * -_mangle_texture_access (const gchar * str, GstGLTextureTarget from, - GstGLTextureTarget to, GstGLAPI gl_api, guint gl_major, guint gl_minor) +_mangle_texture_access (const gchar * str, GstGLContext * context, + GstGLTextureTarget from, GstGLTextureTarget to, GstGLSLVersion version, + GstGLSLProfile profile) { const gchar *from_str = NULL, *to_str = NULL; gchar *ret, *tmp; @@ -611,8 +652,12 @@ _mangle_texture_access (const gchar * str, GstGLTextureTarget from, 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)) { + /* GL3 || gles3 but not when external-oes unless the image_external_essl3 extension is supported */ + 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"; } else { if (to == GST_GL_TEXTURE_TARGET_2D) @@ -684,11 +729,11 @@ _mangle_sampler_type (const gchar * str, GstGLTextureTarget from, static gchar * _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 ((gl_api & GST_GL_API_OPENGL3) || (gl_api & GST_GL_API_GLES2 - && gl_major >= 3)) { + if (profile == GST_GLSL_PROFILE_CORE || (profile == GST_GLSL_PROFILE_ES + && version >= GST_GLSL_VERSION_300)) { gchar *tmp, *tmp2; GRegex *regex; @@ -706,8 +751,8 @@ _mangle_varying_attribute (const gchar * str, guint shader_type, 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)) { + if (profile == GST_GLSL_PROFILE_CORE || (profile == GST_GLSL_PROFILE_ES + && version >= GST_GLSL_VERSION_300)) { gchar *tmp; GRegex *regex; @@ -743,9 +788,16 @@ _mangle_frag_color_data (const gchar * str) } static void -_mangle_version_profile_from_gl_api (GstGLAPI gl_api, gint gl_major, - gint gl_minor, GstGLSLVersion * version, GstGLSLProfile * profile) +_mangle_version_profile_from_gl_api (GstGLContext * context, + 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; *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; } } 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; *profile = GST_GLSL_PROFILE_ES; } else if (gl_major >= 2) { @@ -773,21 +829,24 @@ _mangle_version_profile_from_gl_api (GstGLAPI gl_api, gint gl_major, 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) + GstGLTextureTarget from, GstGLTextureTarget to, GstGLContext * context, + GstGLSLVersion * version, GstGLSLProfile * profile) { gchar *tmp, *tmp2; _init_debug (); - _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); + g_return_val_if_fail (GST_IS_GL_CONTEXT (context), NULL); + + _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); g_free (tmp); - tmp = - _mangle_varying_attribute (tmp2, shader_type, gl_api, gl_major, gl_minor); + tmp = _mangle_varying_attribute (tmp2, shader_type, *version, *profile); g_free (tmp2); if (shader_type == GL_FRAGMENT_SHADER) { if ((*profile == GST_GLSL_PROFILE_ES && *version >= GST_GLSL_VERSION_300) diff --git a/gst-libs/gst/gl/gstglsl_private.h b/gst-libs/gst/gl/gstglsl_private.h index 49c6b38..755170d 100644 --- a/gst-libs/gst/gl/gstglsl_private.h +++ b/gst-libs/gst/gl/gstglsl_private.h @@ -60,8 +60,7 @@ G_GNUC_INTERNAL const gchar * _gst_glsl_shader_string_find_version (const gchar 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); + GstGLTextureTarget to, GstGLContext * context, GstGLSLVersion * version, GstGLSLProfile * profile); G_END_DECLS diff --git a/gst-libs/gst/gl/gstglviewconvert.c b/gst-libs/gst/gl/gstglviewconvert.c index ff770af..2fcbb81 100644 --- a/gst-libs/gst/gl/gstglviewconvert.c +++ b/gst-libs/gst/gl/gstglviewconvert.c @@ -1457,7 +1457,6 @@ _init_view_convert_fbo (GstGLViewConvert * viewconvert) 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; @@ -1574,8 +1573,8 @@ _get_shader_string (GstGLViewConvert * viewconvert, GstGLShader * shader, 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); + GST_GL_TEXTURE_TARGET_2D, viewconvert->from_texture_target, + viewconvert->context, &version, &profile); return tmp2; } @@ -1730,21 +1729,16 @@ _init_view_convert (GstGLViewConvert * viewconvert) { GstGLSLVersion version; GstGLSLProfile profile; - GstGLAPI gl_api; - gint gl_major, gl_minor; GstGLSLStage *vert, *frag; 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); - tmp = _gst_glsl_mangle_shader (gst_gl_shader_string_vertex_mat4_vertex_transform, GL_VERTEX_SHADER, - GST_GL_TEXTURE_TARGET_2D, viewconvert->from_texture_target, gl_api, - gl_major, gl_minor, &version, &profile); + GST_GL_TEXTURE_TARGET_2D, viewconvert->from_texture_target, + viewconvert->context, &version, &profile); tmp1 = gst_glsl_version_profile_to_string (version, profile); 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, - in_mode, out_mode, gl_api, gl_major, gl_minor, version, profile); + in_mode, out_mode, version, profile); strings[1] = fragment_source_str; frag =