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 |