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.
7 #include "gpu/command_buffer/service/shader_translator.h"
8 #include "testing/gtest/include/gtest/gtest.h"
10 // The ANGLE shader translator now uses native GLenums
11 // TODO(jmadill): delete these defines when the ANGLE
12 // roll reliably passes translator version 126
13 #if (ANGLE_SH_VERSION >= 126)
14 #define SH_VERTEX_SHADER GL_VERTEX_SHADER
15 #define SH_FRAGMENT_SHADER GL_FRAGMENT_SHADER
16 #define SH_FLOAT_VEC4 GL_FLOAT_VEC4
22 class ShaderTranslatorTest
: public testing::Test
{
24 ShaderTranslatorTest() {
27 virtual ~ShaderTranslatorTest() {
31 virtual void SetUp() {
32 ShBuiltInResources resources
;
33 ShInitBuiltInResources(&resources
);
34 resources
.MaxExpressionComplexity
= 32;
35 resources
.MaxCallStackDepth
= 32;
37 vertex_translator_
= new ShaderTranslator();
38 fragment_translator_
= new ShaderTranslator();
40 ASSERT_TRUE(vertex_translator_
->Init(
41 SH_VERTEX_SHADER
, SH_GLES2_SPEC
, &resources
,
42 ShaderTranslatorInterface::kGlsl
,
43 SH_EMULATE_BUILT_IN_FUNCTIONS
));
44 ASSERT_TRUE(fragment_translator_
->Init(
45 SH_FRAGMENT_SHADER
, SH_GLES2_SPEC
, &resources
,
46 ShaderTranslatorInterface::kGlsl
,
47 static_cast<ShCompileOptions
>(0)));
48 // Post-init the results must be empty.
49 // Vertex translator results.
50 EXPECT_TRUE(vertex_translator_
->translated_shader() == NULL
);
51 EXPECT_TRUE(vertex_translator_
->info_log() == NULL
);
52 EXPECT_TRUE(vertex_translator_
->attrib_map().empty());
53 EXPECT_TRUE(vertex_translator_
->uniform_map().empty());
54 // Fragment translator results.
55 EXPECT_TRUE(fragment_translator_
->translated_shader() == NULL
);
56 EXPECT_TRUE(fragment_translator_
->info_log() == NULL
);
57 EXPECT_TRUE(fragment_translator_
->attrib_map().empty());
58 EXPECT_TRUE(fragment_translator_
->uniform_map().empty());
60 virtual void TearDown() {
61 vertex_translator_
= NULL
;
62 fragment_translator_
= NULL
;
65 scoped_refptr
<ShaderTranslator
> vertex_translator_
;
66 scoped_refptr
<ShaderTranslator
> fragment_translator_
;
69 TEST_F(ShaderTranslatorTest
, ValidVertexShader
) {
72 " gl_Position = vec4(1.0);\n"
75 // A valid shader should be successfully translated.
76 EXPECT_TRUE(vertex_translator_
->Translate(shader
));
77 // Info log must be NULL.
78 EXPECT_TRUE(vertex_translator_
->info_log() == NULL
);
79 // Translated shader must be valid and non-empty.
80 ASSERT_TRUE(vertex_translator_
->translated_shader() != NULL
);
81 EXPECT_GT(strlen(vertex_translator_
->translated_shader()), 0u);
82 // There should be no attributes or uniforms.
83 EXPECT_TRUE(vertex_translator_
->attrib_map().empty());
84 EXPECT_TRUE(vertex_translator_
->uniform_map().empty());
87 TEST_F(ShaderTranslatorTest
, InvalidVertexShader
) {
88 const char* bad_shader
= "foo-bar";
89 const char* good_shader
=
91 " gl_Position = vec4(1.0);\n"
94 // An invalid shader should fail.
95 EXPECT_FALSE(vertex_translator_
->Translate(bad_shader
));
96 // Info log must be valid and non-empty.
97 ASSERT_TRUE(vertex_translator_
->info_log() != NULL
);
98 EXPECT_GT(strlen(vertex_translator_
->info_log()), 0u);
99 // Translated shader must be NULL.
100 EXPECT_TRUE(vertex_translator_
->translated_shader() == NULL
);
101 // There should be no attributes or uniforms.
102 EXPECT_TRUE(vertex_translator_
->attrib_map().empty());
103 EXPECT_TRUE(vertex_translator_
->uniform_map().empty());
105 // Try a good shader after bad.
106 EXPECT_TRUE(vertex_translator_
->Translate(good_shader
));
107 EXPECT_TRUE(vertex_translator_
->info_log() == NULL
);
108 ASSERT_TRUE(vertex_translator_
->translated_shader() != NULL
);
109 EXPECT_GT(strlen(vertex_translator_
->translated_shader()), 0u);
112 TEST_F(ShaderTranslatorTest
, ValidFragmentShader
) {
115 " gl_FragColor = vec4(1.0);\n"
118 // A valid shader should be successfully translated.
119 EXPECT_TRUE(fragment_translator_
->Translate(shader
));
120 // Info log must be NULL.
121 EXPECT_TRUE(fragment_translator_
->info_log() == NULL
);
122 // Translated shader must be valid and non-empty.
123 ASSERT_TRUE(fragment_translator_
->translated_shader() != NULL
);
124 EXPECT_GT(strlen(fragment_translator_
->translated_shader()), 0u);
125 // There should be no attributes or uniforms.
126 EXPECT_TRUE(fragment_translator_
->attrib_map().empty());
127 EXPECT_TRUE(fragment_translator_
->uniform_map().empty());
130 TEST_F(ShaderTranslatorTest
, InvalidFragmentShader
) {
131 const char* shader
= "foo-bar";
133 // An invalid shader should fail.
134 EXPECT_FALSE(fragment_translator_
->Translate(shader
));
135 // Info log must be valid and non-empty.
136 ASSERT_TRUE(fragment_translator_
->info_log() != NULL
);
137 EXPECT_GT(strlen(fragment_translator_
->info_log()), 0u);
138 // Translated shader must be NULL.
139 EXPECT_TRUE(fragment_translator_
->translated_shader() == NULL
);
140 // There should be no attributes or uniforms.
141 EXPECT_TRUE(fragment_translator_
->attrib_map().empty());
142 EXPECT_TRUE(fragment_translator_
->uniform_map().empty());
145 TEST_F(ShaderTranslatorTest
, GetAttributes
) {
147 "attribute vec4 vPosition;\n"
149 " gl_Position = vPosition;\n"
152 EXPECT_TRUE(vertex_translator_
->Translate(shader
));
153 // Info log must be NULL.
154 EXPECT_TRUE(vertex_translator_
->info_log() == NULL
);
155 // Translated shader must be valid and non-empty.
156 ASSERT_TRUE(vertex_translator_
->translated_shader() != NULL
);
157 EXPECT_GT(strlen(vertex_translator_
->translated_shader()), 0u);
158 // There should be no uniforms.
159 EXPECT_TRUE(vertex_translator_
->uniform_map().empty());
160 // There should be one attribute with following characteristics:
161 // name:vPosition type:SH_FLOAT_VEC4 size:1.
162 const ShaderTranslator::VariableMap
& attrib_map
=
163 vertex_translator_
->attrib_map();
164 EXPECT_EQ(1u, attrib_map
.size());
165 ShaderTranslator::VariableMap::const_iterator iter
=
166 attrib_map
.find("vPosition");
167 EXPECT_TRUE(iter
!= attrib_map
.end());
168 EXPECT_EQ(SH_FLOAT_VEC4
, iter
->second
.type
);
169 EXPECT_EQ(1, iter
->second
.size
);
170 EXPECT_EQ("vPosition", iter
->second
.name
);
173 TEST_F(ShaderTranslatorTest
, GetUniforms
) {
175 "precision mediump float;\n"
182 "uniform Bar bar[2];\n"
184 " gl_FragColor = bar[0].foo.color[0] + bar[1].foo.color[0];\n"
187 EXPECT_TRUE(fragment_translator_
->Translate(shader
));
188 // Info log must be NULL.
189 EXPECT_TRUE(fragment_translator_
->info_log() == NULL
);
190 // Translated shader must be valid and non-empty.
191 ASSERT_TRUE(fragment_translator_
->translated_shader() != NULL
);
192 EXPECT_GT(strlen(fragment_translator_
->translated_shader()), 0u);
193 // There should be no attributes.
194 EXPECT_TRUE(fragment_translator_
->attrib_map().empty());
195 // There should be two uniforms with following characteristics:
196 // 1. name:bar[0].foo.color[0] type:SH_FLOAT_VEC4 size:1
197 // 2. name:bar[1].foo.color[0] type:SH_FLOAT_VEC4 size:1
198 const ShaderTranslator::VariableMap
& uniform_map
=
199 fragment_translator_
->uniform_map();
200 EXPECT_EQ(2u, uniform_map
.size());
202 ShaderTranslator::VariableMap::const_iterator iter
=
203 uniform_map
.find("bar[0].foo.color[0]");
204 EXPECT_TRUE(iter
!= uniform_map
.end());
205 EXPECT_EQ(SH_FLOAT_VEC4
, iter
->second
.type
);
206 EXPECT_EQ(1, iter
->second
.size
);
207 EXPECT_EQ("bar[0].foo.color[0]", iter
->second
.name
);
209 iter
= uniform_map
.find("bar[1].foo.color[0]");
210 EXPECT_TRUE(iter
!= uniform_map
.end());
211 EXPECT_EQ(SH_FLOAT_VEC4
, iter
->second
.type
);
212 EXPECT_EQ(1, iter
->second
.size
);
213 EXPECT_EQ("bar[1].foo.color[0]", iter
->second
.name
);
216 #if defined(OS_MACOSX)
217 TEST_F(ShaderTranslatorTest
, BuiltInFunctionEmulation
) {
218 // This test might become invalid in the future when ANGLE Translator is no
219 // longer emulate dot(float, float) in Mac, or the emulated function name is
220 // no longer webgl_dot_emu.
223 " gl_Position = vec4(dot(1.0, 1.0), 1.0, 1.0, 1.0);\n"
226 EXPECT_TRUE(vertex_translator_
->Translate(shader
));
227 // Info log must be NULL.
228 EXPECT_TRUE(vertex_translator_
->info_log() == NULL
);
229 // Translated shader must be valid and non-empty.
230 ASSERT_TRUE(vertex_translator_
->translated_shader() != NULL
);
231 EXPECT_TRUE(strstr(vertex_translator_
->translated_shader(),
232 "webgl_dot_emu") != NULL
);
236 TEST_F(ShaderTranslatorTest
, OptionsString
) {
237 scoped_refptr
<ShaderTranslator
> translator_1
= new ShaderTranslator();
238 scoped_refptr
<ShaderTranslator
> translator_2
= new ShaderTranslator();
239 scoped_refptr
<ShaderTranslator
> translator_3
= new ShaderTranslator();
241 ShBuiltInResources resources
;
242 ShInitBuiltInResources(&resources
);
244 ASSERT_TRUE(translator_1
->Init(
245 SH_VERTEX_SHADER
, SH_GLES2_SPEC
, &resources
,
246 ShaderTranslatorInterface::kGlsl
,
247 SH_EMULATE_BUILT_IN_FUNCTIONS
));
248 ASSERT_TRUE(translator_2
->Init(
249 SH_FRAGMENT_SHADER
, SH_GLES2_SPEC
, &resources
,
250 ShaderTranslatorInterface::kGlsl
,
251 static_cast<ShCompileOptions
>(0)));
252 resources
.EXT_draw_buffers
= 1;
253 ASSERT_TRUE(translator_3
->Init(
254 SH_VERTEX_SHADER
, SH_GLES2_SPEC
, &resources
,
255 ShaderTranslatorInterface::kGlsl
,
256 SH_EMULATE_BUILT_IN_FUNCTIONS
));
258 std::string
options_1(
259 translator_1
->GetStringForOptionsThatWouldAffectCompilation());
260 std::string
options_2(
261 translator_1
->GetStringForOptionsThatWouldAffectCompilation());
262 std::string
options_3(
263 translator_2
->GetStringForOptionsThatWouldAffectCompilation());
264 std::string
options_4(
265 translator_3
->GetStringForOptionsThatWouldAffectCompilation());
267 EXPECT_EQ(options_1
, options_2
);
268 EXPECT_NE(options_1
, options_3
);
269 EXPECT_NE(options_1
, options_4
);
270 EXPECT_NE(options_3
, options_4
);