Chromium Code Reviews| 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/program_manager.h" | 5 #include "gpu/command_buffer/service/program_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
| 16 #include "base/metrics/histogram.h" | 16 #include "base/metrics/histogram.h" |
| 17 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
| 18 #include "base/strings/string_util.h" | |
| 18 #include "base/time/time.h" | 19 #include "base/time/time.h" |
| 19 #include "gpu/command_buffer/common/gles2_cmd_format.h" | 20 #include "gpu/command_buffer/common/gles2_cmd_format.h" |
| 20 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 21 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
| 21 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 22 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| 22 #include "gpu/command_buffer/service/gpu_switches.h" | 23 #include "gpu/command_buffer/service/gpu_switches.h" |
| 23 #include "gpu/command_buffer/service/program_cache.h" | 24 #include "gpu/command_buffer/service/program_cache.h" |
| 24 #include "gpu/command_buffer/service/shader_manager.h" | 25 #include "gpu/command_buffer/service/shader_manager.h" |
| 25 #include "gpu/command_buffer/service/shader_translator.h" | 26 #include "gpu/command_buffer/service/shader_translator.h" |
| 26 #include "third_party/re2/re2/re2.h" | 27 #include "third_party/re2/re2/re2.h" |
| 27 | 28 |
| 28 using base::TimeDelta; | 29 using base::TimeDelta; |
| 29 using base::TimeTicks; | 30 using base::TimeTicks; |
| 30 | 31 |
| 31 namespace gpu { | 32 namespace gpu { |
| 32 namespace gles2 { | 33 namespace gles2 { |
| 33 | 34 |
| 34 namespace { | 35 namespace { |
| 35 | 36 |
| 36 struct UniformType { | |
| 37 explicit UniformType(const ShaderTranslator::VariableInfo uniform) | |
| 38 : type(uniform.type), | |
| 39 size(uniform.size), | |
| 40 precision(uniform.precision) { } | |
| 41 | |
| 42 UniformType() | |
| 43 : type(0), | |
| 44 size(0), | |
| 45 precision(SH_PRECISION_MEDIUMP) { } | |
| 46 | |
| 47 bool operator==(const UniformType& other) const { | |
| 48 return type == other.type && | |
| 49 size == other.size && | |
| 50 precision == other.precision; | |
| 51 } | |
| 52 | |
| 53 int type; | |
| 54 int size; | |
| 55 int precision; | |
| 56 }; | |
| 57 | |
| 58 int ShaderTypeToIndex(GLenum shader_type) { | 37 int ShaderTypeToIndex(GLenum shader_type) { |
| 59 switch (shader_type) { | 38 switch (shader_type) { |
| 60 case GL_VERTEX_SHADER: | 39 case GL_VERTEX_SHADER: |
| 61 return 0; | 40 return 0; |
| 62 case GL_FRAGMENT_SHADER: | 41 case GL_FRAGMENT_SHADER: |
| 63 return 1; | 42 return 1; |
| 64 default: | 43 default: |
| 65 NOTREACHED(); | 44 NOTREACHED(); |
| 66 return 0; | 45 return 0; |
| 67 } | 46 } |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 382 scoped_ptr<char[]> name_buffer(new char[max_len]); | 361 scoped_ptr<char[]> name_buffer(new char[max_len]); |
| 383 for (GLint ii = 0; ii < num_attribs; ++ii) { | 362 for (GLint ii = 0; ii < num_attribs; ++ii) { |
| 384 GLsizei length = 0; | 363 GLsizei length = 0; |
| 385 GLsizei size = 0; | 364 GLsizei size = 0; |
| 386 GLenum type = 0; | 365 GLenum type = 0; |
| 387 glGetActiveAttrib( | 366 glGetActiveAttrib( |
| 388 service_id_, ii, max_len, &length, &size, &type, name_buffer.get()); | 367 service_id_, ii, max_len, &length, &size, &type, name_buffer.get()); |
| 389 DCHECK(max_len == 0 || length < max_len); | 368 DCHECK(max_len == 0 || length < max_len); |
| 390 DCHECK(length == 0 || name_buffer[length] == '\0'); | 369 DCHECK(length == 0 || name_buffer[length] == '\0'); |
| 391 if (!ProgramManager::IsInvalidPrefix(name_buffer.get(), length)) { | 370 if (!ProgramManager::IsInvalidPrefix(name_buffer.get(), length)) { |
| 392 std::string name; | |
| 393 std::string original_name; | 371 std::string original_name; |
| 394 GetCorrectedVariableInfo( | 372 GetCorrectedVertexAttrib(name_buffer.get(), &original_name, &type); |
| 395 false, name_buffer.get(), &name, &original_name, &size, &type); | |
| 396 // TODO(gman): Should we check for error? | 373 // TODO(gman): Should we check for error? |
| 397 GLint location = glGetAttribLocation(service_id_, name_buffer.get()); | 374 GLint location = glGetAttribLocation(service_id_, name_buffer.get()); |
| 398 if (location > max_location) { | 375 if (location > max_location) { |
| 399 max_location = location; | 376 max_location = location; |
| 400 } | 377 } |
| 401 attrib_infos_.push_back( | 378 attrib_infos_.push_back( |
| 402 VertexAttrib(size, type, original_name, location)); | 379 VertexAttrib(1, type, original_name, location)); |
| 403 max_attrib_name_length_ = std::max( | 380 max_attrib_name_length_ = std::max( |
| 404 max_attrib_name_length_, static_cast<GLsizei>(original_name.size())); | 381 max_attrib_name_length_, static_cast<GLsizei>(original_name.size())); |
| 405 } | 382 } |
| 406 } | 383 } |
| 407 | 384 |
| 408 // Create attrib location to index map. | 385 // Create attrib location to index map. |
| 409 attrib_location_to_index_map_.resize(max_location + 1); | 386 attrib_location_to_index_map_.resize(max_location + 1); |
| 410 for (GLint ii = 0; ii <= max_location; ++ii) { | 387 for (GLint ii = 0; ii <= max_location; ++ii) { |
| 411 attrib_location_to_index_map_[ii] = -1; | 388 attrib_location_to_index_map_[ii] = -1; |
| 412 } | 389 } |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 440 for (GLint ii = 0; ii < num_uniforms; ++ii) { | 417 for (GLint ii = 0; ii < num_uniforms; ++ii) { |
| 441 GLsizei length = 0; | 418 GLsizei length = 0; |
| 442 UniformData data; | 419 UniformData data; |
| 443 glGetActiveUniform( | 420 glGetActiveUniform( |
| 444 service_id_, ii, max_len, &length, | 421 service_id_, ii, max_len, &length, |
| 445 &data.size, &data.type, name_buffer.get()); | 422 &data.size, &data.type, name_buffer.get()); |
| 446 DCHECK(max_len == 0 || length < max_len); | 423 DCHECK(max_len == 0 || length < max_len); |
| 447 DCHECK(length == 0 || name_buffer[length] == '\0'); | 424 DCHECK(length == 0 || name_buffer[length] == '\0'); |
| 448 if (!ProgramManager::IsInvalidPrefix(name_buffer.get(), length)) { | 425 if (!ProgramManager::IsInvalidPrefix(name_buffer.get(), length)) { |
| 449 data.queried_name = std::string(name_buffer.get()); | 426 data.queried_name = std::string(name_buffer.get()); |
| 450 GetCorrectedVariableInfo( | 427 GetCorrectedUniformData( |
| 451 true, name_buffer.get(), &data.corrected_name, &data.original_name, | 428 data.queried_name, |
| 452 &data.size, &data.type); | 429 &data.corrected_name, &data.original_name, &data.size, &data.type); |
| 453 uniform_data.push_back(data); | 430 uniform_data.push_back(data); |
| 454 } | 431 } |
| 455 } | 432 } |
| 456 | 433 |
| 457 // NOTE: We don't care if 2 uniforms are bound to the same location. | 434 // NOTE: We don't care if 2 uniforms are bound to the same location. |
| 458 // One of them will take preference. The spec allows this, same as | 435 // One of them will take preference. The spec allows this, same as |
| 459 // BindAttribLocation. | 436 // BindAttribLocation. |
| 460 // | 437 // |
| 461 // The reason we don't check is if we were to fail we'd have to | 438 // The reason we don't check is if we were to fail we'd have to |
| 462 // restore the previous program but since we've already linked successfully | 439 // restore the previous program but since we've already linked successfully |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 750 element_index != 0) { | 727 element_index != 0) { |
| 751 return false; | 728 return false; |
| 752 } | 729 } |
| 753 | 730 |
| 754 bind_uniform_location_map_[short_name] = location; | 731 bind_uniform_location_map_[short_name] = location; |
| 755 return true; | 732 return true; |
| 756 } | 733 } |
| 757 | 734 |
| 758 // Note: This is only valid to call right after a program has been linked | 735 // Note: This is only valid to call right after a program has been linked |
| 759 // successfully. | 736 // successfully. |
| 760 void Program::GetCorrectedVariableInfo( | 737 void Program::GetCorrectedUniformData( |
| 761 bool use_uniforms, | 738 const std::string& name, |
| 762 const std::string& name, std::string* corrected_name, | 739 std::string* corrected_name, std::string* original_name, |
| 763 std::string* original_name, | |
| 764 GLsizei* size, GLenum* type) const { | 740 GLsizei* size, GLenum* type) const { |
| 765 DCHECK(corrected_name); | 741 DCHECK(corrected_name && original_name && size && type); |
| 766 DCHECK(original_name); | 742 for (int ii = 0; ii < kMaxAttachedShaders; ++ii) { |
| 767 DCHECK(size); | 743 Shader* shader = attached_shaders_[ii].get(); |
| 768 DCHECK(type); | 744 if (!shader) |
| 769 const char* kArraySpec = "[0]"; | 745 continue; |
| 770 for (int jj = 0; jj < 2; ++jj) { | 746 const sh::ShaderVariable* info = NULL; |
| 771 std::string test_name(name + ((jj == 1) ? kArraySpec : "")); | 747 const sh::Uniform* uniform = shader->GetUniformInfo(name); |
| 772 for (int ii = 0; ii < kMaxAttachedShaders; ++ii) { | 748 bool found = false; |
| 773 Shader* shader = attached_shaders_[ii].get(); | 749 if (uniform) |
| 774 if (shader) { | 750 found = uniform->findInfoByMappedName(name, &info, original_name); |
| 775 const Shader::VariableInfo* variable_info = | 751 if (found) { |
| 776 use_uniforms ? shader->GetUniformInfo(test_name) : | 752 const std::string kArraySpec("[0]"); |
| 777 shader->GetAttribInfo(test_name); | 753 if (info->arraySize > 0 && !EndsWith(name, kArraySpec, true)) { |
| 778 // Note: There is an assuption here that if an attrib is defined in more | 754 *corrected_name = name + kArraySpec; |
| 779 // than 1 attached shader their types and sizes match. Should we check | 755 *original_name += kArraySpec; |
| 780 // for that case? | 756 } else { |
| 781 if (variable_info) { | 757 *corrected_name = name; |
| 782 *corrected_name = test_name; | |
| 783 *original_name = variable_info->name; | |
| 784 *type = variable_info->type; | |
| 785 *size = variable_info->size; | |
| 786 return; | |
| 787 } | |
| 788 } | 758 } |
| 759 *type = info->type; | |
| 760 *size = std::max(1, info->arraySize); | |
| 761 return; | |
| 789 } | 762 } |
| 790 } | 763 } |
| 791 *corrected_name = name; | 764 *corrected_name = name; |
| 792 *original_name = name; | 765 *original_name = name; |
|
Ken Russell (switch to Gerrit)
2014/10/07 03:35:26
Why is it OK to silently pass through the incoming
Zhenyao Mo
2014/10/07 18:23:40
Good question. In theory this path should never b
| |
| 793 } | 766 } |
| 794 | 767 |
| 768 void Program::GetCorrectedVertexAttrib( | |
| 769 const std::string& name, std::string* original_name, GLenum* type) const { | |
| 770 DCHECK(original_name); | |
| 771 DCHECK(type); | |
| 772 Shader* shader = attached_shaders_[ShaderTypeToIndex(GL_VERTEX_SHADER)].get(); | |
| 773 if (shader) { | |
| 774 const sh::Attribute* info = shader->GetAttribInfo(name); | |
|
Ken Russell (switch to Gerrit)
2014/10/07 03:35:26
Somewhere it should be documented that vertex attr
Zhenyao Mo
2014/10/07 18:23:40
Done.
| |
| 775 if (info) { | |
| 776 *original_name = info->name; | |
| 777 *type = info->type; | |
| 778 return; | |
| 779 } | |
| 780 } | |
| 781 *original_name = name; | |
|
Ken Russell (switch to Gerrit)
2014/10/07 03:35:26
Why is it OK to silently pass through the incoming
Zhenyao Mo
2014/10/07 18:23:40
Same reply as above.
| |
| 782 } | |
| 783 | |
| 795 bool Program::AddUniformInfo( | 784 bool Program::AddUniformInfo( |
| 796 GLsizei size, GLenum type, GLint location, GLint fake_base_location, | 785 GLsizei size, GLenum type, GLint location, GLint fake_base_location, |
| 797 const std::string& name, const std::string& original_name, | 786 const std::string& name, const std::string& original_name, |
| 798 size_t* next_available_index) { | 787 size_t* next_available_index) { |
| 799 DCHECK(next_available_index); | 788 DCHECK(next_available_index); |
| 800 const char* kArraySpec = "[0]"; | 789 const char* kArraySpec = "[0]"; |
| 801 size_t uniform_index = | 790 size_t uniform_index = |
| 802 fake_base_location >= 0 ? fake_base_location : *next_available_index; | 791 fake_base_location >= 0 ? fake_base_location : *next_available_index; |
| 803 if (uniform_infos_.size() < uniform_index + 1) { | 792 if (uniform_infos_.size() < uniform_index + 1) { |
| 804 uniform_infos_.resize(uniform_index + 1); | 793 uniform_infos_.resize(uniform_index + 1); |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1007 std::pair<std::set<GLint>::iterator, bool> result = | 996 std::pair<std::set<GLint>::iterator, bool> result = |
| 1008 location_binding_used.insert(it->second); | 997 location_binding_used.insert(it->second); |
| 1009 if (!result.second) | 998 if (!result.second) |
| 1010 return true; | 999 return true; |
| 1011 } | 1000 } |
| 1012 } | 1001 } |
| 1013 return false; | 1002 return false; |
| 1014 } | 1003 } |
| 1015 | 1004 |
| 1016 bool Program::DetectUniformsMismatch(std::string* conflicting_name) const { | 1005 bool Program::DetectUniformsMismatch(std::string* conflicting_name) const { |
| 1017 typedef std::map<std::string, UniformType> UniformMap; | 1006 typedef std::map<std::string, const sh::Uniform*> UniformPointerMap; |
| 1018 UniformMap uniform_map; | 1007 UniformPointerMap uniform_pointer_map; |
| 1019 for (int ii = 0; ii < kMaxAttachedShaders; ++ii) { | 1008 for (int ii = 0; ii < kMaxAttachedShaders; ++ii) { |
| 1020 const ShaderTranslator::VariableMap& shader_uniforms = | 1009 const UniformMap& shader_uniforms = attached_shaders_[ii]->uniform_map(); |
| 1021 attached_shaders_[ii]->uniform_map(); | 1010 for (UniformMap::const_iterator iter = shader_uniforms.begin(); |
| 1022 for (ShaderTranslator::VariableMap::const_iterator iter = | |
| 1023 shader_uniforms.begin(); | |
| 1024 iter != shader_uniforms.end(); ++iter) { | 1011 iter != shader_uniforms.end(); ++iter) { |
| 1025 const std::string& name = iter->first; | 1012 const std::string& name = iter->first; |
| 1026 UniformType type(iter->second); | 1013 UniformPointerMap::iterator hit = uniform_pointer_map.find(name); |
| 1027 UniformMap::iterator map_entry = uniform_map.find(name); | 1014 if (hit == uniform_pointer_map.end()) { |
| 1028 if (map_entry == uniform_map.end()) { | 1015 uniform_pointer_map[name] = &(iter->second); |
| 1029 uniform_map[name] = type; | |
| 1030 } else { | 1016 } else { |
| 1031 // If a uniform is already in the map, i.e., it has already been | 1017 // If a uniform is in the map, i.e., it has already been declared by |
| 1032 // declared by other shader, then the type and precision must match. | 1018 // another shader, then the type, precision, etc. must match. |
| 1033 if (map_entry->second == type) | 1019 if (hit->second->isSameUniformAtLinkTime(iter->second)) |
| 1034 continue; | 1020 continue; |
| 1035 *conflicting_name = name; | 1021 *conflicting_name = name; |
| 1036 return true; | 1022 return true; |
| 1037 } | 1023 } |
| 1038 } | 1024 } |
| 1039 } | 1025 } |
| 1040 return false; | 1026 return false; |
| 1041 } | 1027 } |
| 1042 | 1028 |
| 1043 bool Program::DetectVaryingsMismatch(std::string* conflicting_name) const { | 1029 bool Program::DetectVaryingsMismatch(std::string* conflicting_name) const { |
| 1044 DCHECK(attached_shaders_[0].get() && | 1030 DCHECK(attached_shaders_[0].get() && |
| 1045 attached_shaders_[0]->shader_type() == GL_VERTEX_SHADER && | 1031 attached_shaders_[0]->shader_type() == GL_VERTEX_SHADER && |
| 1046 attached_shaders_[1].get() && | 1032 attached_shaders_[1].get() && |
| 1047 attached_shaders_[1]->shader_type() == GL_FRAGMENT_SHADER); | 1033 attached_shaders_[1]->shader_type() == GL_FRAGMENT_SHADER); |
| 1048 const ShaderTranslator::VariableMap* vertex_varyings = | 1034 const VaryingMap* vertex_varyings = &(attached_shaders_[0]->varying_map()); |
| 1049 &(attached_shaders_[0]->varying_map()); | 1035 const VaryingMap* fragment_varyings = &(attached_shaders_[1]->varying_map()); |
| 1050 const ShaderTranslator::VariableMap* fragment_varyings = | |
| 1051 &(attached_shaders_[1]->varying_map()); | |
| 1052 | 1036 |
| 1053 for (ShaderTranslator::VariableMap::const_iterator iter = | 1037 for (VaryingMap::const_iterator iter = fragment_varyings->begin(); |
| 1054 fragment_varyings->begin(); | |
| 1055 iter != fragment_varyings->end(); ++iter) { | 1038 iter != fragment_varyings->end(); ++iter) { |
| 1056 const std::string& name = iter->first; | 1039 const std::string& name = iter->first; |
| 1057 if (IsBuiltInVarying(name)) | 1040 if (IsBuiltInVarying(name)) |
| 1058 continue; | 1041 continue; |
| 1059 | 1042 |
| 1060 ShaderTranslator::VariableMap::const_iterator hit = | 1043 VaryingMap::const_iterator hit = vertex_varyings->find(name); |
| 1061 vertex_varyings->find(name); | |
| 1062 if (hit == vertex_varyings->end()) { | 1044 if (hit == vertex_varyings->end()) { |
| 1063 if (iter->second.static_use) { | 1045 if (iter->second.staticUse) { |
| 1064 *conflicting_name = name; | 1046 *conflicting_name = name; |
| 1065 return true; | 1047 return true; |
| 1066 } | 1048 } |
| 1067 continue; | 1049 continue; |
| 1068 } | 1050 } |
| 1069 | 1051 |
| 1070 if (hit->second.type != iter->second.type || | 1052 if (!hit->second.isSameVaryingAtLinkTime(iter->second)) { |
| 1071 hit->second.size != iter->second.size) { | |
| 1072 *conflicting_name = name; | 1053 *conflicting_name = name; |
| 1073 return true; | 1054 return true; |
| 1074 } | 1055 } |
| 1075 | 1056 |
| 1076 } | 1057 } |
| 1077 return false; | 1058 return false; |
| 1078 } | 1059 } |
| 1079 | 1060 |
| 1080 bool Program::DetectGlobalNameConflicts(std::string* conflicting_name) const { | 1061 bool Program::DetectGlobalNameConflicts(std::string* conflicting_name) const { |
| 1081 DCHECK(attached_shaders_[0].get() && | 1062 DCHECK(attached_shaders_[0].get() && |
| 1082 attached_shaders_[0]->shader_type() == GL_VERTEX_SHADER && | 1063 attached_shaders_[0]->shader_type() == GL_VERTEX_SHADER && |
| 1083 attached_shaders_[1].get() && | 1064 attached_shaders_[1].get() && |
| 1084 attached_shaders_[1]->shader_type() == GL_FRAGMENT_SHADER); | 1065 attached_shaders_[1]->shader_type() == GL_FRAGMENT_SHADER); |
| 1085 const ShaderTranslator::VariableMap* uniforms[2]; | 1066 const UniformMap* uniforms[2]; |
| 1086 uniforms[0] = &(attached_shaders_[0]->uniform_map()); | 1067 uniforms[0] = &(attached_shaders_[0]->uniform_map()); |
| 1087 uniforms[1] = &(attached_shaders_[1]->uniform_map()); | 1068 uniforms[1] = &(attached_shaders_[1]->uniform_map()); |
| 1088 const ShaderTranslator::VariableMap* attribs = | 1069 const AttributeMap* attribs = |
| 1089 &(attached_shaders_[0]->attrib_map()); | 1070 &(attached_shaders_[0]->attrib_map()); |
| 1090 | 1071 |
| 1091 for (ShaderTranslator::VariableMap::const_iterator iter = | 1072 for (AttributeMap::const_iterator iter = attribs->begin(); |
| 1092 attribs->begin(); iter != attribs->end(); ++iter) { | 1073 iter != attribs->end(); ++iter) { |
| 1093 for (int ii = 0; ii < 2; ++ii) { | 1074 for (int ii = 0; ii < 2; ++ii) { |
| 1094 if (uniforms[ii]->find(iter->first) != uniforms[ii]->end()) { | 1075 if (uniforms[ii]->find(iter->first) != uniforms[ii]->end()) { |
| 1095 *conflicting_name = iter->first; | 1076 *conflicting_name = iter->first; |
| 1096 return true; | 1077 return true; |
| 1097 } | 1078 } |
| 1098 } | 1079 } |
| 1099 } | 1080 } |
| 1100 return false; | 1081 return false; |
| 1101 } | 1082 } |
| 1102 | 1083 |
| 1103 bool Program::CheckVaryingsPacking( | 1084 bool Program::CheckVaryingsPacking( |
| 1104 Program::VaryingsPackingOption option) const { | 1085 Program::VaryingsPackingOption option) const { |
| 1105 DCHECK(attached_shaders_[0].get() && | 1086 DCHECK(attached_shaders_[0].get() && |
| 1106 attached_shaders_[0]->shader_type() == GL_VERTEX_SHADER && | 1087 attached_shaders_[0]->shader_type() == GL_VERTEX_SHADER && |
| 1107 attached_shaders_[1].get() && | 1088 attached_shaders_[1].get() && |
| 1108 attached_shaders_[1]->shader_type() == GL_FRAGMENT_SHADER); | 1089 attached_shaders_[1]->shader_type() == GL_FRAGMENT_SHADER); |
| 1109 const ShaderTranslator::VariableMap* vertex_varyings = | 1090 const VaryingMap* vertex_varyings = &(attached_shaders_[0]->varying_map()); |
| 1110 &(attached_shaders_[0]->varying_map()); | 1091 const VaryingMap* fragment_varyings = &(attached_shaders_[1]->varying_map()); |
| 1111 const ShaderTranslator::VariableMap* fragment_varyings = | |
| 1112 &(attached_shaders_[1]->varying_map()); | |
| 1113 | 1092 |
| 1114 std::map<std::string, ShVariableInfo> combined_map; | 1093 std::map<std::string, ShVariableInfo> combined_map; |
| 1115 | 1094 |
| 1116 for (ShaderTranslator::VariableMap::const_iterator iter = | 1095 for (VaryingMap::const_iterator iter = fragment_varyings->begin(); |
| 1117 fragment_varyings->begin(); | |
| 1118 iter != fragment_varyings->end(); ++iter) { | 1096 iter != fragment_varyings->end(); ++iter) { |
| 1119 if (!iter->second.static_use && option == kCountOnlyStaticallyUsed) | 1097 if (!iter->second.staticUse && option == kCountOnlyStaticallyUsed) |
| 1120 continue; | 1098 continue; |
| 1121 if (!IsBuiltInVarying(iter->first)) { | 1099 if (!IsBuiltInVarying(iter->first)) { |
| 1122 ShaderTranslator::VariableMap::const_iterator vertex_iter = | 1100 VaryingMap::const_iterator vertex_iter = |
| 1123 vertex_varyings->find(iter->first); | 1101 vertex_varyings->find(iter->first); |
| 1124 if (vertex_iter == vertex_varyings->end() || | 1102 if (vertex_iter == vertex_varyings->end() || |
| 1125 (!vertex_iter->second.static_use && | 1103 (!vertex_iter->second.staticUse && |
| 1126 option == kCountOnlyStaticallyUsed)) | 1104 option == kCountOnlyStaticallyUsed)) |
| 1127 continue; | 1105 continue; |
| 1128 } | 1106 } |
| 1129 | 1107 |
| 1130 ShVariableInfo var; | 1108 ShVariableInfo var; |
| 1131 var.type = static_cast<sh::GLenum>(iter->second.type); | 1109 var.type = static_cast<sh::GLenum>(iter->second.type); |
| 1132 var.size = iter->second.size; | 1110 var.size = std::max(1, iter->second.arraySize); |
| 1133 combined_map[iter->first] = var; | 1111 combined_map[iter->first] = var; |
| 1134 } | 1112 } |
| 1135 | 1113 |
| 1136 if (combined_map.size() == 0) | 1114 if (combined_map.size() == 0) |
| 1137 return true; | 1115 return true; |
| 1138 scoped_ptr<ShVariableInfo[]> variables( | 1116 scoped_ptr<ShVariableInfo[]> variables( |
| 1139 new ShVariableInfo[combined_map.size()]); | 1117 new ShVariableInfo[combined_map.size()]); |
| 1140 size_t index = 0; | 1118 size_t index = 0; |
| 1141 for (std::map<std::string, ShVariableInfo>::const_iterator iter = | 1119 for (std::map<std::string, ShVariableInfo>::const_iterator iter = |
| 1142 combined_map.begin(); | 1120 combined_map.begin(); |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1365 DCHECK(program); | 1343 DCHECK(program); |
| 1366 program->ClearUniforms(&zero_); | 1344 program->ClearUniforms(&zero_); |
| 1367 } | 1345 } |
| 1368 | 1346 |
| 1369 int32 ProgramManager::MakeFakeLocation(int32 index, int32 element) { | 1347 int32 ProgramManager::MakeFakeLocation(int32 index, int32 element) { |
| 1370 return index + element * 0x10000; | 1348 return index + element * 0x10000; |
| 1371 } | 1349 } |
| 1372 | 1350 |
| 1373 } // namespace gles2 | 1351 } // namespace gles2 |
| 1374 } // namespace gpu | 1352 } // namespace gpu |
| OLD | NEW |