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 ShInitBuiltInResources(&resources
);
23 resources
.MaxExpressionComplexity
= 32;
24 resources
.MaxCallStackDepth
= 32;
26 vertex_translator_
= new ShaderTranslator();
27 fragment_translator_
= new ShaderTranslator();
29 ASSERT_TRUE(vertex_translator_
->Init(
30 SH_VERTEX_SHADER
, SH_GLES2_SPEC
, &resources
,
31 ShaderTranslatorInterface::kGlsl
,
32 SH_EMULATE_BUILT_IN_FUNCTIONS
));
33 ASSERT_TRUE(fragment_translator_
->Init(
34 SH_FRAGMENT_SHADER
, SH_GLES2_SPEC
, &resources
,
35 ShaderTranslatorInterface::kGlsl
,
36 static_cast<ShCompileOptions
>(0)));
37 // Post-init the results must be empty.
38 // Vertex translator results.
39 EXPECT_TRUE(vertex_translator_
->translated_shader() == NULL
);
40 EXPECT_TRUE(vertex_translator_
->info_log() == NULL
);
41 EXPECT_TRUE(vertex_translator_
->attrib_map().empty());
42 EXPECT_TRUE(vertex_translator_
->uniform_map().empty());
43 // Fragment translator results.
44 EXPECT_TRUE(fragment_translator_
->translated_shader() == NULL
);
45 EXPECT_TRUE(fragment_translator_
->info_log() == NULL
);
46 EXPECT_TRUE(fragment_translator_
->attrib_map().empty());
47 EXPECT_TRUE(fragment_translator_
->uniform_map().empty());
49 virtual void TearDown() {
50 vertex_translator_
= NULL
;
51 fragment_translator_
= NULL
;
54 scoped_refptr
<ShaderTranslator
> vertex_translator_
;
55 scoped_refptr
<ShaderTranslator
> fragment_translator_
;
58 TEST_F(ShaderTranslatorTest
, ValidVertexShader
) {
61 " gl_Position = vec4(1.0);\n"
64 // A valid shader should be successfully translated.
65 EXPECT_TRUE(vertex_translator_
->Translate(shader
));
66 // Info log must be NULL.
67 EXPECT_TRUE(vertex_translator_
->info_log() == NULL
);
68 // Translated shader must be valid and non-empty.
69 ASSERT_TRUE(vertex_translator_
->translated_shader() != NULL
);
70 EXPECT_GT(strlen(vertex_translator_
->translated_shader()), 0u);
71 // There should be no attributes or uniforms.
72 EXPECT_TRUE(vertex_translator_
->attrib_map().empty());
73 EXPECT_TRUE(vertex_translator_
->uniform_map().empty());
76 TEST_F(ShaderTranslatorTest
, InvalidVertexShader
) {
77 const char* bad_shader
= "foo-bar";
78 const char* good_shader
=
80 " gl_Position = vec4(1.0);\n"
83 // An invalid shader should fail.
84 EXPECT_FALSE(vertex_translator_
->Translate(bad_shader
));
85 // Info log must be valid and non-empty.
86 ASSERT_TRUE(vertex_translator_
->info_log() != NULL
);
87 EXPECT_GT(strlen(vertex_translator_
->info_log()), 0u);
88 // Translated shader must be NULL.
89 EXPECT_TRUE(vertex_translator_
->translated_shader() == NULL
);
90 // There should be no attributes or uniforms.
91 EXPECT_TRUE(vertex_translator_
->attrib_map().empty());
92 EXPECT_TRUE(vertex_translator_
->uniform_map().empty());
94 // Try a good shader after bad.
95 EXPECT_TRUE(vertex_translator_
->Translate(good_shader
));
96 EXPECT_TRUE(vertex_translator_
->info_log() == NULL
);
97 ASSERT_TRUE(vertex_translator_
->translated_shader() != NULL
);
98 EXPECT_GT(strlen(vertex_translator_
->translated_shader()), 0u);
101 TEST_F(ShaderTranslatorTest
, ValidFragmentShader
) {
104 " gl_FragColor = vec4(1.0);\n"
107 // A valid shader should be successfully translated.
108 EXPECT_TRUE(fragment_translator_
->Translate(shader
));
109 // Info log must be NULL.
110 EXPECT_TRUE(fragment_translator_
->info_log() == NULL
);
111 // Translated shader must be valid and non-empty.
112 ASSERT_TRUE(fragment_translator_
->translated_shader() != NULL
);
113 EXPECT_GT(strlen(fragment_translator_
->translated_shader()), 0u);
114 // There should be no attributes or uniforms.
115 EXPECT_TRUE(fragment_translator_
->attrib_map().empty());
116 EXPECT_TRUE(fragment_translator_
->uniform_map().empty());
119 TEST_F(ShaderTranslatorTest
, InvalidFragmentShader
) {
120 const char* shader
= "foo-bar";
122 // An invalid shader should fail.
123 EXPECT_FALSE(fragment_translator_
->Translate(shader
));
124 // Info log must be valid and non-empty.
125 ASSERT_TRUE(fragment_translator_
->info_log() != NULL
);
126 EXPECT_GT(strlen(fragment_translator_
->info_log()), 0u);
127 // Translated shader must be NULL.
128 EXPECT_TRUE(fragment_translator_
->translated_shader() == NULL
);
129 // There should be no attributes or uniforms.
130 EXPECT_TRUE(fragment_translator_
->attrib_map().empty());
131 EXPECT_TRUE(fragment_translator_
->uniform_map().empty());
134 TEST_F(ShaderTranslatorTest
, GetAttributes
) {
136 "attribute vec4 vPosition;\n"
138 " gl_Position = vPosition;\n"
141 EXPECT_TRUE(vertex_translator_
->Translate(shader
));
142 // Info log must be NULL.
143 EXPECT_TRUE(vertex_translator_
->info_log() == NULL
);
144 // Translated shader must be valid and non-empty.
145 ASSERT_TRUE(vertex_translator_
->translated_shader() != NULL
);
146 EXPECT_GT(strlen(vertex_translator_
->translated_shader()), 0u);
147 // There should be no uniforms.
148 EXPECT_TRUE(vertex_translator_
->uniform_map().empty());
149 // There should be one attribute with following characteristics:
150 // name:vPosition type:SH_FLOAT_VEC4 size:1.
151 const ShaderTranslator::VariableMap
& attrib_map
=
152 vertex_translator_
->attrib_map();
153 EXPECT_EQ(1u, attrib_map
.size());
154 ShaderTranslator::VariableMap::const_iterator iter
=
155 attrib_map
.find("vPosition");
156 EXPECT_TRUE(iter
!= attrib_map
.end());
157 EXPECT_EQ(SH_FLOAT_VEC4
, iter
->second
.type
);
158 EXPECT_EQ(1, iter
->second
.size
);
159 EXPECT_EQ("vPosition", iter
->second
.name
);
162 TEST_F(ShaderTranslatorTest
, GetUniforms
) {
164 "precision mediump float;\n"
171 "uniform Bar bar[2];\n"
173 " gl_FragColor = bar[0].foo.color[0] + bar[1].foo.color[0];\n"
176 EXPECT_TRUE(fragment_translator_
->Translate(shader
));
177 // Info log must be NULL.
178 EXPECT_TRUE(fragment_translator_
->info_log() == NULL
);
179 // Translated shader must be valid and non-empty.
180 ASSERT_TRUE(fragment_translator_
->translated_shader() != NULL
);
181 EXPECT_GT(strlen(fragment_translator_
->translated_shader()), 0u);
182 // There should be no attributes.
183 EXPECT_TRUE(fragment_translator_
->attrib_map().empty());
184 // There should be two uniforms with following characteristics:
185 // 1. name:bar[0].foo.color[0] type:SH_FLOAT_VEC4 size:1
186 // 2. name:bar[1].foo.color[0] type:SH_FLOAT_VEC4 size:1
187 const ShaderTranslator::VariableMap
& uniform_map
=
188 fragment_translator_
->uniform_map();
189 EXPECT_EQ(2u, uniform_map
.size());
191 ShaderTranslator::VariableMap::const_iterator iter
=
192 uniform_map
.find("bar[0].foo.color[0]");
193 EXPECT_TRUE(iter
!= uniform_map
.end());
194 EXPECT_EQ(SH_FLOAT_VEC4
, iter
->second
.type
);
195 EXPECT_EQ(1, iter
->second
.size
);
196 EXPECT_EQ("bar[0].foo.color[0]", iter
->second
.name
);
198 iter
= uniform_map
.find("bar[1].foo.color[0]");
199 EXPECT_TRUE(iter
!= uniform_map
.end());
200 EXPECT_EQ(SH_FLOAT_VEC4
, iter
->second
.type
);
201 EXPECT_EQ(1, iter
->second
.size
);
202 EXPECT_EQ("bar[1].foo.color[0]", iter
->second
.name
);
205 #if defined(OS_MACOSX)
206 TEST_F(ShaderTranslatorTest
, BuiltInFunctionEmulation
) {
207 // This test might become invalid in the future when ANGLE Translator is no
208 // longer emulate dot(float, float) in Mac, or the emulated function name is
209 // no longer webgl_dot_emu.
212 " gl_Position = vec4(dot(1.0, 1.0), 1.0, 1.0, 1.0);\n"
215 EXPECT_TRUE(vertex_translator_
->Translate(shader
));
216 // Info log must be NULL.
217 EXPECT_TRUE(vertex_translator_
->info_log() == NULL
);
218 // Translated shader must be valid and non-empty.
219 ASSERT_TRUE(vertex_translator_
->translated_shader() != NULL
);
220 EXPECT_TRUE(strstr(vertex_translator_
->translated_shader(),
221 "webgl_dot_emu") != NULL
);
225 TEST_F(ShaderTranslatorTest
, OptionsString
) {
226 scoped_refptr
<ShaderTranslator
> translator_1
= new ShaderTranslator();
227 scoped_refptr
<ShaderTranslator
> translator_2
= new ShaderTranslator();
228 scoped_refptr
<ShaderTranslator
> translator_3
= new ShaderTranslator();
230 ShBuiltInResources resources
;
231 ShInitBuiltInResources(&resources
);
233 ASSERT_TRUE(translator_1
->Init(
234 SH_VERTEX_SHADER
, SH_GLES2_SPEC
, &resources
,
235 ShaderTranslatorInterface::kGlsl
,
236 SH_EMULATE_BUILT_IN_FUNCTIONS
));
237 ASSERT_TRUE(translator_2
->Init(
238 SH_FRAGMENT_SHADER
, SH_GLES2_SPEC
, &resources
,
239 ShaderTranslatorInterface::kGlsl
,
240 static_cast<ShCompileOptions
>(0)));
241 resources
.EXT_draw_buffers
= 1;
242 ASSERT_TRUE(translator_3
->Init(
243 SH_VERTEX_SHADER
, SH_GLES2_SPEC
, &resources
,
244 ShaderTranslatorInterface::kGlsl
,
245 SH_EMULATE_BUILT_IN_FUNCTIONS
));
247 std::string
options_1(
248 translator_1
->GetStringForOptionsThatWouldAffectCompilation());
249 std::string
options_2(
250 translator_1
->GetStringForOptionsThatWouldAffectCompilation());
251 std::string
options_3(
252 translator_2
->GetStringForOptionsThatWouldAffectCompilation());
253 std::string
options_4(
254 translator_3
->GetStringForOptionsThatWouldAffectCompilation());
256 EXPECT_EQ(options_1
, options_2
);
257 EXPECT_NE(options_1
, options_3
);
258 EXPECT_NE(options_1
, options_4
);
259 EXPECT_NE(options_3
, options_4
);