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 "gpu/command_buffer/service/shader_translator.h"
6 #include "testing/gtest/include/gtest/gtest.h"
11 class ShaderTranslatorTest : public testing::Test {
13 ShaderTranslatorTest() {
16 virtual ~ShaderTranslatorTest() {
20 virtual void SetUp() {
21 ShBuiltInResources resources;
22 resources.MaxExpressionComplexity = 32;
23 resources.MaxCallStackDepth = 32;
24 ShInitBuiltInResources(&resources);
25 vertex_translator_ = new ShaderTranslator();
26 fragment_translator_ = new ShaderTranslator();
28 ASSERT_TRUE(vertex_translator_->Init(
29 SH_VERTEX_SHADER, SH_GLES2_SPEC, &resources,
30 ShaderTranslatorInterface::kGlsl,
31 SH_EMULATE_BUILT_IN_FUNCTIONS));
32 ASSERT_TRUE(fragment_translator_->Init(
33 SH_FRAGMENT_SHADER, SH_GLES2_SPEC, &resources,
34 ShaderTranslatorInterface::kGlsl,
35 static_cast<ShCompileOptions>(0)));
36 // Post-init the results must be empty.
37 // Vertex translator results.
38 EXPECT_TRUE(vertex_translator_->translated_shader() == NULL);
39 EXPECT_TRUE(vertex_translator_->info_log() == NULL);
40 EXPECT_TRUE(vertex_translator_->attrib_map().empty());
41 EXPECT_TRUE(vertex_translator_->uniform_map().empty());
42 // Fragment translator results.
43 EXPECT_TRUE(fragment_translator_->translated_shader() == NULL);
44 EXPECT_TRUE(fragment_translator_->info_log() == NULL);
45 EXPECT_TRUE(fragment_translator_->attrib_map().empty());
46 EXPECT_TRUE(fragment_translator_->uniform_map().empty());
48 virtual void TearDown() {
49 vertex_translator_ = NULL;
50 fragment_translator_ = NULL;
53 scoped_refptr<ShaderTranslator> vertex_translator_;
54 scoped_refptr<ShaderTranslator> fragment_translator_;
57 TEST_F(ShaderTranslatorTest, ValidVertexShader) {
60 " gl_Position = vec4(1.0);\n"
63 // A valid shader should be successfully translated.
64 EXPECT_TRUE(vertex_translator_->Translate(shader));
65 // Info log must be NULL.
66 EXPECT_TRUE(vertex_translator_->info_log() == NULL);
67 // Translated shader must be valid and non-empty.
68 ASSERT_TRUE(vertex_translator_->translated_shader() != NULL);
69 EXPECT_GT(strlen(vertex_translator_->translated_shader()), 0u);
70 // There should be no attributes or uniforms.
71 EXPECT_TRUE(vertex_translator_->attrib_map().empty());
72 EXPECT_TRUE(vertex_translator_->uniform_map().empty());
75 TEST_F(ShaderTranslatorTest, InvalidVertexShader) {
76 const char* bad_shader = "foo-bar";
77 const char* good_shader =
79 " gl_Position = vec4(1.0);\n"
82 // An invalid shader should fail.
83 EXPECT_FALSE(vertex_translator_->Translate(bad_shader));
84 // Info log must be valid and non-empty.
85 ASSERT_TRUE(vertex_translator_->info_log() != NULL);
86 EXPECT_GT(strlen(vertex_translator_->info_log()), 0u);
87 // Translated shader must be NULL.
88 EXPECT_TRUE(vertex_translator_->translated_shader() == NULL);
89 // There should be no attributes or uniforms.
90 EXPECT_TRUE(vertex_translator_->attrib_map().empty());
91 EXPECT_TRUE(vertex_translator_->uniform_map().empty());
93 // Try a good shader after bad.
94 EXPECT_TRUE(vertex_translator_->Translate(good_shader));
95 EXPECT_TRUE(vertex_translator_->info_log() == NULL);
96 ASSERT_TRUE(vertex_translator_->translated_shader() != NULL);
97 EXPECT_GT(strlen(vertex_translator_->translated_shader()), 0u);
100 TEST_F(ShaderTranslatorTest, ValidFragmentShader) {
103 " gl_FragColor = vec4(1.0);\n"
106 // A valid shader should be successfully translated.
107 EXPECT_TRUE(fragment_translator_->Translate(shader));
108 // Info log must be NULL.
109 EXPECT_TRUE(fragment_translator_->info_log() == NULL);
110 // Translated shader must be valid and non-empty.
111 ASSERT_TRUE(fragment_translator_->translated_shader() != NULL);
112 EXPECT_GT(strlen(fragment_translator_->translated_shader()), 0u);
113 // There should be no attributes or uniforms.
114 EXPECT_TRUE(fragment_translator_->attrib_map().empty());
115 EXPECT_TRUE(fragment_translator_->uniform_map().empty());
118 TEST_F(ShaderTranslatorTest, InvalidFragmentShader) {
119 const char* shader = "foo-bar";
121 // An invalid shader should fail.
122 EXPECT_FALSE(fragment_translator_->Translate(shader));
123 // Info log must be valid and non-empty.
124 ASSERT_TRUE(fragment_translator_->info_log() != NULL);
125 EXPECT_GT(strlen(fragment_translator_->info_log()), 0u);
126 // Translated shader must be NULL.
127 EXPECT_TRUE(fragment_translator_->translated_shader() == NULL);
128 // There should be no attributes or uniforms.
129 EXPECT_TRUE(fragment_translator_->attrib_map().empty());
130 EXPECT_TRUE(fragment_translator_->uniform_map().empty());
133 TEST_F(ShaderTranslatorTest, GetAttributes) {
135 "attribute vec4 vPosition;\n"
137 " gl_Position = vPosition;\n"
140 EXPECT_TRUE(vertex_translator_->Translate(shader));
141 // Info log must be NULL.
142 EXPECT_TRUE(vertex_translator_->info_log() == NULL);
143 // Translated shader must be valid and non-empty.
144 ASSERT_TRUE(vertex_translator_->translated_shader() != NULL);
145 EXPECT_GT(strlen(vertex_translator_->translated_shader()), 0u);
146 // There should be no uniforms.
147 EXPECT_TRUE(vertex_translator_->uniform_map().empty());
148 // There should be one attribute with following characteristics:
149 // name:vPosition type:SH_FLOAT_VEC4 size:1.
150 const ShaderTranslator::VariableMap& attrib_map =
151 vertex_translator_->attrib_map();
152 EXPECT_EQ(1u, attrib_map.size());
153 ShaderTranslator::VariableMap::const_iterator iter =
154 attrib_map.find("vPosition");
155 EXPECT_TRUE(iter != attrib_map.end());
156 EXPECT_EQ(SH_FLOAT_VEC4, iter->second.type);
157 EXPECT_EQ(1, iter->second.size);
158 EXPECT_EQ("vPosition", iter->second.name);
161 TEST_F(ShaderTranslatorTest, GetUniforms) {
163 "precision mediump float;\n"
170 "uniform Bar bar[2];\n"
172 " gl_FragColor = bar[0].foo.color[0] + bar[1].foo.color[0];\n"
175 EXPECT_TRUE(fragment_translator_->Translate(shader));
176 // Info log must be NULL.
177 EXPECT_TRUE(fragment_translator_->info_log() == NULL);
178 // Translated shader must be valid and non-empty.
179 ASSERT_TRUE(fragment_translator_->translated_shader() != NULL);
180 EXPECT_GT(strlen(fragment_translator_->translated_shader()), 0u);
181 // There should be no attributes.
182 EXPECT_TRUE(fragment_translator_->attrib_map().empty());
183 // There should be two uniforms with following characteristics:
184 // 1. name:bar[0].foo.color[0] type:SH_FLOAT_VEC4 size:1
185 // 2. name:bar[1].foo.color[0] type:SH_FLOAT_VEC4 size:1
186 const ShaderTranslator::VariableMap& uniform_map =
187 fragment_translator_->uniform_map();
188 EXPECT_EQ(2u, uniform_map.size());
190 ShaderTranslator::VariableMap::const_iterator iter =
191 uniform_map.find("bar[0].foo.color[0]");
192 EXPECT_TRUE(iter != uniform_map.end());
193 EXPECT_EQ(SH_FLOAT_VEC4, iter->second.type);
194 EXPECT_EQ(1, iter->second.size);
195 EXPECT_EQ("bar[0].foo.color[0]", iter->second.name);
197 iter = uniform_map.find("bar[1].foo.color[0]");
198 EXPECT_TRUE(iter != uniform_map.end());
199 EXPECT_EQ(SH_FLOAT_VEC4, iter->second.type);
200 EXPECT_EQ(1, iter->second.size);
201 EXPECT_EQ("bar[1].foo.color[0]", iter->second.name);
204 #if defined(OS_MACOSX)
205 TEST_F(ShaderTranslatorTest, BuiltInFunctionEmulation) {
206 // This test might become invalid in the future when ANGLE Translator is no
207 // longer emulate dot(float, float) in Mac, or the emulated function name is
208 // no longer webgl_dot_emu.
211 " gl_Position = vec4(dot(1.0, 1.0), 1.0, 1.0, 1.0);\n"
214 EXPECT_TRUE(vertex_translator_->Translate(shader));
215 // Info log must be NULL.
216 EXPECT_TRUE(vertex_translator_->info_log() == NULL);
217 // Translated shader must be valid and non-empty.
218 ASSERT_TRUE(vertex_translator_->translated_shader() != NULL);
219 EXPECT_TRUE(strstr(vertex_translator_->translated_shader(),
220 "webgl_dot_emu") != NULL);
224 TEST_F(ShaderTranslatorTest, OptionsString) {
225 scoped_refptr<ShaderTranslator> translator_1 = new ShaderTranslator();
226 scoped_refptr<ShaderTranslator> translator_2 = new ShaderTranslator();
227 scoped_refptr<ShaderTranslator> translator_3 = new ShaderTranslator();
229 ShBuiltInResources resources;
230 ShInitBuiltInResources(&resources);
232 ASSERT_TRUE(translator_1->Init(
233 SH_VERTEX_SHADER, SH_GLES2_SPEC, &resources,
234 ShaderTranslatorInterface::kGlsl,
235 SH_EMULATE_BUILT_IN_FUNCTIONS));
236 ASSERT_TRUE(translator_2->Init(
237 SH_FRAGMENT_SHADER, SH_GLES2_SPEC, &resources,
238 ShaderTranslatorInterface::kGlsl,
239 static_cast<ShCompileOptions>(0)));
240 resources.EXT_draw_buffers = 1;
241 ASSERT_TRUE(translator_3->Init(
242 SH_VERTEX_SHADER, SH_GLES2_SPEC, &resources,
243 ShaderTranslatorInterface::kGlsl,
244 SH_EMULATE_BUILT_IN_FUNCTIONS));
246 std::string options_1(
247 translator_1->GetStringForOptionsThatWouldEffectCompilation());
248 std::string options_2(
249 translator_1->GetStringForOptionsThatWouldEffectCompilation());
250 std::string options_3(
251 translator_2->GetStringForOptionsThatWouldEffectCompilation());
252 std::string options_4(
253 translator_3->GetStringForOptionsThatWouldEffectCompilation());
255 EXPECT_EQ(options_1, options_2);
256 EXPECT_NE(options_1, options_3);
257 EXPECT_NE(options_1, options_4);
258 EXPECT_NE(options_3, options_4);