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 int kAttrib1Precision = SH_PRECISION_MEDIUMP;
    138   const char* kAttrib1Name = "attr1";
    139   const GLenum kAttrib2Type = GL_FLOAT_VEC3;
    140   const GLsizei kAttrib2Size = 4;
    141   const int kAttrib2Precision = SH_PRECISION_HIGHP;
    142   const char* kAttrib2Name = "attr2";
    143   const int kAttribStaticUse = 0;
    144   const GLenum kUniform1Type = GL_FLOAT_MAT2;
    145   const GLsizei kUniform1Size = 3;
    146   const int kUniform1Precision = SH_PRECISION_LOWP;
    147   const int kUniform1StaticUse = 1;
    148   const char* kUniform1Name = "uni1";
    149   const GLenum kUniform2Type = GL_FLOAT_MAT3;
    150   const GLsizei kUniform2Size = 5;
    151   const int kUniform2Precision = SH_PRECISION_MEDIUMP;
    152   const int kUniform2StaticUse = 0;
    153   const char* kUniform2Name = "uni2";
    154 
    155   MockShaderTranslator shader_translator;
    156   ShaderTranslator::VariableMap attrib_map;
    157   attrib_map[kAttrib1Name] = ShaderTranslatorInterface::VariableInfo(
    158       kAttrib1Type, kAttrib1Size, kAttrib1Precision,
    159       kAttribStaticUse, kAttrib1Name);
    160   attrib_map[kAttrib2Name] = ShaderTranslatorInterface::VariableInfo(
    161       kAttrib2Type, kAttrib2Size, kAttrib2Precision,
    162       kAttribStaticUse, kAttrib2Name);
    163   ShaderTranslator::VariableMap uniform_map;
    164   uniform_map[kUniform1Name] = ShaderTranslatorInterface::VariableInfo(
    165       kUniform1Type, kUniform1Size, kUniform1Precision,
    166       kUniform1StaticUse, kUniform1Name);
    167   uniform_map[kUniform2Name] = ShaderTranslatorInterface::VariableInfo(
    168       kUniform2Type, kUniform2Size, kUniform2Precision,
    169       kUniform2StaticUse, kUniform2Name);
    170   EXPECT_CALL(shader_translator, attrib_map())
    171       .WillRepeatedly(ReturnRef(attrib_map));
    172   EXPECT_CALL(shader_translator, uniform_map())
    173       .WillRepeatedly(ReturnRef(uniform_map));
    174   ShaderTranslator::VariableMap varying_map;
    175   EXPECT_CALL(shader_translator, varying_map())
    176       .WillRepeatedly(ReturnRef(varying_map));
    177   ShaderTranslator::NameMap name_map;
    178   EXPECT_CALL(shader_translator, name_map())
    179       .WillRepeatedly(ReturnRef(name_map));
    180   // Check we can create shader.
    181   Shader* shader1 = manager_.CreateShader(
    182       kClient1Id, kService1Id, kShader1Type);
    183   // Check shader got created.
    184   ASSERT_TRUE(shader1 != NULL);
    185   // Set Status
    186   shader1->SetStatus(true, "", &shader_translator);
    187   // Check attrib and uniform infos got copied.
    188   for (ShaderTranslator::VariableMap::const_iterator it = attrib_map.begin();
    189        it != attrib_map.end(); ++it) {
    190     const Shader::VariableInfo* variable_info =
    191         shader1->GetAttribInfo(it->first);
    192     ASSERT_TRUE(variable_info != NULL);
    193     EXPECT_EQ(it->second.type, variable_info->type);
    194     EXPECT_EQ(it->second.size, variable_info->size);
    195     EXPECT_EQ(it->second.precision, variable_info->precision);
    196     EXPECT_EQ(it->second.static_use, variable_info->static_use);
    197     EXPECT_EQ(it->second.name, variable_info->name);
    198   }
    199   for (ShaderTranslator::VariableMap::const_iterator it = uniform_map.begin();
    200        it != uniform_map.end(); ++it) {
    201     const Shader::VariableInfo* variable_info =
    202         shader1->GetUniformInfo(it->first);
    203     ASSERT_TRUE(variable_info != NULL);
    204     EXPECT_EQ(it->second.type, variable_info->type);
    205     EXPECT_EQ(it->second.size, variable_info->size);
    206     EXPECT_EQ(it->second.precision, variable_info->precision);
    207     EXPECT_EQ(it->second.static_use, variable_info->static_use);
    208     EXPECT_EQ(it->second.name, variable_info->name);
    209   }
    210   // Check attrib and uniform get cleared.
    211   shader1->SetStatus(true, NULL, NULL);
    212   EXPECT_TRUE(shader1->log_info() == NULL);
    213   for (ShaderTranslator::VariableMap::const_iterator it = attrib_map.begin();
    214        it != attrib_map.end(); ++it) {
    215     const Shader::VariableInfo* variable_info =
    216         shader1->GetAttribInfo(it->first);
    217     EXPECT_TRUE(variable_info == NULL);
    218   }
    219   for (ShaderTranslator::VariableMap::const_iterator it = uniform_map.begin();
    220        it != uniform_map.end(); ++it) {
    221     const Shader::VariableInfo* variable_info =
    222         shader1->GetUniformInfo(it->first);
    223     ASSERT_TRUE(variable_info == NULL);
    224   }
    225 }
    226 
    227 TEST_F(ShaderManagerTest, ShaderInfoUseCount) {
    228   const GLuint kClient1Id = 1;
    229   const GLuint kService1Id = 11;
    230   const GLenum kShader1Type = GL_VERTEX_SHADER;
    231   // Check we can create shader.
    232   Shader* shader1 = manager_.CreateShader(
    233       kClient1Id, kService1Id, kShader1Type);
    234   // Check shader got created.
    235   ASSERT_TRUE(shader1 != NULL);
    236   EXPECT_FALSE(shader1->InUse());
    237   EXPECT_FALSE(shader1->IsDeleted());
    238   manager_.UseShader(shader1);
    239   EXPECT_TRUE(shader1->InUse());
    240   manager_.UseShader(shader1);
    241   EXPECT_TRUE(shader1->InUse());
    242   manager_.MarkAsDeleted(shader1);
    243   EXPECT_TRUE(shader1->IsDeleted());
    244   Shader* shader2 = manager_.GetShader(kClient1Id);
    245   EXPECT_EQ(shader1, shader2);
    246   manager_.UnuseShader(shader1);
    247   EXPECT_TRUE(shader1->InUse());
    248   manager_.UnuseShader(shader1);  // this should delete the info.
    249   shader2 = manager_.GetShader(kClient1Id);
    250   EXPECT_TRUE(shader2 == NULL);
    251 
    252   shader1 = manager_.CreateShader(kClient1Id, kService1Id, kShader1Type);
    253   ASSERT_TRUE(shader1 != NULL);
    254   EXPECT_FALSE(shader1->InUse());
    255   manager_.UseShader(shader1);
    256   EXPECT_TRUE(shader1->InUse());
    257   manager_.UseShader(shader1);
    258   EXPECT_TRUE(shader1->InUse());
    259   manager_.UnuseShader(shader1);
    260   EXPECT_TRUE(shader1->InUse());
    261   manager_.UnuseShader(shader1);
    262   EXPECT_FALSE(shader1->InUse());
    263   shader2 = manager_.GetShader(kClient1Id);
    264   EXPECT_EQ(shader1, shader2);
    265   manager_.MarkAsDeleted(shader1);  // this should delete the shader.
    266   shader2 = manager_.GetShader(kClient1Id);
    267   EXPECT_TRUE(shader2 == NULL);
    268 }
    269 
    270 }  // namespace gles2
    271 }  // namespace gpu
    272