| 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/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 return gpu::kDefaultMaxProgramCacheMemoryBytes; | 33 return gpu::kDefaultMaxProgramCacheMemoryBytes; |
| 34 } | 34 } |
| 35 | 35 |
| 36 } // anonymous namespace | 36 } // anonymous namespace |
| 37 | 37 |
| 38 namespace gpu { | 38 namespace gpu { |
| 39 namespace gles2 { | 39 namespace gles2 { |
| 40 | 40 |
| 41 namespace { | 41 namespace { |
| 42 | 42 |
| 43 enum ShaderMapType { | |
| 44 ATTRIB_MAP = 0, | |
| 45 UNIFORM_MAP, | |
| 46 VARYING_MAP | |
| 47 }; | |
| 48 | |
| 49 void FillShaderVariableProto( | 43 void FillShaderVariableProto( |
| 50 ShaderVariableProto* proto, const sh::ShaderVariable& variable) { | 44 ShaderVariableProto* proto, const sh::ShaderVariable& variable) { |
| 51 proto->set_type(variable.type); | 45 proto->set_type(variable.type); |
| 52 proto->set_precision(variable.precision); | 46 proto->set_precision(variable.precision); |
| 53 proto->set_name(variable.name); | 47 proto->set_name(variable.name); |
| 54 proto->set_mapped_name(variable.mappedName); | 48 proto->set_mapped_name(variable.mappedName); |
| 55 proto->set_array_size(variable.arraySize); | 49 proto->set_array_size(variable.arraySize); |
| 56 proto->set_static_use(variable.staticUse); | 50 proto->set_static_use(variable.staticUse); |
| 57 for (size_t ii = 0; ii < variable.fields.size(); ++ii) { | 51 for (size_t ii = 0; ii < variable.fields.size(); ++ii) { |
| 58 ShaderVariableProto* field = proto->add_fields(); | 52 ShaderVariableProto* field = proto->add_fields(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 for (UniformMap::const_iterator iter = shader->uniform_map().begin(); | 84 for (UniformMap::const_iterator iter = shader->uniform_map().begin(); |
| 91 iter != shader->uniform_map().end(); ++iter) { | 85 iter != shader->uniform_map().end(); ++iter) { |
| 92 ShaderUniformProto* info = proto->add_uniforms(); | 86 ShaderUniformProto* info = proto->add_uniforms(); |
| 93 FillShaderUniformProto(info, iter->second); | 87 FillShaderUniformProto(info, iter->second); |
| 94 } | 88 } |
| 95 for (VaryingMap::const_iterator iter = shader->varying_map().begin(); | 89 for (VaryingMap::const_iterator iter = shader->varying_map().begin(); |
| 96 iter != shader->varying_map().end(); ++iter) { | 90 iter != shader->varying_map().end(); ++iter) { |
| 97 ShaderVaryingProto* info = proto->add_varyings(); | 91 ShaderVaryingProto* info = proto->add_varyings(); |
| 98 FillShaderVaryingProto(info, iter->second); | 92 FillShaderVaryingProto(info, iter->second); |
| 99 } | 93 } |
| 94 for (auto iter = shader->output_variable_list().begin(); |
| 95 iter != shader->output_variable_list().end(); ++iter) { |
| 96 ShaderAttributeProto* info = proto->add_output_variables(); |
| 97 FillShaderAttributeProto(info, *iter); |
| 98 } |
| 100 } | 99 } |
| 101 | 100 |
| 102 void RetrieveShaderVariableInfo( | 101 void RetrieveShaderVariableInfo( |
| 103 const ShaderVariableProto& proto, sh::ShaderVariable* variable) { | 102 const ShaderVariableProto& proto, sh::ShaderVariable* variable) { |
| 104 variable->type = proto.type(); | 103 variable->type = proto.type(); |
| 105 variable->precision = proto.precision(); | 104 variable->precision = proto.precision(); |
| 106 variable->name = proto.name(); | 105 variable->name = proto.name(); |
| 107 variable->mappedName = proto.mapped_name(); | 106 variable->mappedName = proto.mapped_name(); |
| 108 variable->arraySize = proto.array_size(); | 107 variable->arraySize = proto.array_size(); |
| 109 variable->staticUse = proto.static_use(); | 108 variable->staticUse = proto.static_use(); |
| 110 variable->fields.resize(proto.fields_size()); | 109 variable->fields.resize(proto.fields_size()); |
| 111 for (int ii = 0; ii < proto.fields_size(); ++ii) | 110 for (int ii = 0; ii < proto.fields_size(); ++ii) |
| 112 RetrieveShaderVariableInfo(proto.fields(ii), &(variable->fields[ii])); | 111 RetrieveShaderVariableInfo(proto.fields(ii), &(variable->fields[ii])); |
| 113 variable->structName = proto.struct_name(); | 112 variable->structName = proto.struct_name(); |
| 114 } | 113 } |
| 115 | 114 |
| 116 void RetrieveShaderAttributeInfo( | 115 void RetrieveShaderAttributeInfo( |
| 117 const ShaderAttributeProto& proto, AttributeMap* map) { | 116 const ShaderAttributeProto& proto, AttributeMap* map) { |
| 118 sh::Attribute attrib; | 117 sh::Attribute attrib; |
| 119 RetrieveShaderVariableInfo(proto.basic(), &attrib); | 118 RetrieveShaderVariableInfo(proto.basic(), &attrib); |
| 120 attrib.location = proto.location(); | 119 attrib.location = proto.location(); |
| 121 (*map)[proto.basic().mapped_name()] = attrib; | 120 (*map)[proto.basic().mapped_name()] = attrib; |
| 122 } | 121 } |
| 123 | 122 |
| 123 void RetrieveShaderOutputVariableInfo(const ShaderAttributeProto& proto, |
| 124 AttributeList* list) { |
| 125 sh::Attribute attrib; |
| 126 RetrieveShaderVariableInfo(proto.basic(), &attrib); |
| 127 attrib.location = proto.location(); |
| 128 list->push_back(attrib); |
| 129 } |
| 130 |
| 124 void RetrieveShaderUniformInfo( | 131 void RetrieveShaderUniformInfo( |
| 125 const ShaderUniformProto& proto, UniformMap* map) { | 132 const ShaderUniformProto& proto, UniformMap* map) { |
| 126 sh::Uniform uniform; | 133 sh::Uniform uniform; |
| 127 RetrieveShaderVariableInfo(proto.basic(), &uniform); | 134 RetrieveShaderVariableInfo(proto.basic(), &uniform); |
| 128 (*map)[proto.basic().mapped_name()] = uniform; | 135 (*map)[proto.basic().mapped_name()] = uniform; |
| 129 } | 136 } |
| 130 | 137 |
| 131 void RetrieveShaderVaryingInfo( | 138 void RetrieveShaderVaryingInfo( |
| 132 const ShaderVaryingProto& proto, VaryingMap* map) { | 139 const ShaderVaryingProto& proto, VaryingMap* map) { |
| 133 sh::Varying varying; | 140 sh::Varying varying; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 static_cast<const GLvoid*>(value->data()), | 213 static_cast<const GLvoid*>(value->data()), |
| 207 value->length()); | 214 value->length()); |
| 208 GLint success = 0; | 215 GLint success = 0; |
| 209 glGetProgramiv(program, GL_LINK_STATUS, &success); | 216 glGetProgramiv(program, GL_LINK_STATUS, &success); |
| 210 if (success == GL_FALSE) { | 217 if (success == GL_FALSE) { |
| 211 return PROGRAM_LOAD_FAILURE; | 218 return PROGRAM_LOAD_FAILURE; |
| 212 } | 219 } |
| 213 shader_a->set_attrib_map(value->attrib_map_0()); | 220 shader_a->set_attrib_map(value->attrib_map_0()); |
| 214 shader_a->set_uniform_map(value->uniform_map_0()); | 221 shader_a->set_uniform_map(value->uniform_map_0()); |
| 215 shader_a->set_varying_map(value->varying_map_0()); | 222 shader_a->set_varying_map(value->varying_map_0()); |
| 223 shader_a->set_output_variable_list(value->output_variable_list_0()); |
| 216 shader_b->set_attrib_map(value->attrib_map_1()); | 224 shader_b->set_attrib_map(value->attrib_map_1()); |
| 217 shader_b->set_uniform_map(value->uniform_map_1()); | 225 shader_b->set_uniform_map(value->uniform_map_1()); |
| 218 shader_b->set_varying_map(value->varying_map_1()); | 226 shader_b->set_varying_map(value->varying_map_1()); |
| 227 shader_b->set_output_variable_list(value->output_variable_list_1()); |
| 219 | 228 |
| 220 if (!shader_callback.is_null() && | 229 if (!shader_callback.is_null() && |
| 221 !base::CommandLine::ForCurrentProcess()->HasSwitch( | 230 !base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 222 switches::kDisableGpuShaderDiskCache)) { | 231 switches::kDisableGpuShaderDiskCache)) { |
| 223 scoped_ptr<GpuProgramProto> proto( | 232 scoped_ptr<GpuProgramProto> proto( |
| 224 GpuProgramProto::default_instance().New()); | 233 GpuProgramProto::default_instance().New()); |
| 225 proto->set_sha(sha, kHashLength); | 234 proto->set_sha(sha, kHashLength); |
| 226 proto->set_format(value->format()); | 235 proto->set_format(value->format()); |
| 227 proto->set_program(value->data(), value->length()); | 236 proto->set_program(value->data(), value->length()); |
| 228 | 237 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 GpuProgramProto::default_instance().New()); | 304 GpuProgramProto::default_instance().New()); |
| 296 proto->set_sha(sha, kHashLength); | 305 proto->set_sha(sha, kHashLength); |
| 297 proto->set_format(format); | 306 proto->set_format(format); |
| 298 proto->set_program(binary.get(), length); | 307 proto->set_program(binary.get(), length); |
| 299 | 308 |
| 300 FillShaderProto(proto->mutable_vertex_shader(), a_sha, shader_a); | 309 FillShaderProto(proto->mutable_vertex_shader(), a_sha, shader_a); |
| 301 FillShaderProto(proto->mutable_fragment_shader(), b_sha, shader_b); | 310 FillShaderProto(proto->mutable_fragment_shader(), b_sha, shader_b); |
| 302 RunShaderCallback(shader_callback, proto.get(), sha_string); | 311 RunShaderCallback(shader_callback, proto.get(), sha_string); |
| 303 } | 312 } |
| 304 | 313 |
| 305 store_.Put(sha_string, | 314 store_.Put( |
| 306 new ProgramCacheValue(length, | 315 sha_string, |
| 307 format, | 316 new ProgramCacheValue( |
| 308 binary.release(), | 317 length, format, binary.release(), sha_string, a_sha, |
| 309 sha_string, | 318 shader_a->attrib_map(), shader_a->uniform_map(), |
| 310 a_sha, | 319 shader_a->varying_map(), shader_a->output_variable_list(), b_sha, |
| 311 shader_a->attrib_map(), | 320 shader_b->attrib_map(), shader_b->uniform_map(), |
| 312 shader_a->uniform_map(), | 321 shader_b->varying_map(), shader_b->output_variable_list(), this)); |
| 313 shader_a->varying_map(), | |
| 314 b_sha, | |
| 315 shader_b->attrib_map(), | |
| 316 shader_b->uniform_map(), | |
| 317 shader_b->varying_map(), | |
| 318 this)); | |
| 319 | 322 |
| 320 UMA_HISTOGRAM_COUNTS("GPU.ProgramCache.MemorySizeAfterKb", | 323 UMA_HISTOGRAM_COUNTS("GPU.ProgramCache.MemorySizeAfterKb", |
| 321 curr_size_bytes_ / 1024); | 324 curr_size_bytes_ / 1024); |
| 322 } | 325 } |
| 323 | 326 |
| 324 void MemoryProgramCache::LoadProgram(const std::string& program) { | 327 void MemoryProgramCache::LoadProgram(const std::string& program) { |
| 325 scoped_ptr<GpuProgramProto> proto(GpuProgramProto::default_instance().New()); | 328 scoped_ptr<GpuProgramProto> proto(GpuProgramProto::default_instance().New()); |
| 326 if (proto->ParseFromString(program)) { | 329 if (proto->ParseFromString(program)) { |
| 327 AttributeMap vertex_attribs; | 330 AttributeMap vertex_attribs; |
| 328 UniformMap vertex_uniforms; | 331 UniformMap vertex_uniforms; |
| 329 VaryingMap vertex_varyings; | 332 VaryingMap vertex_varyings; |
| 333 AttributeList vertex_output_variables; |
| 330 for (int i = 0; i < proto->vertex_shader().attribs_size(); i++) { | 334 for (int i = 0; i < proto->vertex_shader().attribs_size(); i++) { |
| 331 RetrieveShaderAttributeInfo(proto->vertex_shader().attribs(i), | 335 RetrieveShaderAttributeInfo(proto->vertex_shader().attribs(i), |
| 332 &vertex_attribs); | 336 &vertex_attribs); |
| 333 } | 337 } |
| 334 for (int i = 0; i < proto->vertex_shader().uniforms_size(); i++) { | 338 for (int i = 0; i < proto->vertex_shader().uniforms_size(); i++) { |
| 335 RetrieveShaderUniformInfo(proto->vertex_shader().uniforms(i), | 339 RetrieveShaderUniformInfo(proto->vertex_shader().uniforms(i), |
| 336 &vertex_uniforms); | 340 &vertex_uniforms); |
| 337 } | 341 } |
| 338 for (int i = 0; i < proto->vertex_shader().varyings_size(); i++) { | 342 for (int i = 0; i < proto->vertex_shader().varyings_size(); i++) { |
| 339 RetrieveShaderVaryingInfo(proto->vertex_shader().varyings(i), | 343 RetrieveShaderVaryingInfo(proto->vertex_shader().varyings(i), |
| 340 &vertex_varyings); | 344 &vertex_varyings); |
| 341 } | 345 } |
| 346 for (int i = 0; i < proto->vertex_shader().output_variables_size(); i++) { |
| 347 RetrieveShaderOutputVariableInfo( |
| 348 proto->vertex_shader().output_variables(i), &vertex_output_variables); |
| 349 } |
| 342 | 350 |
| 343 AttributeMap fragment_attribs; | 351 AttributeMap fragment_attribs; |
| 344 UniformMap fragment_uniforms; | 352 UniformMap fragment_uniforms; |
| 345 VaryingMap fragment_varyings; | 353 VaryingMap fragment_varyings; |
| 354 AttributeList fragment_output_variables; |
| 346 for (int i = 0; i < proto->fragment_shader().attribs_size(); i++) { | 355 for (int i = 0; i < proto->fragment_shader().attribs_size(); i++) { |
| 347 RetrieveShaderAttributeInfo(proto->fragment_shader().attribs(i), | 356 RetrieveShaderAttributeInfo(proto->fragment_shader().attribs(i), |
| 348 &fragment_attribs); | 357 &fragment_attribs); |
| 349 } | 358 } |
| 350 for (int i = 0; i < proto->fragment_shader().uniforms_size(); i++) { | 359 for (int i = 0; i < proto->fragment_shader().uniforms_size(); i++) { |
| 351 RetrieveShaderUniformInfo(proto->fragment_shader().uniforms(i), | 360 RetrieveShaderUniformInfo(proto->fragment_shader().uniforms(i), |
| 352 &fragment_uniforms); | 361 &fragment_uniforms); |
| 353 } | 362 } |
| 354 for (int i = 0; i < proto->fragment_shader().varyings_size(); i++) { | 363 for (int i = 0; i < proto->fragment_shader().varyings_size(); i++) { |
| 355 RetrieveShaderVaryingInfo(proto->fragment_shader().varyings(i), | 364 RetrieveShaderVaryingInfo(proto->fragment_shader().varyings(i), |
| 356 &fragment_varyings); | 365 &fragment_varyings); |
| 357 } | 366 } |
| 367 for (int i = 0; i < proto->fragment_shader().output_variables_size(); i++) { |
| 368 RetrieveShaderOutputVariableInfo( |
| 369 proto->fragment_shader().output_variables(i), |
| 370 &fragment_output_variables); |
| 371 } |
| 358 | 372 |
| 359 scoped_ptr<char[]> binary(new char[proto->program().length()]); | 373 scoped_ptr<char[]> binary(new char[proto->program().length()]); |
| 360 memcpy(binary.get(), proto->program().c_str(), proto->program().length()); | 374 memcpy(binary.get(), proto->program().c_str(), proto->program().length()); |
| 361 | 375 |
| 362 store_.Put(proto->sha(), | 376 store_.Put( |
| 363 new ProgramCacheValue(proto->program().length(), | 377 proto->sha(), |
| 364 proto->format(), | 378 new ProgramCacheValue( |
| 365 binary.release(), | 379 proto->program().length(), proto->format(), binary.release(), |
| 366 proto->sha(), | 380 proto->sha(), proto->vertex_shader().sha().c_str(), vertex_attribs, |
| 367 proto->vertex_shader().sha().c_str(), | 381 vertex_uniforms, vertex_varyings, vertex_output_variables, |
| 368 vertex_attribs, | 382 proto->fragment_shader().sha().c_str(), fragment_attribs, |
| 369 vertex_uniforms, | 383 fragment_uniforms, fragment_varyings, fragment_output_variables, |
| 370 vertex_varyings, | 384 this)); |
| 371 proto->fragment_shader().sha().c_str(), | |
| 372 fragment_attribs, | |
| 373 fragment_uniforms, | |
| 374 fragment_varyings, | |
| 375 this)); | |
| 376 | 385 |
| 377 UMA_HISTOGRAM_COUNTS("GPU.ProgramCache.MemorySizeAfterKb", | 386 UMA_HISTOGRAM_COUNTS("GPU.ProgramCache.MemorySizeAfterKb", |
| 378 curr_size_bytes_ / 1024); | 387 curr_size_bytes_ / 1024); |
| 379 } else { | 388 } else { |
| 380 LOG(ERROR) << "Failed to parse proto file."; | 389 LOG(ERROR) << "Failed to parse proto file."; |
| 381 } | 390 } |
| 382 } | 391 } |
| 383 | 392 |
| 384 MemoryProgramCache::ProgramCacheValue::ProgramCacheValue( | 393 MemoryProgramCache::ProgramCacheValue::ProgramCacheValue( |
| 385 GLsizei length, | 394 GLsizei length, |
| 386 GLenum format, | 395 GLenum format, |
| 387 const char* data, | 396 const char* data, |
| 388 const std::string& program_hash, | 397 const std::string& program_hash, |
| 389 const char* shader_0_hash, | 398 const char* shader_0_hash, |
| 390 const AttributeMap& attrib_map_0, | 399 const AttributeMap& attrib_map_0, |
| 391 const UniformMap& uniform_map_0, | 400 const UniformMap& uniform_map_0, |
| 392 const VaryingMap& varying_map_0, | 401 const VaryingMap& varying_map_0, |
| 402 const AttributeList& output_variable_list_0, |
| 393 const char* shader_1_hash, | 403 const char* shader_1_hash, |
| 394 const AttributeMap& attrib_map_1, | 404 const AttributeMap& attrib_map_1, |
| 395 const UniformMap& uniform_map_1, | 405 const UniformMap& uniform_map_1, |
| 396 const VaryingMap& varying_map_1, | 406 const VaryingMap& varying_map_1, |
| 407 const AttributeList& output_variable_list_1, |
| 397 MemoryProgramCache* program_cache) | 408 MemoryProgramCache* program_cache) |
| 398 : length_(length), | 409 : length_(length), |
| 399 format_(format), | 410 format_(format), |
| 400 data_(data), | 411 data_(data), |
| 401 program_hash_(program_hash), | 412 program_hash_(program_hash), |
| 402 shader_0_hash_(shader_0_hash, kHashLength), | 413 shader_0_hash_(shader_0_hash, kHashLength), |
| 403 attrib_map_0_(attrib_map_0), | 414 attrib_map_0_(attrib_map_0), |
| 404 uniform_map_0_(uniform_map_0), | 415 uniform_map_0_(uniform_map_0), |
| 405 varying_map_0_(varying_map_0), | 416 varying_map_0_(varying_map_0), |
| 417 output_variable_list_0_(output_variable_list_0), |
| 406 shader_1_hash_(shader_1_hash, kHashLength), | 418 shader_1_hash_(shader_1_hash, kHashLength), |
| 407 attrib_map_1_(attrib_map_1), | 419 attrib_map_1_(attrib_map_1), |
| 408 uniform_map_1_(uniform_map_1), | 420 uniform_map_1_(uniform_map_1), |
| 409 varying_map_1_(varying_map_1), | 421 varying_map_1_(varying_map_1), |
| 422 output_variable_list_1_(output_variable_list_1), |
| 410 program_cache_(program_cache) { | 423 program_cache_(program_cache) { |
| 411 program_cache_->curr_size_bytes_ += length_; | 424 program_cache_->curr_size_bytes_ += length_; |
| 412 program_cache_->LinkedProgramCacheSuccess(program_hash); | 425 program_cache_->LinkedProgramCacheSuccess(program_hash); |
| 413 } | 426 } |
| 414 | 427 |
| 415 MemoryProgramCache::ProgramCacheValue::~ProgramCacheValue() { | 428 MemoryProgramCache::ProgramCacheValue::~ProgramCacheValue() { |
| 416 program_cache_->curr_size_bytes_ -= length_; | 429 program_cache_->curr_size_bytes_ -= length_; |
| 417 program_cache_->Evict(program_hash_); | 430 program_cache_->Evict(program_hash_); |
| 418 } | 431 } |
| 419 | 432 |
| 420 } // namespace gles2 | 433 } // namespace gles2 |
| 421 } // namespace gpu | 434 } // namespace gpu |
| OLD | NEW |