| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 #include "base/basictypes.h" | 6 #include "base/basictypes.h" |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/scoped_ptr.h" | 8 #include "base/scoped_ptr.h" |
| 9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 10 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 10 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| 11 | 11 |
| 12 namespace gpu { | 12 namespace gpu { |
| 13 namespace gles2 { | 13 namespace gles2 { |
| 14 | 14 |
| 15 bool ProgramManager::IsInvalidPrefix(const char* name, size_t length) { | 15 bool ProgramManager::IsInvalidPrefix(const char* name, size_t length) { |
| 16 static const char kInvalidPrefix[] = { 'g', 'l', '_' }; | 16 static const char kInvalidPrefix[] = { 'g', 'l', '_' }; |
| 17 return (length >= sizeof(kInvalidPrefix) && | 17 return (length >= sizeof(kInvalidPrefix) && |
| 18 memcmp(name, kInvalidPrefix, sizeof(kInvalidPrefix)) == 0); | 18 memcmp(name, kInvalidPrefix, sizeof(kInvalidPrefix)) == 0); |
| 19 } | 19 } |
| 20 | 20 |
| 21 void ProgramManager::ProgramInfo::Reset() { |
| 22 valid_ = false; |
| 23 max_uniform_name_length_ = 0; |
| 24 max_attrib_name_length_ = 0; |
| 25 attrib_infos_.clear(); |
| 26 uniform_infos_.clear(); |
| 27 sampler_indices_.clear(); |
| 28 location_to_index_map_.clear(); |
| 29 } |
| 30 |
| 21 void ProgramManager::ProgramInfo::Update() { | 31 void ProgramManager::ProgramInfo::Update() { |
| 32 Reset(); |
| 22 GLint num_attribs = 0; | 33 GLint num_attribs = 0; |
| 23 GLint max_len = 0; | 34 GLint max_len = 0; |
| 24 max_uniform_name_length_ = 0; | 35 glGetProgramiv(service_id_, GL_ACTIVE_ATTRIBUTES, &num_attribs); |
| 25 max_attrib_name_length_ = 0; | 36 glGetProgramiv(service_id_, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_len); |
| 26 glGetProgramiv(program_id_, GL_ACTIVE_ATTRIBUTES, &num_attribs); | |
| 27 glGetProgramiv(program_id_, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_len); | |
| 28 // TODO(gman): Should we check for error? | 37 // TODO(gman): Should we check for error? |
| 29 scoped_array<char> name_buffer(new char[max_len]); | 38 scoped_array<char> name_buffer(new char[max_len]); |
| 30 attrib_infos_.clear(); | |
| 31 for (GLint ii = 0; ii < num_attribs; ++ii) { | 39 for (GLint ii = 0; ii < num_attribs; ++ii) { |
| 32 GLsizei length; | 40 GLsizei length; |
| 33 GLsizei size; | 41 GLsizei size; |
| 34 GLenum type; | 42 GLenum type; |
| 35 glGetActiveAttrib( | 43 glGetActiveAttrib( |
| 36 program_id_, ii, max_len, &length, &size, &type, name_buffer.get()); | 44 service_id_, ii, max_len, &length, &size, &type, name_buffer.get()); |
| 37 if (!IsInvalidPrefix(name_buffer.get(), length)) { | 45 if (!IsInvalidPrefix(name_buffer.get(), length)) { |
| 38 // TODO(gman): Should we check for error? | 46 // TODO(gman): Should we check for error? |
| 39 GLint location = glGetAttribLocation(program_id_, name_buffer.get()); | 47 GLint location = glGetAttribLocation(service_id_, name_buffer.get()); |
| 40 attrib_infos_.push_back( | 48 attrib_infos_.push_back( |
| 41 VertexAttribInfo(size, type, name_buffer.get(), location)); | 49 VertexAttribInfo(size, type, name_buffer.get(), location)); |
| 42 max_attrib_name_length_ = std::max(max_attrib_name_length_, length); | 50 max_attrib_name_length_ = std::max(max_attrib_name_length_, length); |
| 43 } | 51 } |
| 44 } | 52 } |
| 45 | 53 |
| 46 GLint num_uniforms; | 54 GLint num_uniforms; |
| 47 glGetProgramiv(program_id_, GL_ACTIVE_UNIFORMS, &num_uniforms); | 55 glGetProgramiv(service_id_, GL_ACTIVE_UNIFORMS, &num_uniforms); |
| 48 uniform_infos_.clear(); | 56 glGetProgramiv(service_id_, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_len); |
| 49 sampler_indices_.clear(); | |
| 50 glGetProgramiv(program_id_, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_len); | |
| 51 name_buffer.reset(new char[max_len]); | 57 name_buffer.reset(new char[max_len]); |
| 52 GLint max_location = -1; | 58 GLint max_location = -1; |
| 53 int index = 0; // this index tracks valid uniforms. | 59 int index = 0; // this index tracks valid uniforms. |
| 54 for (GLint ii = 0; ii < num_uniforms; ++ii) { | 60 for (GLint ii = 0; ii < num_uniforms; ++ii) { |
| 55 GLsizei length; | 61 GLsizei length; |
| 56 GLsizei size; | 62 GLsizei size; |
| 57 GLenum type; | 63 GLenum type; |
| 58 glGetActiveUniform( | 64 glGetActiveUniform( |
| 59 program_id_, ii, max_len, &length, &size, &type, name_buffer.get()); | 65 service_id_, ii, max_len, &length, &size, &type, name_buffer.get()); |
| 60 // TODO(gman): Should we check for error? | 66 // TODO(gman): Should we check for error? |
| 61 if (!IsInvalidPrefix(name_buffer.get(), length)) { | 67 if (!IsInvalidPrefix(name_buffer.get(), length)) { |
| 62 GLint location = glGetUniformLocation(program_id_, name_buffer.get()); | 68 GLint location = glGetUniformLocation(service_id_, name_buffer.get()); |
| 63 const UniformInfo* info = | 69 const UniformInfo* info = |
| 64 AddUniformInfo(size, type, location, name_buffer.get()); | 70 AddUniformInfo(size, type, location, name_buffer.get()); |
| 65 for (size_t jj = 0; jj < info->element_locations.size(); ++jj) { | 71 for (size_t jj = 0; jj < info->element_locations.size(); ++jj) { |
| 66 if (info->element_locations[jj] > max_location) { | 72 if (info->element_locations[jj] > max_location) { |
| 67 max_location = info->element_locations[jj]; | 73 max_location = info->element_locations[jj]; |
| 68 } | 74 } |
| 69 } | 75 } |
| 70 if (info->IsSampler()) { | 76 if (info->IsSampler()) { |
| 71 sampler_indices_.push_back(index); | 77 sampler_indices_.push_back(index); |
| 72 } | 78 } |
| 73 max_uniform_name_length_ = | 79 max_uniform_name_length_ = |
| 74 std::max(max_uniform_name_length_, | 80 std::max(max_uniform_name_length_, |
| 75 static_cast<GLsizei>(info->name.size())); | 81 static_cast<GLsizei>(info->name.size())); |
| 76 ++index; | 82 ++index; |
| 77 } | 83 } |
| 78 } | 84 } |
| 79 // Create location to index map. | 85 // Create location to index map. |
| 80 location_to_index_map_.resize(max_location + 1); | 86 location_to_index_map_.resize(max_location + 1); |
| 81 for (GLint ii = 0; ii <= max_location; ++ii) { | 87 for (GLint ii = 0; ii <= max_location; ++ii) { |
| 82 location_to_index_map_[ii] = -1; | 88 location_to_index_map_[ii] = -1; |
| 83 } | 89 } |
| 84 for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { | 90 for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { |
| 85 const UniformInfo& info = uniform_infos_[ii]; | 91 const UniformInfo& info = uniform_infos_[ii]; |
| 86 for (size_t jj = 0; jj < info.element_locations.size(); ++jj) { | 92 for (size_t jj = 0; jj < info.element_locations.size(); ++jj) { |
| 87 location_to_index_map_[info.element_locations[jj]] = ii; | 93 location_to_index_map_[info.element_locations[jj]] = ii; |
| 88 } | 94 } |
| 89 } | 95 } |
| 96 valid_ = true; |
| 90 } | 97 } |
| 91 | 98 |
| 92 GLint ProgramManager::ProgramInfo::GetUniformLocation( | 99 GLint ProgramManager::ProgramInfo::GetUniformLocation( |
| 93 const std::string& name) const { | 100 const std::string& name) const { |
| 94 for (GLuint ii = 0; ii < uniform_infos_.size(); ++ii) { | 101 for (GLuint ii = 0; ii < uniform_infos_.size(); ++ii) { |
| 95 const UniformInfo& info = uniform_infos_[ii]; | 102 const UniformInfo& info = uniform_infos_[ii]; |
| 96 if (info.name == name || | 103 if (info.name == name || |
| 97 (info.is_array && | 104 (info.is_array && |
| 98 info.name.compare(0, info.name.size() - 3, name) == 0)) { | 105 info.name.compare(0, info.name.size() - 3, name) == 0)) { |
| 99 return info.element_locations[0]; | 106 return info.element_locations[0]; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 info.element_locations.resize(size); | 165 info.element_locations.resize(size); |
| 159 info.element_locations[0] = location; | 166 info.element_locations[0] = location; |
| 160 size_t num_texture_units = info.IsSampler() ? size : 0u; | 167 size_t num_texture_units = info.IsSampler() ? size : 0u; |
| 161 info.texture_units.clear(); | 168 info.texture_units.clear(); |
| 162 info.texture_units.resize(num_texture_units, 0); | 169 info.texture_units.resize(num_texture_units, 0); |
| 163 | 170 |
| 164 if (size > 1) { | 171 if (size > 1) { |
| 165 for (GLsizei ii = 1; ii < info.size; ++ii) { | 172 for (GLsizei ii = 1; ii < info.size; ++ii) { |
| 166 std::string element_name(name + "[" + IntToString(ii) + "]"); | 173 std::string element_name(name + "[" + IntToString(ii) + "]"); |
| 167 info.element_locations[ii] = | 174 info.element_locations[ii] = |
| 168 glGetUniformLocation(program_id_, element_name.c_str()); | 175 glGetUniformLocation(service_id_, element_name.c_str()); |
| 169 } | 176 } |
| 170 // Sadly there is no way to tell if this is an array except if the name | 177 // Sadly there is no way to tell if this is an array except if the name |
| 171 // has an array string or the size > 1. That means an array of size 1 can | 178 // has an array string or the size > 1. That means an array of size 1 can |
| 172 // be ambiguous. | 179 // be ambiguous. |
| 173 // | 180 // |
| 174 // For now we just make sure that if the size is > 1 then the name must have | 181 // For now we just make sure that if the size is > 1 then the name must have |
| 175 // an array spec. | 182 // an array spec. |
| 176 | 183 |
| 177 // Go through the array element locations looking for a match. | 184 // Go through the array element locations looking for a match. |
| 178 // We can skip the first element because it's the same as the | 185 // We can skip the first element because it's the same as the |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: | 222 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: |
| 216 *params = max_attrib_name_length_; | 223 *params = max_attrib_name_length_; |
| 217 break; | 224 break; |
| 218 case GL_ACTIVE_UNIFORMS: | 225 case GL_ACTIVE_UNIFORMS: |
| 219 *params = uniform_infos_.size(); | 226 *params = uniform_infos_.size(); |
| 220 break; | 227 break; |
| 221 case GL_ACTIVE_UNIFORM_MAX_LENGTH: | 228 case GL_ACTIVE_UNIFORM_MAX_LENGTH: |
| 222 *params = max_uniform_name_length_; | 229 *params = max_uniform_name_length_; |
| 223 break; | 230 break; |
| 224 default: | 231 default: |
| 225 glGetProgramiv(program_id_, pname, params); | 232 glGetProgramiv(service_id_, pname, params); |
| 226 break; | 233 break; |
| 227 } | 234 } |
| 228 } | 235 } |
| 229 | 236 |
| 230 void ProgramManager::CreateProgramInfo(GLuint program_id) { | 237 void ProgramManager::CreateProgramInfo(GLuint client_id, GLuint service_id) { |
| 231 std::pair<ProgramInfoMap::iterator, bool> result = | 238 std::pair<ProgramInfoMap::iterator, bool> result = |
| 232 program_infos_.insert( | 239 program_infos_.insert( |
| 233 std::make_pair(program_id, | 240 std::make_pair(client_id, |
| 234 ProgramInfo::Ref(new ProgramInfo(program_id)))); | 241 ProgramInfo::Ref(new ProgramInfo(service_id)))); |
| 235 DCHECK(result.second); | 242 DCHECK(result.second); |
| 236 } | 243 } |
| 237 | 244 |
| 238 ProgramManager::ProgramInfo* ProgramManager::GetProgramInfo(GLuint program_id) { | 245 ProgramManager::ProgramInfo* ProgramManager::GetProgramInfo(GLuint client_id) { |
| 239 ProgramInfoMap::iterator it = program_infos_.find(program_id); | 246 ProgramInfoMap::iterator it = program_infos_.find(client_id); |
| 240 return it != program_infos_.end() ? it->second : NULL; | 247 return it != program_infos_.end() ? it->second : NULL; |
| 241 } | 248 } |
| 242 | 249 |
| 243 void ProgramManager::RemoveProgramInfo(GLuint program_id) { | 250 void ProgramManager::RemoveProgramInfo(GLuint client_id) { |
| 244 ProgramInfoMap::iterator it = program_infos_.find(program_id); | 251 ProgramInfoMap::iterator it = program_infos_.find(client_id); |
| 245 if (it != program_infos_.end()) { | 252 if (it != program_infos_.end()) { |
| 246 it->second->MarkAsDeleted(); | 253 it->second->MarkAsDeleted(); |
| 247 program_infos_.erase(it); | 254 program_infos_.erase(it); |
| 248 } | 255 } |
| 249 } | 256 } |
| 250 | 257 |
| 251 } // namespace gles2 | 258 } // namespace gles2 |
| 252 } // namespace gpu | 259 } // namespace gpu |
| 253 | 260 |
| 254 | 261 |
| OLD | NEW |