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