Fix crash in SpeechRecognizerImpl introduced in AudioParams refactor.
[chromium-blink-merge.git] / gpu / command_buffer / service / shader_translator_unittest.cc
blob0c60b44c5a63853badb359d0a7f8618be4249c97
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <GLES2/gl2.h>
7 #include "gpu/command_buffer/service/shader_translator.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "ui/gl/gl_version_info.h"
11 namespace gpu {
12 namespace gles2 {
14 class ShaderTranslatorTest : public testing::Test {
15 public:
16 ShaderTranslatorTest() {
17 shader_output_language_ =
18 ShaderTranslator::GetShaderOutputLanguageForContext(
19 gfx::GLVersionInfo("2.0", "", ""));
22 ~ShaderTranslatorTest() override {}
24 protected:
25 void SetUp() override {
26 ShBuiltInResources resources;
27 ShInitBuiltInResources(&resources);
28 resources.MaxExpressionComplexity = 32;
29 resources.MaxCallStackDepth = 32;
31 vertex_translator_ = new ShaderTranslator();
32 fragment_translator_ = new ShaderTranslator();
34 ASSERT_TRUE(vertex_translator_->Init(GL_VERTEX_SHADER, SH_GLES2_SPEC,
35 &resources, shader_output_language_,
36 SH_EMULATE_BUILT_IN_FUNCTIONS));
37 ASSERT_TRUE(fragment_translator_->Init(GL_FRAGMENT_SHADER, SH_GLES2_SPEC,
38 &resources, shader_output_language_,
39 static_cast<ShCompileOptions>(0)));
41 void TearDown() override {
42 vertex_translator_ = NULL;
43 fragment_translator_ = NULL;
46 scoped_refptr<ShaderTranslator> vertex_translator_;
47 scoped_refptr<ShaderTranslator> fragment_translator_;
48 ShShaderOutput shader_output_language_;
51 TEST_F(ShaderTranslatorTest, ValidVertexShader) {
52 const char* shader =
53 "void main() {\n"
54 " gl_Position = vec4(1.0);\n"
55 "}";
57 // A valid shader should be successfully translated.
58 std::string info_log, translated_source;
59 int shader_version;
60 AttributeMap attrib_map;
61 UniformMap uniform_map;
62 VaryingMap varying_map;
63 NameMap name_map;
64 EXPECT_TRUE(vertex_translator_->Translate(shader,
65 &info_log,
66 &translated_source,
67 &shader_version,
68 &attrib_map,
69 &uniform_map,
70 &varying_map,
71 &name_map));
72 // Info log must be NULL.
73 EXPECT_TRUE(info_log.empty());
74 // Translated shader must be valid and non-empty.
75 ASSERT_FALSE(translated_source.empty());
76 // There should be no attributes, uniforms, and only one built-in
77 // varying: gl_Position.
78 EXPECT_TRUE(attrib_map.empty());
79 EXPECT_TRUE(uniform_map.empty());
80 EXPECT_EQ(1u, varying_map.size());
81 // There should be no name mapping.
82 EXPECT_TRUE(name_map.empty());
85 TEST_F(ShaderTranslatorTest, InvalidVertexShader) {
86 const char* bad_shader = "foo-bar";
87 const char* good_shader =
88 "void main() {\n"
89 " gl_Position = vec4(1.0);\n"
90 "}";
92 // An invalid shader should fail.
93 std::string info_log, translated_source;
94 int shader_version;
95 AttributeMap attrib_map;
96 UniformMap uniform_map;
97 VaryingMap varying_map;
98 NameMap name_map;
99 EXPECT_FALSE(vertex_translator_->Translate(bad_shader,
100 &info_log,
101 &translated_source,
102 &shader_version,
103 &attrib_map,
104 &uniform_map,
105 &varying_map,
106 &name_map));
107 // Info log must be valid and non-empty.
108 ASSERT_FALSE(info_log.empty());
109 // Translated shader must be NULL.
110 EXPECT_TRUE(translated_source.empty());
111 // There should be no attributes, uniforms, varyings, or name mapping.
112 EXPECT_TRUE(attrib_map.empty());
113 EXPECT_TRUE(uniform_map.empty());
114 EXPECT_TRUE(varying_map.empty());
115 EXPECT_TRUE(name_map.empty());
117 // Try a good shader after bad.
118 info_log.clear();
119 EXPECT_TRUE(vertex_translator_->Translate(good_shader,
120 &info_log,
121 &translated_source,
122 &shader_version,
123 &attrib_map,
124 &uniform_map,
125 &varying_map,
126 &name_map));
127 EXPECT_TRUE(info_log.empty());
128 EXPECT_FALSE(translated_source.empty());
131 TEST_F(ShaderTranslatorTest, ValidFragmentShader) {
132 const char* shader =
133 "void main() {\n"
134 " gl_FragColor = vec4(1.0);\n"
135 "}";
137 // A valid shader should be successfully translated.
138 std::string info_log, translated_source;
139 int shader_version;
140 AttributeMap attrib_map;
141 UniformMap uniform_map;
142 VaryingMap varying_map;
143 NameMap name_map;
144 EXPECT_TRUE(fragment_translator_->Translate(shader,
145 &info_log,
146 &translated_source,
147 &shader_version,
148 &attrib_map,
149 &uniform_map,
150 &varying_map,
151 &name_map));
152 // Info log must be NULL.
153 EXPECT_TRUE(info_log.empty());
154 // Translated shader must be valid and non-empty.
155 ASSERT_FALSE(translated_source.empty());
156 // There should be no attributes, uniforms, varyings, or name mapping.
157 EXPECT_TRUE(attrib_map.empty());
158 EXPECT_TRUE(uniform_map.empty());
159 EXPECT_TRUE(varying_map.empty());
160 EXPECT_TRUE(name_map.empty());
163 TEST_F(ShaderTranslatorTest, InvalidFragmentShader) {
164 const char* shader = "foo-bar";
166 std::string info_log, translated_source;
167 int shader_version;
168 AttributeMap attrib_map;
169 UniformMap uniform_map;
170 VaryingMap varying_map;
171 NameMap name_map;
172 // An invalid shader should fail.
173 EXPECT_FALSE(fragment_translator_->Translate(shader,
174 &info_log,
175 &translated_source,
176 &shader_version,
177 &attrib_map,
178 &uniform_map,
179 &varying_map,
180 &name_map));
181 // Info log must be valid and non-empty.
182 EXPECT_FALSE(info_log.empty());
183 // Translated shader must be NULL.
184 EXPECT_TRUE(translated_source.empty());
185 // There should be no attributes or uniforms.
186 EXPECT_TRUE(attrib_map.empty());
187 EXPECT_TRUE(uniform_map.empty());
188 EXPECT_TRUE(varying_map.empty());
189 EXPECT_TRUE(name_map.empty());
192 TEST_F(ShaderTranslatorTest, GetAttributes) {
193 const char* shader =
194 "attribute vec4 vPosition;\n"
195 "void main() {\n"
196 " gl_Position = vPosition;\n"
197 "}";
199 std::string info_log, translated_source;
200 int shader_version;
201 AttributeMap attrib_map;
202 UniformMap uniform_map;
203 VaryingMap varying_map;
204 NameMap name_map;
205 EXPECT_TRUE(vertex_translator_->Translate(shader,
206 &info_log,
207 &translated_source,
208 &shader_version,
209 &attrib_map,
210 &uniform_map,
211 &varying_map,
212 &name_map));
213 // Info log must be NULL.
214 EXPECT_TRUE(info_log.empty());
215 // Translated shader must be valid and non-empty.
216 EXPECT_FALSE(translated_source.empty());
217 // There should be no uniforms.
218 EXPECT_TRUE(uniform_map.empty());
219 // There should be one attribute with following characteristics:
220 // name:vPosition type:GL_FLOAT_VEC4 size:0.
221 EXPECT_EQ(1u, attrib_map.size());
222 AttributeMap::const_iterator iter = attrib_map.find("vPosition");
223 EXPECT_TRUE(iter != attrib_map.end());
224 EXPECT_EQ(static_cast<GLenum>(GL_FLOAT_VEC4), iter->second.type);
225 EXPECT_EQ(0u, iter->second.arraySize);
226 EXPECT_EQ("vPosition", iter->second.name);
229 TEST_F(ShaderTranslatorTest, GetUniforms) {
230 const char* shader =
231 "precision mediump float;\n"
232 "struct Foo {\n"
233 " vec4 color[1];\n"
234 "};\n"
235 "struct Bar {\n"
236 " Foo foo;\n"
237 "};\n"
238 "uniform Bar bar[2];\n"
239 "void main() {\n"
240 " gl_FragColor = bar[0].foo.color[0] + bar[1].foo.color[0];\n"
241 "}";
243 std::string info_log, translated_source;
244 int shader_version;
245 AttributeMap attrib_map;
246 UniformMap uniform_map;
247 VaryingMap varying_map;
248 NameMap name_map;
249 EXPECT_TRUE(fragment_translator_->Translate(shader,
250 &info_log,
251 &translated_source,
252 &shader_version,
253 &attrib_map,
254 &uniform_map,
255 &varying_map,
256 &name_map));
257 // Info log must be NULL.
258 EXPECT_TRUE(info_log.empty());
259 // Translated shader must be valid and non-empty.
260 EXPECT_FALSE(translated_source.empty());
261 // There should be no attributes.
262 EXPECT_TRUE(attrib_map.empty());
263 // There should be two uniforms with following characteristics:
264 // 1. name:bar[0].foo.color[0] type:GL_FLOAT_VEC4 size:1
265 // 2. name:bar[1].foo.color[0] type:GL_FLOAT_VEC4 size:1
266 // However, there will be only one entry "bar" in the map.
267 EXPECT_EQ(1u, uniform_map.size());
268 UniformMap::const_iterator iter = uniform_map.find("bar");
269 EXPECT_TRUE(iter != uniform_map.end());
270 // First uniform.
271 const sh::ShaderVariable* info;
272 std::string original_name;
273 EXPECT_TRUE(iter->second.findInfoByMappedName(
274 "bar[0].foo.color[0]", &info, &original_name));
275 EXPECT_EQ(static_cast<GLenum>(GL_FLOAT_VEC4), info->type);
276 EXPECT_EQ(1u, info->arraySize);
277 EXPECT_STREQ("color", info->name.c_str());
278 EXPECT_STREQ("bar[0].foo.color[0]", original_name.c_str());
279 // Second uniform.
280 EXPECT_TRUE(iter->second.findInfoByMappedName(
281 "bar[1].foo.color[0]", &info, &original_name));
282 EXPECT_EQ(static_cast<GLenum>(GL_FLOAT_VEC4), info->type);
283 EXPECT_EQ(1u, info->arraySize);
284 EXPECT_STREQ("color", info->name.c_str());
285 EXPECT_STREQ("bar[1].foo.color[0]", original_name.c_str());
288 TEST_F(ShaderTranslatorTest, OptionsString) {
289 scoped_refptr<ShaderTranslator> translator_1 = new ShaderTranslator();
290 scoped_refptr<ShaderTranslator> translator_2 = new ShaderTranslator();
291 scoped_refptr<ShaderTranslator> translator_3 = new ShaderTranslator();
293 ShBuiltInResources resources;
294 ShInitBuiltInResources(&resources);
296 ASSERT_TRUE(translator_1->Init(GL_VERTEX_SHADER, SH_GLES2_SPEC, &resources,
297 SH_GLSL_150_CORE_OUTPUT,
298 SH_EMULATE_BUILT_IN_FUNCTIONS));
299 ASSERT_TRUE(translator_2->Init(GL_FRAGMENT_SHADER, SH_GLES2_SPEC, &resources,
300 SH_GLSL_150_CORE_OUTPUT,
301 static_cast<ShCompileOptions>(0)));
302 resources.EXT_draw_buffers = 1;
303 ASSERT_TRUE(translator_3->Init(GL_VERTEX_SHADER, SH_GLES2_SPEC, &resources,
304 SH_GLSL_150_CORE_OUTPUT,
305 SH_EMULATE_BUILT_IN_FUNCTIONS));
307 std::string options_1(
308 translator_1->GetStringForOptionsThatWouldAffectCompilation());
309 std::string options_2(
310 translator_1->GetStringForOptionsThatWouldAffectCompilation());
311 std::string options_3(
312 translator_2->GetStringForOptionsThatWouldAffectCompilation());
313 std::string options_4(
314 translator_3->GetStringForOptionsThatWouldAffectCompilation());
316 EXPECT_EQ(options_1, options_2);
317 EXPECT_NE(options_1, options_3);
318 EXPECT_NE(options_1, options_4);
319 EXPECT_NE(options_3, options_4);
322 class ShaderTranslatorOutputVersionTest
323 : public testing::TestWithParam<testing::tuple<const char*, const char*>> {
326 TEST_P(ShaderTranslatorOutputVersionTest, HasCorrectOutputGLSLVersion) {
327 // Test that translating to a shader targeting certain OpenGL context version
328 // (version string in test param tuple index 0) produces a GLSL shader that
329 // contains correct version string for that context (version directive
330 // in test param tuple index 1).
332 const char* kShader =
333 "attribute vec4 vPosition;\n"
334 "void main() {\n"
335 " gl_Position = vPosition;\n"
336 "}";
338 gfx::GLVersionInfo output_context_version(testing::get<0>(GetParam()), "",
339 "");
341 scoped_refptr<ShaderTranslator> translator = new ShaderTranslator();
342 ShBuiltInResources resources;
343 ShInitBuiltInResources(&resources);
344 ShCompileOptions compile_options = SH_OBJECT_CODE;
345 ShShaderOutput shader_output_language =
346 ShaderTranslator::GetShaderOutputLanguageForContext(
347 output_context_version);
348 ASSERT_TRUE(translator->Init(GL_VERTEX_SHADER, SH_GLES2_SPEC, &resources,
349 shader_output_language, compile_options));
351 std::string translated_source;
352 int shader_version;
353 EXPECT_TRUE(translator->Translate(kShader, nullptr, &translated_source,
354 &shader_version, nullptr, nullptr, nullptr,
355 nullptr));
357 std::string expected_version_directive = testing::get<1>(GetParam());
358 if (expected_version_directive.empty()) {
359 EXPECT_TRUE(translated_source.find("#version") == std::string::npos)
360 << "Translation was:\n" << translated_source;
361 } else {
362 EXPECT_TRUE(translated_source.find(expected_version_directive) !=
363 std::string::npos)
364 << "Translation was:\n" << translated_source;
368 // For some compilers, using make_tuple("a", "bb") would end up
369 // instantiating make_tuple<char[1], char[2]>. This does not work.
370 namespace {
371 testing::tuple<const char*, const char*> make_gl_glsl_tuple(
372 const char* gl_version,
373 const char* glsl_version_directive) {
374 return testing::make_tuple(gl_version, glsl_version_directive);
378 // Test data for the above test. OpenGL specifications specify a
379 // certain version of GLSL to be guaranteed to be supported. Test
380 // that ShaderTranslator produces a GLSL shader with the exact
381 // specified GLSL version for each known OpenGL version.
382 INSTANTIATE_TEST_CASE_P(
383 KnownOpenGLContexts,
384 ShaderTranslatorOutputVersionTest,
385 testing::Values(make_gl_glsl_tuple("4.5", "#version 450\n"),
386 make_gl_glsl_tuple("4.4", "#version 440\n"),
387 make_gl_glsl_tuple("4.3", "#version 430\n"),
388 make_gl_glsl_tuple("4.2", "#version 420\n"),
389 make_gl_glsl_tuple("4.1", "#version 410\n"),
390 make_gl_glsl_tuple("4.0", "#version 400\n"),
391 make_gl_glsl_tuple("3.3", "#version 330\n"),
392 make_gl_glsl_tuple("3.2", "#version 150\n"),
393 make_gl_glsl_tuple("3.1", "#version 140\n"),
394 make_gl_glsl_tuple("3.0", "#version 130\n")));
396 // Test data for the above test. Check that early OpenGL contexts get
397 // GLSL compatibility profile shader, e.g. shader has no #version
398 // directive. Also check that future version 3.3+ OpenGL contexts get
399 // similar shader. We do not expect that future 3.3+ specs contain
400 // the "all eariler GLSL versions" clause, since 3.3 did not contain
401 // it either.
402 INSTANTIATE_TEST_CASE_P(OldOrUnknownOpenGLContexts,
403 ShaderTranslatorOutputVersionTest,
404 testing::Values(make_gl_glsl_tuple("3.4", ""),
405 make_gl_glsl_tuple("2.0", "")));
407 // Test data for the above test. Cases for the future OpenGL versions. The
408 // code assumes that the future OpenGL specs specify the clause that all
409 // earlier GLSL versions are supported. We select the highest GLSL
410 // version known at the time of writing.
411 INSTANTIATE_TEST_CASE_P(
412 BackwardsCompatibleFutureOpenGLContexts,
413 ShaderTranslatorOutputVersionTest,
414 testing::Values(make_gl_glsl_tuple("5.0", "#version 450\n"),
415 make_gl_glsl_tuple("4.6", "#version 450\n")));
417 // Test data for the above test. Check that for the OpenGL ES output
418 // contexts, the shader is such that GLSL 1.0 is used. The translator
419 // selects GLSL 1.0 by not output any version at the moment, though we
420 // do not know if that would be correct for the future OpenGL ES specs.
421 INSTANTIATE_TEST_CASE_P(OpenGLESContexts,
422 ShaderTranslatorOutputVersionTest,
423 testing::Values(make_gl_glsl_tuple("opengl es 2.0", ""),
424 make_gl_glsl_tuple("opengl es 3.0", ""),
425 make_gl_glsl_tuple("opengl es 3.1", ""),
426 make_gl_glsl_tuple("opengl es 3.2",
427 "")));
429 } // namespace gles2
430 } // namespace gpu