- add sources.
[platform/framework/web/crosswalk.git] / src / gpu / command_buffer / service / shader_translator_unittest.cc
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.
4
5 #include "gpu/command_buffer/service/shader_translator.h"
6 #include "testing/gtest/include/gtest/gtest.h"
7
8 namespace gpu {
9 namespace gles2 {
10
11 class ShaderTranslatorTest : public testing::Test {
12  public:
13   ShaderTranslatorTest() {
14   }
15
16   virtual ~ShaderTranslatorTest() {
17   }
18
19  protected:
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();
27
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());
47   }
48   virtual void TearDown() {
49     vertex_translator_ = NULL;
50     fragment_translator_ = NULL;
51   }
52
53   scoped_refptr<ShaderTranslator> vertex_translator_;
54   scoped_refptr<ShaderTranslator> fragment_translator_;
55 };
56
57 TEST_F(ShaderTranslatorTest, ValidVertexShader) {
58   const char* shader =
59       "void main() {\n"
60       "  gl_Position = vec4(1.0);\n"
61       "}";
62
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());
73 }
74
75 TEST_F(ShaderTranslatorTest, InvalidVertexShader) {
76   const char* bad_shader = "foo-bar";
77   const char* good_shader =
78       "void main() {\n"
79       "  gl_Position = vec4(1.0);\n"
80       "}";
81
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());
92
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);
98 }
99
100 TEST_F(ShaderTranslatorTest, ValidFragmentShader) {
101   const char* shader =
102       "void main() {\n"
103       "  gl_FragColor = vec4(1.0);\n"
104       "}";
105
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());
116 }
117
118 TEST_F(ShaderTranslatorTest, InvalidFragmentShader) {
119   const char* shader = "foo-bar";
120
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());
131 }
132
133 TEST_F(ShaderTranslatorTest, GetAttributes) {
134   const char* shader =
135       "attribute vec4 vPosition;\n"
136       "void main() {\n"
137       "  gl_Position = vPosition;\n"
138       "}";
139
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);
159 }
160
161 TEST_F(ShaderTranslatorTest, GetUniforms) {
162   const char* shader =
163       "precision mediump float;\n"
164       "struct Foo {\n"
165       "  vec4 color[1];\n"
166       "};\n"
167       "struct Bar {\n"
168       "  Foo foo;\n"
169       "};\n"
170       "uniform Bar bar[2];\n"
171       "void main() {\n"
172       "  gl_FragColor = bar[0].foo.color[0] + bar[1].foo.color[0];\n"
173       "}";
174
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());
189   // First uniform.
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);
196   // Second uniform.
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);
202 }
203
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.
209   const char* shader =
210       "void main() {\n"
211       "  gl_Position = vec4(dot(1.0, 1.0), 1.0, 1.0, 1.0);\n"
212       "}";
213
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);
221 }
222 #endif
223
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();
228
229   ShBuiltInResources resources;
230   ShInitBuiltInResources(&resources);
231
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));
245
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());
254
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);
259 }
260
261 }  // namespace gles2
262 }  // namespace gpu
263