]> code.ossystems Code Review - openembedded-core.git/blob
31d8e052fdb659a193346cd464bd0460d3745270
[openembedded-core.git] /
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
5  GLES3
6
7 There are numerous slight differences required between Desktop GL and GLES3 for
8 multiple render targets.
9
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
14
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.
19
20 Upstream-Status: Backport [1.9.1]
21
22 ---
23  gst-libs/gst/gl/gstglcolorconvert.c | 125 ++++++++++++++++++++++++++++--------
24  1 file changed, 99 insertions(+), 26 deletions(-)
25
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,
31  
32  static gchar *
33  _mangle_varying_attribute (const gchar * str, guint shader_type,
34 -    GstGLAPI gl_api)
35 +    GstGLAPI gl_api, guint gl_major, guint gl_minor)
36  {
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)) {
42        gchar *tmp, *tmp2;
43        GRegex *regex;
44  
45 @@ -1821,7 +1822,10 @@ _mangle_varying_attribute (const gchar * str, guint shader_type,
46  
47        g_free (tmp);
48        return tmp2;
49 -    } else if (shader_type == GL_FRAGMENT_SHADER) {
50 +    }
51 +  } else if (shader_type == GL_FRAGMENT_SHADER) {
52 +    if ((gl_api & GST_GL_API_OPENGL3) || (gl_api & GST_GL_API_GLES2
53 +            && gl_major > 3)) {
54        gchar *tmp;
55        GRegex *regex;
56  
57 @@ -1837,28 +1841,48 @@ _mangle_varying_attribute (const gchar * str, guint shader_type,
58  }
59  
60  static gchar *
61 -_mangle_frag_color (const gchar * str)
62 +_mangle_frag_color_data (const gchar * str)
63  {
64    GRegex *regex;
65 -  gchar *ret;
66 +  gchar *ret, *tmp;
67  
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);
71  
72 +  tmp = ret;
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);
77 +  g_free (tmp);
78 +
79    return ret;
80  }
81  
82  static void
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)
87  {
88 +  *version = GST_GLSL_VERSION_NONE;
89 +  *profile = GST_GLSL_PROFILE_NONE;
90 +
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;
97 +    } else {
98 +      *version = GST_GLSL_VERSION_150;
99 +      *profile = GST_GLSL_PROFILE_NONE;
100 +    }
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;
110 +    }
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,
115  
116  static gchar *
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)
122  {
123    gchar *tmp, *tmp2;
124  
125 +  _mangle_version_profile_from_gl_api (gl_api, gl_major, gl_minor, version,
126 +      profile);
127    tmp = _mangle_texture_access (str, from, to, gl_api);
128    tmp2 = _mangle_sampler_type (tmp, from, to);
129    g_free (tmp);
130 -  tmp = _mangle_varying_attribute (tmp2, shader_type, gl_api);
131 +  tmp =
132 +      _mangle_varying_attribute (tmp2, shader_type, gl_api, gl_major, gl_minor);
133    g_free (tmp2);
134 -  if (shader_type == GL_FRAGMENT_SHADER && gl_api & GST_GL_API_OPENGL3) {
135 -    tmp2 = _mangle_frag_color (tmp);
136 -    g_free (tmp);
137 -    tmp = tmp2;
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);
143 +      g_free (tmp);
144 +      tmp = tmp2;
145 +    }
146    }
147 -  _mangle_version_profile_from_gl_api (gl_api, version, profile);
148    return tmp;
149  }
150  
151 @@ -1899,15 +1929,18 @@ _create_shader (GstGLColorConvert * convert)
152    const gchar *strings[2];
153    GError *error = NULL;
154    GstGLAPI gl_api;
155 +  gint gl_major, gl_minor;
156    int i;
157  
158    gl_api = gst_gl_context_get_gl_api (convert->context);
159 +  gst_gl_context_get_gl_version (convert->context, &gl_major, &gl_minor);
160  
161    ret = gst_gl_shader_new (convert->context);
162  
163    tmp =
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,
167 +      &profile);
168  
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);
174  
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');
179 +
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) {
184 +      gint i;
185 +
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);
189 +      }
190 +    } else {
191 +      g_string_append (str, "layout (location = 0) out vec4 fragColor;\n");
192 +    }
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) {
197 +      gint i;
198 +
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);
203 +        g_free (var_name);
204 +      }
205 +    } else {
206 +      g_string_append (str, "out vec4 fragColor;\n");
207 +      gst_gl_shader_bind_frag_data_location (ret, 0, "fragColor");
208 +    }
209    }
210  
211    for (i = 0; i < MAX_FUNCTIONS; i++) {
212 @@ -1959,7 +2020,19 @@ _create_shader (GstGLColorConvert * convert)
213      g_string_append_c (str, '\n');
214    }
215  
216 -  g_string_append (str, "\nvarying vec2 v_texcoord;\nvoid main (void) {\n");
217 +  {
218 +    const gchar *varying = NULL;
219 +
220 +    if ((profile == GST_GLSL_PROFILE_ES && version >= GST_GLSL_VERSION_300)
221 +        || (profile == GST_GLSL_PROFILE_CORE
222 +            && version >= GST_GLSL_VERSION_150)) {
223 +      varying = "in";
224 +    } else {
225 +      varying = "varying";
226 +    }
227 +    g_string_append_printf (str, "\n%s vec2 v_texcoord;\nvoid main (void) {\n",
228 +        varying);
229 +  }
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);
239    g_free (tmp);
240  
241    strings[1] = info->frag_prog;
242 -- 
243 1.9.1
244