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