diff options
Diffstat (limited to 'chromium/gpu/command_buffer/service/shader_translator_unittest.cc')
-rw-r--r-- | chromium/gpu/command_buffer/service/shader_translator_unittest.cc | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/chromium/gpu/command_buffer/service/shader_translator_unittest.cc b/chromium/gpu/command_buffer/service/shader_translator_unittest.cc new file mode 100644 index 00000000000..a08851adcf8 --- /dev/null +++ b/chromium/gpu/command_buffer/service/shader_translator_unittest.cc @@ -0,0 +1,263 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "gpu/command_buffer/service/shader_translator.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace gpu { +namespace gles2 { + +class ShaderTranslatorTest : public testing::Test { + public: + ShaderTranslatorTest() { + } + + virtual ~ShaderTranslatorTest() { + } + + protected: + virtual void SetUp() { + ShBuiltInResources resources; + resources.MaxExpressionComplexity = 32; + resources.MaxCallStackDepth = 32; + ShInitBuiltInResources(&resources); + vertex_translator_ = new ShaderTranslator(); + fragment_translator_ = new ShaderTranslator(); + + ASSERT_TRUE(vertex_translator_->Init( + SH_VERTEX_SHADER, SH_GLES2_SPEC, &resources, + ShaderTranslatorInterface::kGlsl, + ShaderTranslatorInterface::kGlslBuiltInFunctionEmulated)); + ASSERT_TRUE(fragment_translator_->Init( + SH_FRAGMENT_SHADER, SH_GLES2_SPEC, &resources, + ShaderTranslatorInterface::kGlsl, + ShaderTranslatorInterface::kGlslBuiltInFunctionOriginal)); + // Post-init the results must be empty. + // Vertex translator results. + EXPECT_TRUE(vertex_translator_->translated_shader() == NULL); + EXPECT_TRUE(vertex_translator_->info_log() == NULL); + EXPECT_TRUE(vertex_translator_->attrib_map().empty()); + EXPECT_TRUE(vertex_translator_->uniform_map().empty()); + // Fragment translator results. + EXPECT_TRUE(fragment_translator_->translated_shader() == NULL); + EXPECT_TRUE(fragment_translator_->info_log() == NULL); + EXPECT_TRUE(fragment_translator_->attrib_map().empty()); + EXPECT_TRUE(fragment_translator_->uniform_map().empty()); + } + virtual void TearDown() { + vertex_translator_ = NULL; + fragment_translator_ = NULL; + } + + scoped_refptr<ShaderTranslator> vertex_translator_; + scoped_refptr<ShaderTranslator> fragment_translator_; +}; + +TEST_F(ShaderTranslatorTest, ValidVertexShader) { + const char* shader = + "void main() {\n" + " gl_Position = vec4(1.0);\n" + "}"; + + // A valid shader should be successfully translated. + EXPECT_TRUE(vertex_translator_->Translate(shader)); + // Info log must be NULL. + EXPECT_TRUE(vertex_translator_->info_log() == NULL); + // Translated shader must be valid and non-empty. + ASSERT_TRUE(vertex_translator_->translated_shader() != NULL); + EXPECT_GT(strlen(vertex_translator_->translated_shader()), 0u); + // There should be no attributes or uniforms. + EXPECT_TRUE(vertex_translator_->attrib_map().empty()); + EXPECT_TRUE(vertex_translator_->uniform_map().empty()); +} + +TEST_F(ShaderTranslatorTest, InvalidVertexShader) { + const char* bad_shader = "foo-bar"; + const char* good_shader = + "void main() {\n" + " gl_Position = vec4(1.0);\n" + "}"; + + // An invalid shader should fail. + EXPECT_FALSE(vertex_translator_->Translate(bad_shader)); + // Info log must be valid and non-empty. + ASSERT_TRUE(vertex_translator_->info_log() != NULL); + EXPECT_GT(strlen(vertex_translator_->info_log()), 0u); + // Translated shader must be NULL. + EXPECT_TRUE(vertex_translator_->translated_shader() == NULL); + // There should be no attributes or uniforms. + EXPECT_TRUE(vertex_translator_->attrib_map().empty()); + EXPECT_TRUE(vertex_translator_->uniform_map().empty()); + + // Try a good shader after bad. + EXPECT_TRUE(vertex_translator_->Translate(good_shader)); + EXPECT_TRUE(vertex_translator_->info_log() == NULL); + ASSERT_TRUE(vertex_translator_->translated_shader() != NULL); + EXPECT_GT(strlen(vertex_translator_->translated_shader()), 0u); +} + +TEST_F(ShaderTranslatorTest, ValidFragmentShader) { + const char* shader = + "void main() {\n" + " gl_FragColor = vec4(1.0);\n" + "}"; + + // A valid shader should be successfully translated. + EXPECT_TRUE(fragment_translator_->Translate(shader)); + // Info log must be NULL. + EXPECT_TRUE(fragment_translator_->info_log() == NULL); + // Translated shader must be valid and non-empty. + ASSERT_TRUE(fragment_translator_->translated_shader() != NULL); + EXPECT_GT(strlen(fragment_translator_->translated_shader()), 0u); + // There should be no attributes or uniforms. + EXPECT_TRUE(fragment_translator_->attrib_map().empty()); + EXPECT_TRUE(fragment_translator_->uniform_map().empty()); +} + +TEST_F(ShaderTranslatorTest, InvalidFragmentShader) { + const char* shader = "foo-bar"; + + // An invalid shader should fail. + EXPECT_FALSE(fragment_translator_->Translate(shader)); + // Info log must be valid and non-empty. + ASSERT_TRUE(fragment_translator_->info_log() != NULL); + EXPECT_GT(strlen(fragment_translator_->info_log()), 0u); + // Translated shader must be NULL. + EXPECT_TRUE(fragment_translator_->translated_shader() == NULL); + // There should be no attributes or uniforms. + EXPECT_TRUE(fragment_translator_->attrib_map().empty()); + EXPECT_TRUE(fragment_translator_->uniform_map().empty()); +} + +TEST_F(ShaderTranslatorTest, GetAttributes) { + const char* shader = + "attribute vec4 vPosition;\n" + "void main() {\n" + " gl_Position = vPosition;\n" + "}"; + + EXPECT_TRUE(vertex_translator_->Translate(shader)); + // Info log must be NULL. + EXPECT_TRUE(vertex_translator_->info_log() == NULL); + // Translated shader must be valid and non-empty. + ASSERT_TRUE(vertex_translator_->translated_shader() != NULL); + EXPECT_GT(strlen(vertex_translator_->translated_shader()), 0u); + // There should be no uniforms. + EXPECT_TRUE(vertex_translator_->uniform_map().empty()); + // There should be one attribute with following characteristics: + // name:vPosition type:SH_FLOAT_VEC4 size:1. + const ShaderTranslator::VariableMap& attrib_map = + vertex_translator_->attrib_map(); + EXPECT_EQ(1u, attrib_map.size()); + ShaderTranslator::VariableMap::const_iterator iter = + attrib_map.find("vPosition"); + EXPECT_TRUE(iter != attrib_map.end()); + EXPECT_EQ(SH_FLOAT_VEC4, iter->second.type); + EXPECT_EQ(1, iter->second.size); + EXPECT_EQ("vPosition", iter->second.name); +} + +TEST_F(ShaderTranslatorTest, GetUniforms) { + const char* shader = + "precision mediump float;\n" + "struct Foo {\n" + " vec4 color[1];\n" + "};\n" + "struct Bar {\n" + " Foo foo;\n" + "};\n" + "uniform Bar bar[2];\n" + "void main() {\n" + " gl_FragColor = bar[0].foo.color[0] + bar[1].foo.color[0];\n" + "}"; + + EXPECT_TRUE(fragment_translator_->Translate(shader)); + // Info log must be NULL. + EXPECT_TRUE(fragment_translator_->info_log() == NULL); + // Translated shader must be valid and non-empty. + ASSERT_TRUE(fragment_translator_->translated_shader() != NULL); + EXPECT_GT(strlen(fragment_translator_->translated_shader()), 0u); + // There should be no attributes. + EXPECT_TRUE(fragment_translator_->attrib_map().empty()); + // There should be two uniforms with following characteristics: + // 1. name:bar[0].foo.color[0] type:SH_FLOAT_VEC4 size:1 + // 2. name:bar[1].foo.color[0] type:SH_FLOAT_VEC4 size:1 + const ShaderTranslator::VariableMap& uniform_map = + fragment_translator_->uniform_map(); + EXPECT_EQ(2u, uniform_map.size()); + // First uniform. + ShaderTranslator::VariableMap::const_iterator iter = + uniform_map.find("bar[0].foo.color[0]"); + EXPECT_TRUE(iter != uniform_map.end()); + EXPECT_EQ(SH_FLOAT_VEC4, iter->second.type); + EXPECT_EQ(1, iter->second.size); + EXPECT_EQ("bar[0].foo.color[0]", iter->second.name); + // Second uniform. + iter = uniform_map.find("bar[1].foo.color[0]"); + EXPECT_TRUE(iter != uniform_map.end()); + EXPECT_EQ(SH_FLOAT_VEC4, iter->second.type); + EXPECT_EQ(1, iter->second.size); + EXPECT_EQ("bar[1].foo.color[0]", iter->second.name); +} + +#if defined(OS_MACOSX) +TEST_F(ShaderTranslatorTest, BuiltInFunctionEmulation) { + // This test might become invalid in the future when ANGLE Translator is no + // longer emulate dot(float, float) in Mac, or the emulated function name is + // no longer webgl_dot_emu. + const char* shader = + "void main() {\n" + " gl_Position = vec4(dot(1.0, 1.0), 1.0, 1.0, 1.0);\n" + "}"; + + EXPECT_TRUE(vertex_translator_->Translate(shader)); + // Info log must be NULL. + EXPECT_TRUE(vertex_translator_->info_log() == NULL); + // Translated shader must be valid and non-empty. + ASSERT_TRUE(vertex_translator_->translated_shader() != NULL); + EXPECT_TRUE(strstr(vertex_translator_->translated_shader(), + "webgl_dot_emu") != NULL); +} +#endif + +TEST_F(ShaderTranslatorTest, OptionsString) { + scoped_refptr<ShaderTranslator> translator_1 = new ShaderTranslator(); + scoped_refptr<ShaderTranslator> translator_2 = new ShaderTranslator(); + scoped_refptr<ShaderTranslator> translator_3 = new ShaderTranslator(); + + ShBuiltInResources resources; + ShInitBuiltInResources(&resources); + + ASSERT_TRUE(translator_1->Init( + SH_VERTEX_SHADER, SH_GLES2_SPEC, &resources, + ShaderTranslatorInterface::kGlsl, + ShaderTranslatorInterface::kGlslBuiltInFunctionEmulated)); + ASSERT_TRUE(translator_2->Init( + SH_FRAGMENT_SHADER, SH_GLES2_SPEC, &resources, + ShaderTranslatorInterface::kGlsl, + ShaderTranslatorInterface::kGlslBuiltInFunctionOriginal)); + resources.EXT_draw_buffers = 1; + ASSERT_TRUE(translator_3->Init( + SH_VERTEX_SHADER, SH_GLES2_SPEC, &resources, + ShaderTranslatorInterface::kGlsl, + ShaderTranslatorInterface::kGlslBuiltInFunctionEmulated)); + + std::string options_1( + translator_1->GetStringForOptionsThatWouldEffectCompilation()); + std::string options_2( + translator_1->GetStringForOptionsThatWouldEffectCompilation()); + std::string options_3( + translator_2->GetStringForOptionsThatWouldEffectCompilation()); + std::string options_4( + translator_3->GetStringForOptionsThatWouldEffectCompilation()); + + EXPECT_EQ(options_1, options_2); + EXPECT_NE(options_1, options_3); + EXPECT_NE(options_1, options_4); + EXPECT_NE(options_3, options_4); +} + +} // namespace gles2 +} // namespace gpu + |