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 |