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/mocks.h"
      9 #include "testing/gtest/include/gtest/gtest.h"
     10 #include "ui/gl/gl_mock.h"
     11 
     12 using ::testing::Return;
     13 using ::testing::ReturnRef;
     14 
     15 namespace gpu {
     16 namespace gles2 {
     17 
     18 class ShaderManagerTest : public testing::Test {
     19  public:
     20   ShaderManagerTest() {
     21   }
     22 
     23   virtual ~ShaderManagerTest() {
     24     manager_.Destroy(false);
     25   }
     26 
     27  protected:
     28   virtual void SetUp() {
     29     gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>());
     30     ::gfx::GLInterface::SetGLInterface(gl_.get());
     31   }
     32 
     33   virtual void TearDown() {
     34     ::gfx::GLInterface::SetGLInterface(NULL);
     35     gl_.reset();
     36   }
     37 
     38   // Use StrictMock to make 100% sure we know how GL will be called.
     39   scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_;
     40   ShaderManager manager_;
     41 };
     42 
     43 TEST_F(ShaderManagerTest, Basic) {
     44   const GLuint kClient1Id = 1;
     45   const GLuint kService1Id = 11;
     46   const GLenum kShader1Type = GL_VERTEX_SHADER;
     47   const GLuint kClient2Id = 2;
     48   // Check we can create shader.
     49   Shader* info0 = manager_.CreateShader(
     50       kClient1Id, kService1Id, kShader1Type);
     51   // Check shader got created.
     52   ASSERT_TRUE(info0 != NULL);
     53   Shader* shader1 = manager_.GetShader(kClient1Id);
     54   ASSERT_EQ(info0, shader1);
     55   // Check we get nothing for a non-existent shader.
     56   EXPECT_TRUE(manager_.GetShader(kClient2Id) == NULL);
     57   // Check we can't get the shader after we remove it.
     58   manager_.MarkAsDeleted(shader1);
     59   EXPECT_TRUE(manager_.GetShader(kClient1Id) == NULL);
     60 }
     61 
     62 TEST_F(ShaderManagerTest, Destroy) {
     63   const GLuint kClient1Id = 1;
     64   const GLuint kService1Id = 11;
     65   const GLenum kShader1Type = GL_VERTEX_SHADER;
     66   // Check we can create shader.
     67   Shader* shader1 = manager_.CreateShader(
     68       kClient1Id, kService1Id, kShader1Type);
     69   // Check shader got created.
     70   ASSERT_TRUE(shader1 != NULL);
     71   EXPECT_CALL(*gl_, DeleteShader(kService1Id))
     72       .Times(1)
     73       .RetiresOnSaturation();
     74   manager_.Destroy(true);
     75   // Check that resources got freed.
     76   shader1 = manager_.GetShader(kClient1Id);
     77   ASSERT_TRUE(shader1 == NULL);
     78 }
     79 
     80 TEST_F(ShaderManagerTest, DeleteBug) {
     81   const GLuint kClient1Id = 1;
     82   const GLuint kClient2Id = 2;
     83   const GLuint kService1Id = 11;
     84   const GLuint kService2Id = 12;
     85   const GLenum kShaderType = GL_VERTEX_SHADER;
     86   // Check we can create shader.
     87   scoped_refptr<Shader> shader1(
     88       manager_.CreateShader(kClient1Id, kService1Id, kShaderType));
     89   scoped_refptr<Shader> shader2(
     90       manager_.CreateShader(kClient2Id, kService2Id, kShaderType));
     91   ASSERT_TRUE(shader1.get());
     92   ASSERT_TRUE(shader2.get());
     93   manager_.UseShader(shader1.get());
     94   manager_.MarkAsDeleted(shader1.get());
     95   manager_.MarkAsDeleted(shader2.get());
     96   EXPECT_TRUE(manager_.IsOwned(shader1.get()));
     97   EXPECT_FALSE(manager_.IsOwned(shader2.get()));
     98 }
     99 
    100 TEST_F(ShaderManagerTest, Shader) {
    101   const GLuint kClient1Id = 1;
    102   const GLuint kService1Id = 11;
    103   const GLenum kShader1Type = GL_VERTEX_SHADER;
    104   const char* kClient1Source = "hello world";
    105   // Check we can create shader.
    106   Shader* shader1 = manager_.CreateShader(
    107       kClient1Id, kService1Id, kShader1Type);
    108   // Check shader got created.
    109   ASSERT_TRUE(shader1 != NULL);
    110   EXPECT_EQ(kService1Id, shader1->service_id());
    111   // Check if the shader has correct type.
    112   EXPECT_EQ(kShader1Type, shader1->shader_type());
    113   EXPECT_FALSE(shader1->IsValid());
    114   EXPECT_FALSE(shader1->InUse());
    115   EXPECT_TRUE(shader1->source() == NULL);
    116   EXPECT_TRUE(shader1->log_info() == NULL);
    117   const char* kLog = "foo";
    118   shader1->SetStatus(true, kLog, NULL);
    119   EXPECT_TRUE(shader1->IsValid());
    120   EXPECT_STREQ(kLog, shader1->log_info()->c_str());
    121   // Check we can set its source.
    122   shader1->UpdateSource(kClient1Source);
    123   EXPECT_STREQ(kClient1Source, shader1->source()->c_str());
    124   EXPECT_EQ(NULL, shader1->translated_source());
    125   // Check we can set its translated source.
    126   shader1->UpdateTranslatedSource(kClient1Source);
    127   EXPECT_STREQ(kClient1Source,
    128                shader1->translated_source()->c_str());
    129 }
    130 
    131 TEST_F(ShaderManagerTest, GetInfo) {
    132   const GLuint kClient1Id = 1;
    133   const GLuint kService1Id = 11;
    134   const GLenum kShader1Type = GL_VERTEX_SHADER;
    135   const GLenum kAttrib1Type = GL_FLOAT_VEC2;
    136   const GLsizei kAttrib1Size = 2;
    137   const char* kAttrib1Name = "attr1";
    138   const GLenum kAttrib2Type = GL_FLOAT_VEC3;
    139   const GLsizei kAttrib2Size = 4;
    140   const char* kAttrib2Name = "attr2";
    141   const GLenum kUniform1Type = GL_FLOAT_MAT2;
    142   const GLsizei kUniform1Size = 3;
    143   const char* kUniform1Name = "uni1";
    144   const GLenum kUniform2Type = GL_FLOAT_MAT3;
    145   const GLsizei kUniform2Size = 5;
    146   const char* kUniform2Name = "uni2";
    147   MockShaderTranslator shader_translator;
    148   ShaderTranslator::VariableMap attrib_map;
    149   attrib_map[kAttrib1Name] = ShaderTranslatorInterface::VariableInfo(
    150       kAttrib1Type, kAttrib1Size, kAttrib1Name);
    151   attrib_map[kAttrib2Name] = ShaderTranslatorInterface::VariableInfo(
    152       kAttrib2Type, kAttrib2Size, kAttrib2Name);
    153   ShaderTranslator::VariableMap uniform_map;
    154   uniform_map[kUniform1Name] = ShaderTranslatorInterface::VariableInfo(
    155       kUniform1Type, kUniform1Size, kUniform1Name);
    156   uniform_map[kUniform2Name] = ShaderTranslatorInterface::VariableInfo(
    157       kUniform2Type, kUniform2Size, kUniform2Name);
    158   EXPECT_CALL(shader_translator, attrib_map())
    159       .WillRepeatedly(ReturnRef(attrib_map));
    160   EXPECT_CALL(shader_translator, uniform_map())
    161       .WillRepeatedly(ReturnRef(uniform_map));
    162   ShaderTranslator::NameMap name_map;
    163   EXPECT_CALL(shader_translator, name_map())
    164       .WillRepeatedly(ReturnRef(name_map));
    165   // Check we can create shader.
    166   Shader* shader1 = manager_.CreateShader(
    167       kClient1Id, kService1Id, kShader1Type);
    168   // Check shader got created.
    169   ASSERT_TRUE(shader1 != NULL);
    170   // Set Status
    171   shader1->SetStatus(true, "", &shader_translator);
    172   // Check attrib and uniform infos got copied.
    173   for (ShaderTranslator::VariableMap::const_iterator it = attrib_map.begin();
    174        it != attrib_map.end(); ++it) {
    175     const Shader::VariableInfo* variable_info =
    176         shader1->GetAttribInfo(it->first);
    177     ASSERT_TRUE(variable_info != NULL);
    178     EXPECT_EQ(it->second.type, variable_info->type);
    179     EXPECT_EQ(it->second.size, variable_info->size);
    180     EXPECT_EQ(it->second.name, variable_info->name);
    181   }
    182   for (ShaderTranslator::VariableMap::const_iterator it = uniform_map.begin();
    183        it != uniform_map.end(); ++it) {
    184     const Shader::VariableInfo* variable_info =
    185         shader1->GetUniformInfo(it->first);
    186     ASSERT_TRUE(variable_info != NULL);
    187     EXPECT_EQ(it->second.type, variable_info->type);
    188     EXPECT_EQ(it->second.size, variable_info->size);
    189     EXPECT_EQ(it->second.name, variable_info->name);
    190   }
    191   // Check attrib and uniform get cleared.
    192   shader1->SetStatus(true, NULL, NULL);
    193   EXPECT_TRUE(shader1->log_info() == NULL);
    194   for (ShaderTranslator::VariableMap::const_iterator it = attrib_map.begin();
    195        it != attrib_map.end(); ++it) {
    196     const Shader::VariableInfo* variable_info =
    197         shader1->GetAttribInfo(it->first);
    198     EXPECT_TRUE(variable_info == NULL);
    199   }
    200   for (ShaderTranslator::VariableMap::const_iterator it = uniform_map.begin();
    201        it != uniform_map.end(); ++it) {
    202     const Shader::VariableInfo* variable_info =
    203         shader1->GetUniformInfo(it->first);
    204     ASSERT_TRUE(variable_info == NULL);
    205   }
    206 }
    207 
    208 TEST_F(ShaderManagerTest, ShaderInfoUseCount) {
    209   const GLuint kClient1Id = 1;
    210   const GLuint kService1Id = 11;
    211   const GLenum kShader1Type = GL_VERTEX_SHADER;
    212   // Check we can create shader.
    213   Shader* shader1 = manager_.CreateShader(
    214       kClient1Id, kService1Id, kShader1Type);
    215   // Check shader got created.
    216   ASSERT_TRUE(shader1 != NULL);
    217   EXPECT_FALSE(shader1->InUse());
    218   EXPECT_FALSE(shader1->IsDeleted());
    219   manager_.UseShader(shader1);
    220   EXPECT_TRUE(shader1->InUse());
    221   manager_.UseShader(shader1);
    222   EXPECT_TRUE(shader1->InUse());
    223   manager_.MarkAsDeleted(shader1);
    224   EXPECT_TRUE(shader1->IsDeleted());
    225   Shader* shader2 = manager_.GetShader(kClient1Id);
    226   EXPECT_EQ(shader1, shader2);
    227   manager_.UnuseShader(shader1);
    228   EXPECT_TRUE(shader1->InUse());
    229   manager_.UnuseShader(shader1);  // this should delete the info.
    230   shader2 = manager_.GetShader(kClient1Id);
    231   EXPECT_TRUE(shader2 == NULL);
    232 
    233   shader1 = manager_.CreateShader(kClient1Id, kService1Id, kShader1Type);
    234   ASSERT_TRUE(shader1 != NULL);
    235   EXPECT_FALSE(shader1->InUse());
    236   manager_.UseShader(shader1);
    237   EXPECT_TRUE(shader1->InUse());
    238   manager_.UseShader(shader1);
    239   EXPECT_TRUE(shader1->InUse());
    240   manager_.UnuseShader(shader1);
    241   EXPECT_TRUE(shader1->InUse());
    242   manager_.UnuseShader(shader1);
    243   EXPECT_FALSE(shader1->InUse());
    244   shader2 = manager_.GetShader(kClient1Id);
    245   EXPECT_EQ(shader1, shader2);
    246   manager_.MarkAsDeleted(shader1);  // this should delete the shader.
    247   shader2 = manager_.GetShader(kClient1Id);
    248   EXPECT_TRUE(shader2 == NULL);
    249 }
    250 
    251 }  // namespace gles2
    252 }  // namespace gpu
    253