Home | History | Annotate | Download | only in service
      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_manager.h"
      6 
      7 #include "base/memory/scoped_ptr.h"
      8 #include "gpu/command_buffer/service/gpu_service_test.h"
      9 #include "gpu/command_buffer/service/mocks.h"
     10 #include "gpu/command_buffer/service/test_helper.h"
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 #include "ui/gl/gl_mock.h"
     13 
     14 using ::testing::Return;
     15 using ::testing::ReturnRef;
     16 
     17 namespace gpu {
     18 namespace gles2 {
     19 
     20 class ShaderManagerTest : public GpuServiceTest {
     21  public:
     22   ShaderManagerTest() {
     23   }
     24 
     25   virtual ~ShaderManagerTest() {
     26     manager_.Destroy(false);
     27   }
     28 
     29  protected:
     30   ShaderManager manager_;
     31 };
     32 
     33 TEST_F(ShaderManagerTest, Basic) {
     34   const GLuint kClient1Id = 1;
     35   const GLuint kService1Id = 11;
     36   const GLenum kShader1Type = GL_VERTEX_SHADER;
     37   const GLuint kClient2Id = 2;
     38   // Check we can create shader.
     39   Shader* info0 = manager_.CreateShader(
     40       kClient1Id, kService1Id, kShader1Type);
     41   // Check shader got created.
     42   ASSERT_TRUE(info0 != NULL);
     43   Shader* shader1 = manager_.GetShader(kClient1Id);
     44   ASSERT_EQ(info0, shader1);
     45   // Check we get nothing for a non-existent shader.
     46   EXPECT_TRUE(manager_.GetShader(kClient2Id) == NULL);
     47   // Check we can't get the shader after we remove it.
     48   manager_.MarkAsDeleted(shader1);
     49   EXPECT_TRUE(manager_.GetShader(kClient1Id) == NULL);
     50 }
     51 
     52 TEST_F(ShaderManagerTest, Destroy) {
     53   const GLuint kClient1Id = 1;
     54   const GLuint kService1Id = 11;
     55   const GLenum kShader1Type = GL_VERTEX_SHADER;
     56   // Check we can create shader.
     57   Shader* shader1 = manager_.CreateShader(
     58       kClient1Id, kService1Id, kShader1Type);
     59   // Check shader got created.
     60   ASSERT_TRUE(shader1 != NULL);
     61   EXPECT_CALL(*gl_, DeleteShader(kService1Id))
     62       .Times(1)
     63       .RetiresOnSaturation();
     64   manager_.Destroy(true);
     65   // Check that resources got freed.
     66   shader1 = manager_.GetShader(kClient1Id);
     67   ASSERT_TRUE(shader1 == NULL);
     68 }
     69 
     70 TEST_F(ShaderManagerTest, DeleteBug) {
     71   const GLuint kClient1Id = 1;
     72   const GLuint kClient2Id = 2;
     73   const GLuint kService1Id = 11;
     74   const GLuint kService2Id = 12;
     75   const GLenum kShaderType = GL_VERTEX_SHADER;
     76   // Check we can create shader.
     77   scoped_refptr<Shader> shader1(
     78       manager_.CreateShader(kClient1Id, kService1Id, kShaderType));
     79   scoped_refptr<Shader> shader2(
     80       manager_.CreateShader(kClient2Id, kService2Id, kShaderType));
     81   ASSERT_TRUE(shader1.get());
     82   ASSERT_TRUE(shader2.get());
     83   manager_.UseShader(shader1.get());
     84   manager_.MarkAsDeleted(shader1.get());
     85   manager_.MarkAsDeleted(shader2.get());
     86   EXPECT_TRUE(manager_.IsOwned(shader1.get()));
     87   EXPECT_FALSE(manager_.IsOwned(shader2.get()));
     88 }
     89 
     90 TEST_F(ShaderManagerTest, DoCompile) {
     91   const GLuint kClient1Id = 1;
     92   const GLuint kService1Id = 11;
     93   const GLenum kShader1Type = GL_VERTEX_SHADER;
     94   const char* kClient1Source = "hello world";
     95   const GLenum kAttrib1Type = GL_FLOAT_VEC2;
     96   const GLsizei kAttrib1Size = 2;
     97   const int kAttrib1Precision = SH_PRECISION_MEDIUMP;
     98   const char* kAttrib1Name = "attr1";
     99   const GLenum kAttrib2Type = GL_FLOAT_VEC3;
    100   const GLsizei kAttrib2Size = 4;
    101   const int kAttrib2Precision = SH_PRECISION_HIGHP;
    102   const char* kAttrib2Name = "attr2";
    103   const int kAttribStaticUse = 0;
    104   const GLenum kUniform1Type = GL_FLOAT_MAT2;
    105   const GLsizei kUniform1Size = 3;
    106   const int kUniform1Precision = SH_PRECISION_LOWP;
    107   const int kUniform1StaticUse = 1;
    108   const char* kUniform1Name = "uni1";
    109   const GLenum kUniform2Type = GL_FLOAT_MAT3;
    110   const GLsizei kUniform2Size = 5;
    111   const int kUniform2Precision = SH_PRECISION_MEDIUMP;
    112   const int kUniform2StaticUse = 0;
    113   const char* kUniform2Name = "uni2";
    114   const GLenum kVarying1Type = GL_FLOAT_VEC4;
    115   const GLsizei kVarying1Size = 1;
    116   const int kVarying1Precision = SH_PRECISION_HIGHP;
    117   const int kVarying1StaticUse = 0;
    118   const char* kVarying1Name = "varying1";
    119 
    120   // Check we can create shader.
    121   Shader* shader1 = manager_.CreateShader(
    122       kClient1Id, kService1Id, kShader1Type);
    123   // Check shader got created.
    124   ASSERT_TRUE(shader1 != NULL);
    125   EXPECT_EQ(kService1Id, shader1->service_id());
    126   // Check if the shader has correct type.
    127   EXPECT_EQ(kShader1Type, shader1->shader_type());
    128   EXPECT_FALSE(shader1->valid());
    129   EXPECT_FALSE(shader1->InUse());
    130   EXPECT_TRUE(shader1->source().empty());
    131   EXPECT_TRUE(shader1->log_info().empty());
    132   EXPECT_TRUE(shader1->signature_source().empty());
    133   EXPECT_TRUE(shader1->translated_source().empty());
    134   EXPECT_EQ(0u, shader1->attrib_map().size());
    135   EXPECT_EQ(0u, shader1->uniform_map().size());
    136   EXPECT_EQ(0u, shader1->varying_map().size());
    137 
    138   // Check we can set its source.
    139   shader1->set_source(kClient1Source);
    140   EXPECT_STREQ(kClient1Source, shader1->source().c_str());
    141   EXPECT_TRUE(shader1->signature_source().empty());
    142 
    143   // Check DoCompile() will set compilation states, log, translated source,
    144   // shader variables, and name mapping.
    145   const std::string kLog = "foo";
    146   const std::string kTranslatedSource = "poo";
    147 
    148   ShaderTranslator::VariableMap attrib_map;
    149   attrib_map[kAttrib1Name] = ShaderTranslatorInterface::VariableInfo(
    150       kAttrib1Type, kAttrib1Size, kAttrib1Precision,
    151       kAttribStaticUse, kAttrib1Name);
    152   attrib_map[kAttrib2Name] = ShaderTranslatorInterface::VariableInfo(
    153       kAttrib2Type, kAttrib2Size, kAttrib2Precision,
    154       kAttribStaticUse, kAttrib2Name);
    155   ShaderTranslator::VariableMap uniform_map;
    156   uniform_map[kUniform1Name] = ShaderTranslatorInterface::VariableInfo(
    157       kUniform1Type, kUniform1Size, kUniform1Precision,
    158       kUniform1StaticUse, kUniform1Name);
    159   uniform_map[kUniform2Name] = ShaderTranslatorInterface::VariableInfo(
    160       kUniform2Type, kUniform2Size, kUniform2Precision,
    161       kUniform2StaticUse, kUniform2Name);
    162   ShaderTranslator::VariableMap varying_map;
    163   varying_map[kVarying1Name] = ShaderTranslatorInterface::VariableInfo(
    164       kVarying1Type, kVarying1Size, kVarying1Precision,
    165       kVarying1StaticUse, kVarying1Name);
    166 
    167   TestHelper::SetShaderStates(
    168       gl_.get(), shader1, true, &kLog, &kTranslatedSource,
    169       &attrib_map, &uniform_map, &varying_map, NULL);
    170   EXPECT_TRUE(shader1->valid());
    171   // When compilation succeeds, no log is recorded.
    172   EXPECT_STREQ("", shader1->log_info().c_str());
    173   EXPECT_STREQ(kClient1Source, shader1->signature_source().c_str());
    174   EXPECT_STREQ(kTranslatedSource.c_str(), shader1->translated_source().c_str());
    175 
    176   // Check varying infos got copied.
    177   EXPECT_EQ(attrib_map.size(), shader1->attrib_map().size());
    178   for (ShaderTranslator::VariableMap::const_iterator it = attrib_map.begin();
    179        it != attrib_map.end(); ++it) {
    180     const Shader::VariableInfo* variable_info =
    181         shader1->GetAttribInfo(it->first);
    182     ASSERT_TRUE(variable_info != NULL);
    183     EXPECT_EQ(it->second.type, variable_info->type);
    184     EXPECT_EQ(it->second.size, variable_info->size);
    185     EXPECT_EQ(it->second.precision, variable_info->precision);
    186     EXPECT_EQ(it->second.static_use, variable_info->static_use);
    187     EXPECT_STREQ(it->second.name.c_str(), variable_info->name.c_str());
    188   }
    189   // Check uniform infos got copied.
    190   EXPECT_EQ(uniform_map.size(), shader1->uniform_map().size());
    191   for (ShaderTranslator::VariableMap::const_iterator it = uniform_map.begin();
    192        it != uniform_map.end(); ++it) {
    193     const Shader::VariableInfo* variable_info =
    194         shader1->GetUniformInfo(it->first);
    195     ASSERT_TRUE(variable_info != NULL);
    196     EXPECT_EQ(it->second.type, variable_info->type);
    197     EXPECT_EQ(it->second.size, variable_info->size);
    198     EXPECT_EQ(it->second.precision, variable_info->precision);
    199     EXPECT_EQ(it->second.static_use, variable_info->static_use);
    200     EXPECT_STREQ(it->second.name.c_str(), variable_info->name.c_str());
    201   }
    202   // Check varying infos got copied.
    203   EXPECT_EQ(varying_map.size(), shader1->varying_map().size());
    204   for (ShaderTranslator::VariableMap::const_iterator it = varying_map.begin();
    205        it != varying_map.end(); ++it) {
    206     const Shader::VariableInfo* variable_info =
    207         shader1->GetVaryingInfo(it->first);
    208     ASSERT_TRUE(variable_info != NULL);
    209     EXPECT_EQ(it->second.type, variable_info->type);
    210     EXPECT_EQ(it->second.size, variable_info->size);
    211     EXPECT_EQ(it->second.precision, variable_info->precision);
    212     EXPECT_EQ(it->second.static_use, variable_info->static_use);
    213     EXPECT_STREQ(it->second.name.c_str(), variable_info->name.c_str());
    214   }
    215 
    216   // Compile failure case.
    217   TestHelper::SetShaderStates(
    218       gl_.get(), shader1, false, &kLog, &kTranslatedSource,
    219       &attrib_map, &uniform_map, &varying_map, NULL);
    220   EXPECT_FALSE(shader1->valid());
    221   EXPECT_STREQ(kLog.c_str(), shader1->log_info().c_str());
    222   EXPECT_STREQ("", shader1->translated_source().c_str());
    223   EXPECT_TRUE(shader1->attrib_map().empty());
    224   EXPECT_TRUE(shader1->uniform_map().empty());
    225   EXPECT_TRUE(shader1->varying_map().empty());
    226 }
    227 
    228 TEST_F(ShaderManagerTest, ShaderInfoUseCount) {
    229   const GLuint kClient1Id = 1;
    230   const GLuint kService1Id = 11;
    231   const GLenum kShader1Type = GL_VERTEX_SHADER;
    232   // Check we can create shader.
    233   Shader* shader1 = manager_.CreateShader(
    234       kClient1Id, kService1Id, kShader1Type);
    235   // Check shader got created.
    236   ASSERT_TRUE(shader1 != NULL);
    237   EXPECT_FALSE(shader1->InUse());
    238   EXPECT_FALSE(shader1->IsDeleted());
    239   manager_.UseShader(shader1);
    240   EXPECT_TRUE(shader1->InUse());
    241   manager_.UseShader(shader1);
    242   EXPECT_TRUE(shader1->InUse());
    243   manager_.MarkAsDeleted(shader1);
    244   EXPECT_TRUE(shader1->IsDeleted());
    245   Shader* shader2 = manager_.GetShader(kClient1Id);
    246   EXPECT_EQ(shader1, shader2);
    247   manager_.UnuseShader(shader1);
    248   EXPECT_TRUE(shader1->InUse());
    249   manager_.UnuseShader(shader1);  // this should delete the info.
    250   shader2 = manager_.GetShader(kClient1Id);
    251   EXPECT_TRUE(shader2 == NULL);
    252 
    253   shader1 = manager_.CreateShader(kClient1Id, kService1Id, kShader1Type);
    254   ASSERT_TRUE(shader1 != NULL);
    255   EXPECT_FALSE(shader1->InUse());
    256   manager_.UseShader(shader1);
    257   EXPECT_TRUE(shader1->InUse());
    258   manager_.UseShader(shader1);
    259   EXPECT_TRUE(shader1->InUse());
    260   manager_.UnuseShader(shader1);
    261   EXPECT_TRUE(shader1->InUse());
    262   manager_.UnuseShader(shader1);
    263   EXPECT_FALSE(shader1->InUse());
    264   shader2 = manager_.GetShader(kClient1Id);
    265   EXPECT_EQ(shader1, shader2);
    266   manager_.MarkAsDeleted(shader1);  // this should delete the shader.
    267   shader2 = manager_.GetShader(kClient1Id);
    268   EXPECT_TRUE(shader2 == NULL);
    269 }
    270 
    271 }  // namespace gles2
    272 }  // namespace gpu
    273