| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "gpu/command_buffer/service/memory_program_cache.h" | 5 #include "gpu/command_buffer/service/memory_program_cache.h" |
| 6 | 6 |
| 7 #include "base/base64.h" | 7 #include "base/base64.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
| 10 #include "base/sha1.h" | 10 #include "base/sha1.h" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 namespace gles2 { | 38 namespace gles2 { |
| 39 | 39 |
| 40 namespace { | 40 namespace { |
| 41 | 41 |
| 42 enum ShaderMapType { | 42 enum ShaderMapType { |
| 43 ATTRIB_MAP = 0, | 43 ATTRIB_MAP = 0, |
| 44 UNIFORM_MAP, | 44 UNIFORM_MAP, |
| 45 VARYING_MAP | 45 VARYING_MAP |
| 46 }; | 46 }; |
| 47 | 47 |
| 48 void StoreShaderInfo(ShaderMapType type, ShaderProto *proto, | 48 void FillShaderVariableProto( |
| 49 const ShaderTranslator::VariableMap& map) { | 49 ShaderVariableProto* proto, const sh::ShaderVariable& variable) { |
| 50 ShaderTranslator::VariableMap::const_iterator iter; | 50 proto->set_type(variable.type); |
| 51 for (iter = map.begin(); iter != map.end(); ++iter) { | 51 proto->set_precision(variable.precision); |
| 52 ShaderInfoProto* info = NULL; | 52 proto->set_name(variable.name); |
| 53 switch (type) { | 53 proto->set_mapped_name(variable.mappedName); |
| 54 case UNIFORM_MAP: | 54 proto->set_array_size(variable.arraySize); |
| 55 info = proto->add_uniforms(); | 55 proto->set_static_use(variable.staticUse); |
| 56 break; | 56 for (size_t ii = 0; ii < variable.fields.size(); ++ii) { |
| 57 case ATTRIB_MAP: | 57 ShaderVariableProto* field = proto->add_fields(); |
| 58 info = proto->add_attribs(); | 58 FillShaderVariableProto(field, variable.fields[ii]); |
| 59 break; | |
| 60 case VARYING_MAP: | |
| 61 info = proto->add_varyings(); | |
| 62 break; | |
| 63 default: NOTREACHED(); | |
| 64 } | |
| 65 | |
| 66 info->set_key(iter->first); | |
| 67 info->set_type(iter->second.type); | |
| 68 info->set_size(iter->second.size); | |
| 69 info->set_precision(iter->second.precision); | |
| 70 info->set_static_use(iter->second.static_use); | |
| 71 info->set_name(iter->second.name); | |
| 72 } | 59 } |
| 60 proto->set_struct_name(variable.structName); |
| 73 } | 61 } |
| 74 | 62 |
| 75 void RetrieveShaderInfo(const ShaderInfoProto& proto, | 63 void FillShaderAttributeProto( |
| 76 ShaderTranslator::VariableMap* map) { | 64 ShaderAttributeProto* proto, const sh::Attribute& attrib) { |
| 77 ShaderTranslator::VariableInfo info( | 65 FillShaderVariableProto(proto->mutable_basic(), attrib); |
| 78 proto.type(), proto.size(), proto.precision(), | 66 proto->set_location(attrib.location); |
| 79 proto.static_use(), proto.name()); | 67 } |
| 80 (*map)[proto.key()] = info; | 68 |
| 69 void FillShaderUniformProto( |
| 70 ShaderUniformProto* proto, const sh::Uniform& uniform) { |
| 71 FillShaderVariableProto(proto->mutable_basic(), uniform); |
| 72 } |
| 73 |
| 74 void FillShaderVaryingProto( |
| 75 ShaderVaryingProto* proto, const sh::Varying& varying) { |
| 76 FillShaderVariableProto(proto->mutable_basic(), varying); |
| 77 proto->set_interpolation(varying.interpolation); |
| 78 proto->set_is_invariant(varying.isInvariant); |
| 81 } | 79 } |
| 82 | 80 |
| 83 void FillShaderProto(ShaderProto* proto, const char* sha, | 81 void FillShaderProto(ShaderProto* proto, const char* sha, |
| 84 const Shader* shader) { | 82 const Shader* shader) { |
| 85 proto->set_sha(sha, gpu::gles2::ProgramCache::kHashLength); | 83 proto->set_sha(sha, gpu::gles2::ProgramCache::kHashLength); |
| 86 StoreShaderInfo(ATTRIB_MAP, proto, shader->attrib_map()); | 84 for (AttributeMap::const_iterator iter = shader->attrib_map().begin(); |
| 87 StoreShaderInfo(UNIFORM_MAP, proto, shader->uniform_map()); | 85 iter != shader->attrib_map().end(); ++iter) { |
| 88 StoreShaderInfo(VARYING_MAP, proto, shader->varying_map()); | 86 ShaderAttributeProto* info = proto->add_attribs(); |
| 87 FillShaderAttributeProto(info, iter->second); |
| 88 } |
| 89 for (UniformMap::const_iterator iter = shader->uniform_map().begin(); |
| 90 iter != shader->uniform_map().end(); ++iter) { |
| 91 ShaderUniformProto* info = proto->add_uniforms(); |
| 92 FillShaderUniformProto(info, iter->second); |
| 93 } |
| 94 for (VaryingMap::const_iterator iter = shader->varying_map().begin(); |
| 95 iter != shader->varying_map().end(); ++iter) { |
| 96 ShaderVaryingProto* info = proto->add_varyings(); |
| 97 FillShaderVaryingProto(info, iter->second); |
| 98 } |
| 99 } |
| 100 |
| 101 void RetrieveShaderVariableInfo( |
| 102 const ShaderVariableProto& proto, sh::ShaderVariable* variable) { |
| 103 variable->type = proto.type(); |
| 104 variable->precision = proto.precision(); |
| 105 variable->name = proto.name(); |
| 106 variable->mappedName = proto.mapped_name(); |
| 107 variable->arraySize = proto.array_size(); |
| 108 variable->staticUse = proto.static_use(); |
| 109 variable->fields.resize(proto.fields_size()); |
| 110 for (int ii = 0; ii < proto.fields_size(); ++ii) |
| 111 RetrieveShaderVariableInfo(proto.fields(ii), &(variable->fields[ii])); |
| 112 variable->structName = proto.struct_name(); |
| 113 } |
| 114 |
| 115 void RetrieveShaderAttributeInfo( |
| 116 const ShaderAttributeProto& proto, AttributeMap* map) { |
| 117 sh::Attribute attrib; |
| 118 RetrieveShaderVariableInfo(proto.basic(), &attrib); |
| 119 attrib.location = proto.location(); |
| 120 (*map)[proto.basic().mapped_name()] = attrib; |
| 121 } |
| 122 |
| 123 void RetrieveShaderUniformInfo( |
| 124 const ShaderUniformProto& proto, UniformMap* map) { |
| 125 sh::Uniform uniform; |
| 126 RetrieveShaderVariableInfo(proto.basic(), &uniform); |
| 127 (*map)[proto.basic().mapped_name()] = uniform; |
| 128 } |
| 129 |
| 130 void RetrieveShaderVaryingInfo( |
| 131 const ShaderVaryingProto& proto, VaryingMap* map) { |
| 132 sh::Varying varying; |
| 133 RetrieveShaderVariableInfo(proto.basic(), &varying); |
| 134 varying.interpolation = static_cast<sh::InterpolationType>( |
| 135 proto.interpolation()); |
| 136 varying.isInvariant = proto.is_invariant(); |
| 137 (*map)[proto.basic().mapped_name()] = varying; |
| 89 } | 138 } |
| 90 | 139 |
| 91 void RunShaderCallback(const ShaderCacheCallback& callback, | 140 void RunShaderCallback(const ShaderCacheCallback& callback, |
| 92 GpuProgramProto* proto, | 141 GpuProgramProto* proto, |
| 93 std::string sha_string) { | 142 std::string sha_string) { |
| 94 std::string shader; | 143 std::string shader; |
| 95 proto->SerializeToString(&shader); | 144 proto->SerializeToString(&shader); |
| 96 | 145 |
| 97 std::string key; | 146 std::string key; |
| 98 base::Base64Encode(sha_string, &key); | 147 base::Base64Encode(sha_string, &key); |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 shader_b->varying_map(), | 312 shader_b->varying_map(), |
| 264 this)); | 313 this)); |
| 265 | 314 |
| 266 UMA_HISTOGRAM_COUNTS("GPU.ProgramCache.MemorySizeAfterKb", | 315 UMA_HISTOGRAM_COUNTS("GPU.ProgramCache.MemorySizeAfterKb", |
| 267 curr_size_bytes_ / 1024); | 316 curr_size_bytes_ / 1024); |
| 268 } | 317 } |
| 269 | 318 |
| 270 void MemoryProgramCache::LoadProgram(const std::string& program) { | 319 void MemoryProgramCache::LoadProgram(const std::string& program) { |
| 271 scoped_ptr<GpuProgramProto> proto(GpuProgramProto::default_instance().New()); | 320 scoped_ptr<GpuProgramProto> proto(GpuProgramProto::default_instance().New()); |
| 272 if (proto->ParseFromString(program)) { | 321 if (proto->ParseFromString(program)) { |
| 273 ShaderTranslator::VariableMap vertex_attribs; | 322 AttributeMap vertex_attribs; |
| 274 ShaderTranslator::VariableMap vertex_uniforms; | 323 UniformMap vertex_uniforms; |
| 275 ShaderTranslator::VariableMap vertex_varyings; | 324 VaryingMap vertex_varyings; |
| 276 | |
| 277 for (int i = 0; i < proto->vertex_shader().attribs_size(); i++) { | 325 for (int i = 0; i < proto->vertex_shader().attribs_size(); i++) { |
| 278 RetrieveShaderInfo(proto->vertex_shader().attribs(i), &vertex_attribs); | 326 RetrieveShaderAttributeInfo(proto->vertex_shader().attribs(i), |
| 327 &vertex_attribs); |
| 328 } |
| 329 for (int i = 0; i < proto->vertex_shader().uniforms_size(); i++) { |
| 330 RetrieveShaderUniformInfo(proto->vertex_shader().uniforms(i), |
| 331 &vertex_uniforms); |
| 332 } |
| 333 for (int i = 0; i < proto->vertex_shader().varyings_size(); i++) { |
| 334 RetrieveShaderVaryingInfo(proto->vertex_shader().varyings(i), |
| 335 &vertex_varyings); |
| 279 } | 336 } |
| 280 | 337 |
| 281 for (int i = 0; i < proto->vertex_shader().uniforms_size(); i++) { | 338 AttributeMap fragment_attribs; |
| 282 RetrieveShaderInfo(proto->vertex_shader().uniforms(i), &vertex_uniforms); | 339 UniformMap fragment_uniforms; |
| 340 VaryingMap fragment_varyings; |
| 341 for (int i = 0; i < proto->fragment_shader().attribs_size(); i++) { |
| 342 RetrieveShaderAttributeInfo(proto->fragment_shader().attribs(i), |
| 343 &fragment_attribs); |
| 283 } | 344 } |
| 284 | 345 for (int i = 0; i < proto->fragment_shader().uniforms_size(); i++) { |
| 285 for (int i = 0; i < proto->vertex_shader().varyings_size(); i++) { | 346 RetrieveShaderUniformInfo(proto->fragment_shader().uniforms(i), |
| 286 RetrieveShaderInfo(proto->vertex_shader().varyings(i), &vertex_varyings); | 347 &fragment_uniforms); |
| 287 } | 348 } |
| 288 | |
| 289 ShaderTranslator::VariableMap fragment_attribs; | |
| 290 ShaderTranslator::VariableMap fragment_uniforms; | |
| 291 ShaderTranslator::VariableMap fragment_varyings; | |
| 292 | |
| 293 for (int i = 0; i < proto->fragment_shader().attribs_size(); i++) { | |
| 294 RetrieveShaderInfo(proto->fragment_shader().attribs(i), | |
| 295 &fragment_attribs); | |
| 296 } | |
| 297 | |
| 298 for (int i = 0; i < proto->fragment_shader().uniforms_size(); i++) { | |
| 299 RetrieveShaderInfo(proto->fragment_shader().uniforms(i), | |
| 300 &fragment_uniforms); | |
| 301 } | |
| 302 | |
| 303 for (int i = 0; i < proto->fragment_shader().varyings_size(); i++) { | 349 for (int i = 0; i < proto->fragment_shader().varyings_size(); i++) { |
| 304 RetrieveShaderInfo(proto->fragment_shader().varyings(i), | 350 RetrieveShaderVaryingInfo(proto->fragment_shader().varyings(i), |
| 305 &fragment_varyings); | 351 &fragment_varyings); |
| 306 } | 352 } |
| 307 | 353 |
| 308 scoped_ptr<char[]> binary(new char[proto->program().length()]); | 354 scoped_ptr<char[]> binary(new char[proto->program().length()]); |
| 309 memcpy(binary.get(), proto->program().c_str(), proto->program().length()); | 355 memcpy(binary.get(), proto->program().c_str(), proto->program().length()); |
| 310 | 356 |
| 311 store_.Put(proto->sha(), | 357 store_.Put(proto->sha(), |
| 312 new ProgramCacheValue(proto->program().length(), | 358 new ProgramCacheValue(proto->program().length(), |
| 313 proto->format(), | 359 proto->format(), |
| 314 binary.release(), | 360 binary.release(), |
| 315 proto->sha(), | 361 proto->sha(), |
| (...skipping 13 matching lines...) Expand all Loading... |
| 329 LOG(ERROR) << "Failed to parse proto file."; | 375 LOG(ERROR) << "Failed to parse proto file."; |
| 330 } | 376 } |
| 331 } | 377 } |
| 332 | 378 |
| 333 MemoryProgramCache::ProgramCacheValue::ProgramCacheValue( | 379 MemoryProgramCache::ProgramCacheValue::ProgramCacheValue( |
| 334 GLsizei length, | 380 GLsizei length, |
| 335 GLenum format, | 381 GLenum format, |
| 336 const char* data, | 382 const char* data, |
| 337 const std::string& program_hash, | 383 const std::string& program_hash, |
| 338 const char* shader_0_hash, | 384 const char* shader_0_hash, |
| 339 const ShaderTranslator::VariableMap& attrib_map_0, | 385 const AttributeMap& attrib_map_0, |
| 340 const ShaderTranslator::VariableMap& uniform_map_0, | 386 const UniformMap& uniform_map_0, |
| 341 const ShaderTranslator::VariableMap& varying_map_0, | 387 const VaryingMap& varying_map_0, |
| 342 const char* shader_1_hash, | 388 const char* shader_1_hash, |
| 343 const ShaderTranslator::VariableMap& attrib_map_1, | 389 const AttributeMap& attrib_map_1, |
| 344 const ShaderTranslator::VariableMap& uniform_map_1, | 390 const UniformMap& uniform_map_1, |
| 345 const ShaderTranslator::VariableMap& varying_map_1, | 391 const VaryingMap& varying_map_1, |
| 346 MemoryProgramCache* program_cache) | 392 MemoryProgramCache* program_cache) |
| 347 : length_(length), | 393 : length_(length), |
| 348 format_(format), | 394 format_(format), |
| 349 data_(data), | 395 data_(data), |
| 350 program_hash_(program_hash), | 396 program_hash_(program_hash), |
| 351 shader_0_hash_(shader_0_hash, kHashLength), | 397 shader_0_hash_(shader_0_hash, kHashLength), |
| 352 attrib_map_0_(attrib_map_0), | 398 attrib_map_0_(attrib_map_0), |
| 353 uniform_map_0_(uniform_map_0), | 399 uniform_map_0_(uniform_map_0), |
| 354 varying_map_0_(varying_map_0), | 400 varying_map_0_(varying_map_0), |
| 355 shader_1_hash_(shader_1_hash, kHashLength), | 401 shader_1_hash_(shader_1_hash, kHashLength), |
| 356 attrib_map_1_(attrib_map_1), | 402 attrib_map_1_(attrib_map_1), |
| 357 uniform_map_1_(uniform_map_1), | 403 uniform_map_1_(uniform_map_1), |
| 358 varying_map_1_(varying_map_1), | 404 varying_map_1_(varying_map_1), |
| 359 program_cache_(program_cache) { | 405 program_cache_(program_cache) { |
| 360 program_cache_->curr_size_bytes_ += length_; | 406 program_cache_->curr_size_bytes_ += length_; |
| 361 program_cache_->LinkedProgramCacheSuccess(program_hash); | 407 program_cache_->LinkedProgramCacheSuccess(program_hash); |
| 362 } | 408 } |
| 363 | 409 |
| 364 MemoryProgramCache::ProgramCacheValue::~ProgramCacheValue() { | 410 MemoryProgramCache::ProgramCacheValue::~ProgramCacheValue() { |
| 365 program_cache_->curr_size_bytes_ -= length_; | 411 program_cache_->curr_size_bytes_ -= length_; |
| 366 program_cache_->Evict(program_hash_); | 412 program_cache_->Evict(program_hash_); |
| 367 } | 413 } |
| 368 | 414 |
| 369 } // namespace gles2 | 415 } // namespace gles2 |
| 370 } // namespace gpu | 416 } // namespace gpu |
| OLD | NEW |