1 From 127e517568490fc147211d8b2fb4da01cecbbeb5 Mon Sep 17 00:00:00 2001
2 From: Matthew Waters <matthew@centricular.com>
3 Date: Thu, 31 Mar 2016 19:50:28 +1100
4 Subject: [PATCH 5/6] glcolorconvert: implement multiple render targets for
7 There are numerous slight differences required between Desktop GL and GLES3 for
8 multiple render targets.
10 1. gl_FragData doesn't exist at all and one is required to use
11 'layout (location = ?) out ...' instead.
12 2. gl_FragColor doesn't exist, same as 1
13 3. texture2D() has been deprecated
15 Fortunately most of these have been taken care of with GL3 and the shader
16 mangling already exists so just expand the conditions they are used in. The
17 gl_FragData issue requires a new mangle pass though. We also use this new
18 pass on desktop GL for consistency.
20 Upstream-Status: Backport [1.9.1]
23 gst-libs/gst/gl/gstglcolorconvert.c | 125 ++++++++++++++++++++++++++++--------
24 1 file changed, 99 insertions(+), 26 deletions(-)
26 diff --git a/gst-libs/gst/gl/gstglcolorconvert.c b/gst-libs/gst/gl/gstglcolorconvert.c
27 index 490ec54..f478faa 100644
28 --- a/gst-libs/gst/gl/gstglcolorconvert.c
29 +++ b/gst-libs/gst/gl/gstglcolorconvert.c
30 @@ -1802,10 +1802,11 @@ _mangle_sampler_type (const gchar * str, GstGLTextureTarget from,
33 _mangle_varying_attribute (const gchar * str, guint shader_type,
35 + GstGLAPI gl_api, guint gl_major, guint gl_minor)
37 - if (gl_api & GST_GL_API_OPENGL3) {
38 - if (shader_type == GL_VERTEX_SHADER) {
39 + if (shader_type == GL_VERTEX_SHADER) {
40 + if ((gl_api & GST_GL_API_OPENGL3) || (gl_api & GST_GL_API_GLES2
41 + && gl_major >= 3)) {
45 @@ -1821,7 +1822,10 @@ _mangle_varying_attribute (const gchar * str, guint shader_type,
49 - } else if (shader_type == GL_FRAGMENT_SHADER) {
51 + } else if (shader_type == GL_FRAGMENT_SHADER) {
52 + if ((gl_api & GST_GL_API_OPENGL3) || (gl_api & GST_GL_API_GLES2
57 @@ -1837,28 +1841,48 @@ _mangle_varying_attribute (const gchar * str, guint shader_type,
61 -_mangle_frag_color (const gchar * str)
62 +_mangle_frag_color_data (const gchar * str)
68 regex = g_regex_new ("gl_FragColor", 0, 0, NULL);
69 ret = g_regex_replace_literal (regex, str, -1, 0, "fragColor", 0, NULL);
70 g_regex_unref (regex);
73 + /* search and replace 'gl_FragData[NUM]' into fragColor_NUM */
74 + regex = g_regex_new ("gl_FragData\\[(\\d+)\\]", 0, 0, NULL);
75 + ret = g_regex_replace (regex, tmp, -1, 0, "fragColor_\\1", 0, NULL);
76 + g_regex_unref (regex);
83 -_mangle_version_profile_from_gl_api (GstGLAPI gl_api, GstGLSLVersion * version,
84 - GstGLSLProfile * profile)
85 +_mangle_version_profile_from_gl_api (GstGLAPI gl_api, gint gl_major,
86 + gint gl_minor, GstGLSLVersion * version, GstGLSLProfile * profile)
88 + *version = GST_GLSL_VERSION_NONE;
89 + *profile = GST_GLSL_PROFILE_NONE;
91 if (gl_api & GST_GL_API_OPENGL3) {
92 - *version = GST_GLSL_VERSION_150;
93 - *profile = GST_GLSL_PROFILE_NONE;
94 + if (gl_major > 3 || gl_minor >= 3) {
95 + *version = GST_GLSL_VERSION_330;
96 + *profile = GST_GLSL_PROFILE_CORE;
98 + *version = GST_GLSL_VERSION_150;
99 + *profile = GST_GLSL_PROFILE_NONE;
101 } else if (gl_api & GST_GL_API_GLES2) {
102 - *version = GST_GLSL_VERSION_100;
103 - *profile = GST_GLSL_PROFILE_ES;
104 + if (gl_major >= 3) {
105 + *version = GST_GLSL_VERSION_300;
106 + *profile = GST_GLSL_PROFILE_ES;
107 + } else if (gl_major >= 2) {
108 + *version = GST_GLSL_VERSION_100;
109 + *profile = GST_GLSL_PROFILE_ES;
111 } else if (gl_api & GST_GL_API_OPENGL) {
112 *version = GST_GLSL_VERSION_110;
113 *profile = GST_GLSL_PROFILE_COMPATIBILITY;
114 @@ -1867,22 +1891,28 @@ _mangle_version_profile_from_gl_api (GstGLAPI gl_api, GstGLSLVersion * version,
117 _mangle_shader (const gchar * str, guint shader_type, GstGLTextureTarget from,
118 - GstGLTextureTarget to, GstGLAPI gl_api, GstGLSLVersion * version,
119 - GstGLSLProfile * profile)
120 + GstGLTextureTarget to, GstGLAPI gl_api, gint gl_major, gint gl_minor,
121 + GstGLSLVersion * version, GstGLSLProfile * profile)
125 + _mangle_version_profile_from_gl_api (gl_api, gl_major, gl_minor, version,
127 tmp = _mangle_texture_access (str, from, to, gl_api);
128 tmp2 = _mangle_sampler_type (tmp, from, to);
130 - tmp = _mangle_varying_attribute (tmp2, shader_type, gl_api);
132 + _mangle_varying_attribute (tmp2, shader_type, gl_api, gl_major, gl_minor);
134 - if (shader_type == GL_FRAGMENT_SHADER && gl_api & GST_GL_API_OPENGL3) {
135 - tmp2 = _mangle_frag_color (tmp);
138 + if (shader_type == GL_FRAGMENT_SHADER) {
139 + if ((*profile == GST_GLSL_PROFILE_ES && *version >= GST_GLSL_VERSION_300)
140 + || (*profile == GST_GLSL_PROFILE_CORE
141 + && *version >= GST_GLSL_VERSION_150)) {
142 + tmp2 = _mangle_frag_color_data (tmp);
147 - _mangle_version_profile_from_gl_api (gl_api, version, profile);
151 @@ -1899,15 +1929,18 @@ _create_shader (GstGLColorConvert * convert)
152 const gchar *strings[2];
153 GError *error = NULL;
155 + gint gl_major, gl_minor;
158 gl_api = gst_gl_context_get_gl_api (convert->context);
159 + gst_gl_context_get_gl_version (convert->context, &gl_major, &gl_minor);
161 ret = gst_gl_shader_new (convert->context);
164 _mangle_shader (text_vertex_shader, GL_VERTEX_SHADER, info->templ->target,
165 - convert->priv->from_texture_target, gl_api, &version, &profile);
166 + convert->priv->from_texture_target, gl_api, gl_major, gl_minor, &version,
169 tmp1 = gst_glsl_version_profile_to_string (version, profile);
170 version_str = g_strdup_printf ("#version %s\n", tmp1);
171 @@ -1945,9 +1978,37 @@ _create_shader (GstGLColorConvert * convert)
172 if (info->templ->uniforms)
173 g_string_append (str, info->templ->uniforms);
175 - if (gl_api & GST_GL_API_OPENGL3) {
176 - g_string_append_c (str, '\n');
177 - g_string_append (str, "out vec4 fragColor;\n");
178 + g_string_append_c (str, '\n');
180 + /* GL 3.3+ and GL ES 3.x */
181 + if ((profile == GST_GLSL_PROFILE_CORE && version >= GST_GLSL_VERSION_330)
182 + || (profile == GST_GLSL_PROFILE_ES && version >= GST_GLSL_VERSION_300)) {
183 + if (info->out_n_textures > 1) {
186 + for (i = 0; i < info->out_n_textures; i++) {
187 + g_string_append_printf (str,
188 + "layout(location = %d) out vec4 fragColor_%d;\n", i, i);
191 + g_string_append (str, "layout (location = 0) out vec4 fragColor;\n");
193 + } else if (profile == GST_GLSL_PROFILE_CORE
194 + && version >= GST_GLSL_VERSION_150) {
195 + /* no layout specifiers, use glBindFragDataLocation instead */
196 + if (info->out_n_textures > 1) {
199 + for (i = 0; i < info->out_n_textures; i++) {
200 + gchar *var_name = g_strdup_printf ("fragColor_%d", i);
201 + g_string_append_printf (str, "out vec4 %s;\n", var_name);
202 + gst_gl_shader_bind_frag_data_location (ret, i, var_name);
206 + g_string_append (str, "out vec4 fragColor;\n");
207 + gst_gl_shader_bind_frag_data_location (ret, 0, "fragColor");
211 for (i = 0; i < MAX_FUNCTIONS; i++) {
212 @@ -1959,7 +2020,19 @@ _create_shader (GstGLColorConvert * convert)
213 g_string_append_c (str, '\n');
216 - g_string_append (str, "\nvarying vec2 v_texcoord;\nvoid main (void) {\n");
218 + const gchar *varying = NULL;
220 + if ((profile == GST_GLSL_PROFILE_ES && version >= GST_GLSL_VERSION_300)
221 + || (profile == GST_GLSL_PROFILE_CORE
222 + && version >= GST_GLSL_VERSION_150)) {
225 + varying = "varying";
227 + g_string_append_printf (str, "\n%s vec2 v_texcoord;\nvoid main (void) {\n",
230 if (info->frag_body) {
231 g_string_append (str, "vec2 texcoord;\n");
232 if (convert->priv->from_texture_target == GST_GL_TEXTURE_TARGET_RECTANGLE
233 @@ -1975,7 +2048,7 @@ _create_shader (GstGLColorConvert * convert)
234 tmp = g_string_free (str, FALSE);
235 info->frag_prog = _mangle_shader (tmp, GL_FRAGMENT_SHADER,
236 info->templ->target, convert->priv->from_texture_target, gl_api,
237 - &version, &profile);
238 + gl_major, gl_minor, &version, &profile);
241 strings[1] = info->frag_prog;