Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(302)

Side by Side Diff: gpu/command_buffer/service/program_manager.cc

Issue 10635011: Add glBindUniformLocationCHROMIUM (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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>
8 #include <set> 7 #include <set>
9 #include <vector> 8 #include <vector>
10 9
11 #include "base/basictypes.h" 10 #include "base/basictypes.h"
12 #include "base/command_line.h" 11 #include "base/command_line.h"
13 #include "base/logging.h" 12 #include "base/logging.h"
14 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/scoped_ptr.h"
15 #include "base/string_number_conversions.h" 14 #include "base/string_number_conversions.h"
16 #include "gpu/command_buffer/common/gles2_cmd_format.h" 15 #include "gpu/command_buffer/common/gles2_cmd_format.h"
17 #include "gpu/command_buffer/common/gles2_cmd_utils.h" 16 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
18 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 17 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
19 #include "gpu/command_buffer/service/gpu_switches.h" 18 #include "gpu/command_buffer/service/gpu_switches.h"
20 19
21 namespace gpu { 20 namespace gpu {
22 namespace gles2 { 21 namespace gles2 {
23 22
24 static int ShaderTypeToIndex(GLenum shader_type) { 23 namespace {
24
25 int ShaderTypeToIndex(GLenum shader_type) {
25 switch (shader_type) { 26 switch (shader_type) {
26 case GL_VERTEX_SHADER: 27 case GL_VERTEX_SHADER:
27 return 0; 28 return 0;
28 case GL_FRAGMENT_SHADER: 29 case GL_FRAGMENT_SHADER:
29 return 1; 30 return 1;
30 default: 31 default:
31 NOTREACHED(); 32 NOTREACHED();
32 return 0; 33 return 0;
33 } 34 }
34 } 35 }
35 36
37 // Given a name like "foo.bar[123].moo[456]" sets new_name to "foo.bar[123].moo"
38 // and sets element_index to 456. returns false if element expression was not a
39 // whole decimal number. For example: "foo[1b2]"
40 bool GetUniformNameSansElement(
41 const std::string name, int* element_index, std::string* new_name) {
42 DCHECK(element_index);
43 DCHECK(new_name);
44 if (name.size() < 3 || name[name.size() - 1] != ']') {
45 *element_index = 0;
46 *new_name = name;
47 return true;
48 }
49
50 // Look for an array specification.
51 size_t open_pos = name.find_last_of('[');
52 if (open_pos == std::string::npos ||
53 open_pos >= name.size() - 2) {
54 return false;
55 }
56
57 GLint index = 0;
58 size_t last = name.size() - 1;
59 for (size_t pos = open_pos + 1; pos < last; ++pos) {
60 int8 digit = name[pos] - '0';
61 if (digit < 0 || digit > 9) {
62 return false;
63 }
64 index = index * 10 + digit;
65 }
66
67 if (index < 0) {
68 return false;
69 }
70
71 *element_index = index;
72 *new_name = name.substr(0, open_pos);
73 return true;
74 }
75
76 } // anonymous namespace.
77
78 ProgramManager::ProgramInfo::UniformInfo::UniformInfo()
79 : size(0) {
80 }
81
36 ProgramManager::ProgramInfo::UniformInfo::UniformInfo( 82 ProgramManager::ProgramInfo::UniformInfo::UniformInfo(
37 GLsizei _size, 83 GLsizei _size,
38 GLenum _type, 84 GLenum _type,
39 int _fake_location_base, 85 int _fake_location_base,
40 const std::string& _name) 86 const std::string& _name)
41 : size(_size), 87 : size(_size),
42 type(_type), 88 type(_type),
43 fake_location_base(_fake_location_base), 89 fake_location_base(_fake_location_base),
44 is_array(false), 90 is_array(false),
45 name(_name) { 91 name(_name) {
(...skipping 10 matching lines...) Expand all
56 ProgramManager::ProgramInfo::ProgramInfo( 102 ProgramManager::ProgramInfo::ProgramInfo(
57 ProgramManager* manager, GLuint service_id) 103 ProgramManager* manager, GLuint service_id)
58 : manager_(manager), 104 : manager_(manager),
59 use_count_(0), 105 use_count_(0),
60 max_attrib_name_length_(0), 106 max_attrib_name_length_(0),
61 max_uniform_name_length_(0), 107 max_uniform_name_length_(0),
62 service_id_(service_id), 108 service_id_(service_id),
63 deleted_(false), 109 deleted_(false),
64 valid_(false), 110 valid_(false),
65 link_status_(false), 111 link_status_(false),
66 uniforms_cleared_(false) { 112 uniforms_cleared_(false),
113 num_uniforms_(0) {
67 manager_->StartTracking(this); 114 manager_->StartTracking(this);
68 } 115 }
69 116
70 void ProgramManager::ProgramInfo::Reset() { 117 void ProgramManager::ProgramInfo::Reset() {
71 valid_ = false; 118 valid_ = false;
72 link_status_ = false; 119 link_status_ = false;
120 num_uniforms_ = 0;
73 max_uniform_name_length_ = 0; 121 max_uniform_name_length_ = 0;
74 max_attrib_name_length_ = 0; 122 max_attrib_name_length_ = 0;
75 attrib_infos_.clear(); 123 attrib_infos_.clear();
76 uniform_infos_.clear(); 124 uniform_infos_.clear();
77 sampler_indices_.clear(); 125 sampler_indices_.clear();
78 attrib_location_to_index_map_.clear(); 126 attrib_location_to_index_map_.clear();
79 } 127 }
80 128
81 void ProgramManager::ProgramInfo::UpdateLogInfo() { 129 void ProgramManager::ProgramInfo::UpdateLogInfo() {
82 GLint max_len = 0; 130 GLint max_len = 0;
(...skipping 12 matching lines...) Expand all
95 143
96 void ProgramManager::ProgramInfo::ClearUniforms( 144 void ProgramManager::ProgramInfo::ClearUniforms(
97 std::vector<uint8>* zero_buffer) { 145 std::vector<uint8>* zero_buffer) {
98 DCHECK(zero_buffer); 146 DCHECK(zero_buffer);
99 if (uniforms_cleared_) { 147 if (uniforms_cleared_) {
100 return; 148 return;
101 } 149 }
102 uniforms_cleared_ = true; 150 uniforms_cleared_ = true;
103 for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { 151 for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) {
104 const UniformInfo& uniform_info = uniform_infos_[ii]; 152 const UniformInfo& uniform_info = uniform_infos_[ii];
153 if (!uniform_info.IsValid()) {
154 continue;
155 }
105 GLint location = uniform_info.element_locations[0]; 156 GLint location = uniform_info.element_locations[0];
106 GLsizei size = uniform_info.size; 157 GLsizei size = uniform_info.size;
107 uint32 unit_size = GLES2Util::GetGLDataTypeSizeForUniforms( 158 uint32 unit_size = GLES2Util::GetGLDataTypeSizeForUniforms(
108 uniform_info.type); 159 uniform_info.type);
109 uint32 size_needed = size * unit_size; 160 uint32 size_needed = size * unit_size;
110 if (size_needed > zero_buffer->size()) { 161 if (size_needed > zero_buffer->size()) {
111 zero_buffer->resize(size_needed, 0u); 162 zero_buffer->resize(size_needed, 0u);
112 } 163 }
113 const void* zero = &(*zero_buffer)[0]; 164 const void* zero = &(*zero_buffer)[0];
114 switch (uniform_info.type) { 165 switch (uniform_info.type) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 default: 211 default:
161 NOTREACHED(); 212 NOTREACHED();
162 break; 213 break;
163 } 214 }
164 } 215 }
165 } 216 }
166 217
167 namespace { 218 namespace {
168 219
169 struct UniformData { 220 struct UniformData {
221 UniformData() : size(-1), type(GL_NONE), added(false) {
222 }
170 std::string queried_name; 223 std::string queried_name;
171 std::string corrected_name; 224 std::string corrected_name;
172 std::string original_name; 225 std::string original_name;
173 GLsizei size; 226 GLsizei size;
174 GLenum type; 227 GLenum type;
228 GLint location;
229 bool added;
175 }; 230 };
176 231
177 struct UniformDataComparer { 232 struct UniformDataComparer {
178 bool operator()(const UniformData& lhs, const UniformData& rhs) const { 233 bool operator()(const UniformData& lhs, const UniformData& rhs) const {
179 return lhs.queried_name < rhs.queried_name; 234 return lhs.queried_name < rhs.queried_name;
180 } 235 }
181 }; 236 };
182 237
183 } // anonymous namespace 238 } // anonymous namespace
184 239
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 const VertexAttribInfo& info = attrib_infos_[ii]; 283 const VertexAttribInfo& info = attrib_infos_[ii];
229 attrib_location_to_index_map_[info.location] = ii; 284 attrib_location_to_index_map_[info.location] = ii;
230 } 285 }
231 286
232 max_len = 0; 287 max_len = 0;
233 GLint num_uniforms = 0; 288 GLint num_uniforms = 0;
234 glGetProgramiv(service_id_, GL_ACTIVE_UNIFORMS, &num_uniforms); 289 glGetProgramiv(service_id_, GL_ACTIVE_UNIFORMS, &num_uniforms);
235 glGetProgramiv(service_id_, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_len); 290 glGetProgramiv(service_id_, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_len);
236 name_buffer.reset(new char[max_len]); 291 name_buffer.reset(new char[max_len]);
237 292
238 // Read all the names first and sort them so we get a consistent list 293 // Reads all the names.
239 std::vector<UniformData> uniform_data_; 294 std::vector<UniformData> uniform_data_;
240 for (GLint ii = 0; ii < num_uniforms; ++ii) { 295 for (GLint ii = 0; ii < num_uniforms; ++ii) {
241 GLsizei length = 0; 296 GLsizei length = 0;
242 UniformData data; 297 UniformData data;
243 glGetActiveUniform( 298 glGetActiveUniform(
244 service_id_, ii, max_len, &length, 299 service_id_, ii, max_len, &length,
245 &data.size, &data.type, name_buffer.get()); 300 &data.size, &data.type, name_buffer.get());
246 DCHECK(max_len == 0 || length < max_len); 301 DCHECK(max_len == 0 || length < max_len);
247 DCHECK(length == 0 || name_buffer[length] == '\0'); 302 DCHECK(length == 0 || name_buffer[length] == '\0');
248 if (!IsInvalidPrefix(name_buffer.get(), length)) { 303 if (!IsInvalidPrefix(name_buffer.get(), length)) {
249 data.queried_name = std::string(name_buffer.get()); 304 data.queried_name = std::string(name_buffer.get());
250 GetCorrectedVariableInfo( 305 GetCorrectedVariableInfo(
251 true, name_buffer.get(), &data.corrected_name, &data.original_name, 306 true, name_buffer.get(), &data.corrected_name, &data.original_name,
252 &data.size, &data.type); 307 &data.size, &data.type);
253 uniform_data_.push_back(data); 308 uniform_data_.push_back(data);
254 } 309 }
255 } 310 }
256 311
257 std::sort(uniform_data_.begin(), uniform_data_.end(), UniformDataComparer()); 312 // NOTE: We don't care if 2 uniforms are bound to the same location.
313 // One of them will take preference. The spec allows this, same as
314 // BindAttribLocation.
315 //
316 // The reason we don't check is if we were to fail we'd have to
317 // restore the previous program but since we've already linked successfully
318 // at this point the previous program is gone.
258 319
320 // Assigns the uniforms with bindings.
321 size_t next_available_index = 0;
322 for (size_t ii = 0; ii < uniform_data_.size(); ++ii) {
323 UniformData& data = uniform_data_[ii];
324 data.location = glGetUniformLocation(
325 service_id_, data.queried_name.c_str());
326 // remove "[0]"
327 std::string short_name;
328 int element_index = 0;
329 bool good ALLOW_UNUSED = GetUniformNameSansElement(
330 data.queried_name, &element_index, &short_name);\
331 DCHECK(good);
332 LocationMap::const_iterator it = bind_uniform_location_map_.find(
333 short_name);
334 if (it != bind_uniform_location_map_.end()) {
335 data.added = AddUniformInfo(
336 data.size, data.type, data.location, it->second, data.corrected_name,
337 data.original_name, &next_available_index);
338 }
339 }
340
341 // Assigns the uniforms that were not bound.
259 for (size_t ii = 0; ii < uniform_data_.size(); ++ii) { 342 for (size_t ii = 0; ii < uniform_data_.size(); ++ii) {
260 const UniformData& data = uniform_data_[ii]; 343 const UniformData& data = uniform_data_[ii];
261 GLint location = glGetUniformLocation( 344 if (!data.added) {
262 service_id_, data.queried_name.c_str()); 345 AddUniformInfo(
263 const UniformInfo* info = AddUniformInfo( 346 data.size, data.type, data.location, -1, data.corrected_name,
264 data.size, data.type, location, data.corrected_name, 347 data.original_name, &next_available_index);
265 data.original_name);
266 if (info->IsSampler()) {
267 sampler_indices_.push_back(info->fake_location_base);
268 } 348 }
269 max_uniform_name_length_ =
270 std::max(max_uniform_name_length_,
271 static_cast<GLsizei>(info->name.size()));
272 } 349 }
350
273 valid_ = true; 351 valid_ = true;
274 } 352 }
275 353
276 void ProgramManager::ProgramInfo::ExecuteBindAttribLocationCalls() { 354 void ProgramManager::ProgramInfo::ExecuteBindAttribLocationCalls() {
277 for (std::map<std::string, GLint>::const_iterator it = 355 for (LocationMap::const_iterator it = bind_attrib_location_map_.begin();
278 bind_attrib_location_map_.begin();
279 it != bind_attrib_location_map_.end(); ++it) { 356 it != bind_attrib_location_map_.end(); ++it) {
280 const std::string* mapped_name = GetAttribMappedName(it->first); 357 const std::string* mapped_name = GetAttribMappedName(it->first);
281 if (mapped_name && *mapped_name != it->first) 358 if (mapped_name && *mapped_name != it->first)
282 glBindAttribLocation(service_id_, it->second, mapped_name->c_str()); 359 glBindAttribLocation(service_id_, it->second, mapped_name->c_str());
283 } 360 }
284 } 361 }
285 362
286 bool ProgramManager::ProgramInfo::Link() { 363 bool ProgramManager::ProgramInfo::Link() {
287 ClearLinkStatus(); 364 ClearLinkStatus();
288 if (!CanLink()) { 365 if (!CanLink()) {
(...skipping 22 matching lines...) Expand all
311 return; 388 return;
312 } 389 }
313 glValidateProgram(service_id()); 390 glValidateProgram(service_id());
314 UpdateLogInfo(); 391 UpdateLogInfo();
315 } 392 }
316 393
317 GLint ProgramManager::ProgramInfo::GetUniformFakeLocation( 394 GLint ProgramManager::ProgramInfo::GetUniformFakeLocation(
318 const std::string& name) const { 395 const std::string& name) const {
319 for (GLuint ii = 0; ii < uniform_infos_.size(); ++ii) { 396 for (GLuint ii = 0; ii < uniform_infos_.size(); ++ii) {
320 const UniformInfo& info = uniform_infos_[ii]; 397 const UniformInfo& info = uniform_infos_[ii];
398 if (!info.IsValid()) {
399 continue;
400 }
321 if (info.name == name || 401 if (info.name == name ||
322 (info.is_array && 402 (info.is_array &&
323 info.name.compare(0, info.name.size() - 3, name) == 0)) { 403 info.name.compare(0, info.name.size() - 3, name) == 0)) {
324 return info.fake_location_base; 404 return info.fake_location_base;
325 } else if (info.is_array && 405 } else if (info.is_array &&
326 name.size() >= 3 && name[name.size() - 1] == ']') { 406 name.size() >= 3 && name[name.size() - 1] == ']') {
327 // Look for an array specification. 407 // Look for an array specification.
328 size_t open_pos = name.find_last_of('['); 408 size_t open_pos = name.find_last_of('[');
329 if (open_pos != std::string::npos && 409 if (open_pos != std::string::npos &&
330 open_pos < name.size() - 2 && 410 open_pos < name.size() - 2 &&
331 info.name.size() > open_pos && 411 info.name.size() > open_pos &&
332 name.compare(0, open_pos, info.name, 0, open_pos) == 0) { 412 name.compare(0, open_pos, info.name, 0, open_pos) == 0) {
333 GLint index = 0; 413 GLint index = 0;
334 size_t last = name.size() - 1; 414 size_t last = name.size() - 1;
335 bool bad = false; 415 bool bad = false;
336 for (size_t pos = open_pos + 1; pos < last; ++pos) { 416 for (size_t pos = open_pos + 1; pos < last; ++pos) {
337 int8 digit = name[pos] - '0'; 417 int8 digit = name[pos] - '0';
338 if (digit < 0 || digit > 9) { 418 if (digit < 0 || digit > 9) {
339 bad = true; 419 bad = true;
340 break; 420 break;
341 } 421 }
342 index = index * 10 + digit; 422 index = index * 10 + digit;
343 } 423 }
344 if (!bad && index >= 0 && index < info.size) { 424 if (!bad && index >= 0 && index < info.size) {
345 return GLES2Util::MakeFakeLocation(info.fake_location_base, index); 425 return ProgramManager::MakeFakeLocation(
426 info.fake_location_base, index);
346 } 427 }
347 } 428 }
348 } 429 }
349 } 430 }
350 return -1; 431 return -1;
351 } 432 }
352 433
353 GLint ProgramManager::ProgramInfo::GetAttribLocation( 434 GLint ProgramManager::ProgramInfo::GetAttribLocation(
354 const std::string& name) const { 435 const std::string& name) const {
355 for (GLuint ii = 0; ii < attrib_infos_.size(); ++ii) { 436 for (GLuint ii = 0; ii < attrib_infos_.size(); ++ii) {
(...skipping 11 matching lines...) Expand all
367 DCHECK(real_location); 448 DCHECK(real_location);
368 DCHECK(array_index); 449 DCHECK(array_index);
369 if (fake_location < 0) { 450 if (fake_location < 0) {
370 return NULL; 451 return NULL;
371 } 452 }
372 453
373 GLint uniform_index = GetUniformInfoIndexFromFakeLocation(fake_location); 454 GLint uniform_index = GetUniformInfoIndexFromFakeLocation(fake_location);
374 if (uniform_index >= 0 && 455 if (uniform_index >= 0 &&
375 static_cast<size_t>(uniform_index) < uniform_infos_.size()) { 456 static_cast<size_t>(uniform_index) < uniform_infos_.size()) {
376 const UniformInfo& uniform_info = uniform_infos_[uniform_index]; 457 const UniformInfo& uniform_info = uniform_infos_[uniform_index];
458 if (!uniform_info.IsValid()) {
459 return NULL;
460 }
377 GLint element_index = GetArrayElementIndexFromFakeLocation(fake_location); 461 GLint element_index = GetArrayElementIndexFromFakeLocation(fake_location);
378 if (element_index < uniform_info.size) { 462 if (element_index < uniform_info.size) {
379 *real_location = uniform_info.element_locations[element_index]; 463 *real_location = uniform_info.element_locations[element_index];
380 *array_index = element_index; 464 *array_index = element_index;
381 return &uniform_info; 465 return &uniform_info;
382 } 466 }
383 } 467 }
384 return NULL; 468 return NULL;
385 } 469 }
386 470
387 const std::string* ProgramManager::ProgramInfo::GetAttribMappedName( 471 const std::string* ProgramManager::ProgramInfo::GetAttribMappedName(
388 const std::string& original_name) const { 472 const std::string& original_name) const {
389 for (int ii = 0; ii < kMaxAttachedShaders; ++ii) { 473 for (int ii = 0; ii < kMaxAttachedShaders; ++ii) {
390 ShaderManager::ShaderInfo* shader_info = attached_shaders_[ii].get(); 474 ShaderManager::ShaderInfo* shader_info = attached_shaders_[ii].get();
391 if (shader_info) { 475 if (shader_info) {
392 const std::string* mapped_name = 476 const std::string* mapped_name =
393 shader_info->GetAttribMappedName(original_name); 477 shader_info->GetAttribMappedName(original_name);
394 if (mapped_name) 478 if (mapped_name)
395 return mapped_name; 479 return mapped_name;
396 } 480 }
397 } 481 }
398 return NULL; 482 return NULL;
399 } 483 }
400 484
485 bool ProgramManager::ProgramInfo::SetUniformLocationBinding(
486 const std::string& name, GLint location) {
487 std::string short_name;
488 int element_index = 0;
489 if (!GetUniformNameSansElement(name, &element_index, &short_name) ||
490 element_index != 0) {
491 return false;
492 }
493
494 bind_uniform_location_map_[short_name] = location;
495 return true;
496 }
497
401 // Note: This is only valid to call right after a program has been linked 498 // Note: This is only valid to call right after a program has been linked
402 // successfully. 499 // successfully.
403 void ProgramManager::ProgramInfo::GetCorrectedVariableInfo( 500 void ProgramManager::ProgramInfo::GetCorrectedVariableInfo(
404 bool use_uniforms, 501 bool use_uniforms,
405 const std::string& name, std::string* corrected_name, 502 const std::string& name, std::string* corrected_name,
406 std::string* original_name, 503 std::string* original_name,
407 GLsizei* size, GLenum* type) const { 504 GLsizei* size, GLenum* type) const {
408 DCHECK(corrected_name); 505 DCHECK(corrected_name);
409 DCHECK(original_name); 506 DCHECK(original_name);
410 DCHECK(size); 507 DCHECK(size);
(...skipping 17 matching lines...) Expand all
428 *size = variable_info->size; 525 *size = variable_info->size;
429 return; 526 return;
430 } 527 }
431 } 528 }
432 } 529 }
433 } 530 }
434 *corrected_name = name; 531 *corrected_name = name;
435 *original_name = name; 532 *original_name = name;
436 } 533 }
437 534
438 const ProgramManager::ProgramInfo::UniformInfo* 535 bool ProgramManager::ProgramInfo::AddUniformInfo(
439 ProgramManager::ProgramInfo::AddUniformInfo( 536 GLsizei size, GLenum type, GLint location, GLint fake_base_location,
440 GLsizei size, GLenum type, GLint location, 537 const std::string& name, const std::string& original_name,
441 const std::string& name, const std::string& original_name) { 538 size_t* next_available_index) {
539 DCHECK(next_available_index);
442 const char* kArraySpec = "[0]"; 540 const char* kArraySpec = "[0]";
443 int uniform_index = uniform_infos_.size(); 541 size_t uniform_index =
444 uniform_infos_.push_back( 542 fake_base_location >= 0 ? fake_base_location : *next_available_index;
445 UniformInfo(size, type, uniform_index, original_name)); 543 if (uniform_infos_.size() < uniform_index + 1) {
446 UniformInfo& info = uniform_infos_.back(); 544 uniform_infos_.resize(uniform_index + 1);
545 }
546
547 // return if this location is already in use.
548 if (uniform_infos_[uniform_index].IsValid()) {
549 DCHECK_GE(fake_base_location, 0);
550 return false;
551 }
552
553 uniform_infos_[uniform_index] = UniformInfo(
554 size, type, uniform_index, original_name);
555 ++num_uniforms_;
556
557 UniformInfo& info = uniform_infos_[uniform_index];
447 info.element_locations.resize(size); 558 info.element_locations.resize(size);
448 info.element_locations[0] = location; 559 info.element_locations[0] = location;
449 DCHECK_GE(size, 0); 560 DCHECK_GE(size, 0);
450 size_t num_texture_units = info.IsSampler() ? static_cast<size_t>(size) : 0u; 561 size_t num_texture_units = info.IsSampler() ? static_cast<size_t>(size) : 0u;
451 info.texture_units.clear(); 562 info.texture_units.clear();
452 info.texture_units.resize(num_texture_units, 0); 563 info.texture_units.resize(num_texture_units, 0);
453 564
454 if (size > 1) { 565 if (size > 1) {
455 // Go through the array element locations looking for a match. 566 // Go through the array element locations looking for a match.
456 // We can skip the first element because it's the same as the 567 // We can skip the first element because it's the same as the
(...skipping 12 matching lines...) Expand all
469 info.element_locations[ii] = 580 info.element_locations[ii] =
470 glGetUniformLocation(service_id_, element_name.c_str()); 581 glGetUniformLocation(service_id_, element_name.c_str());
471 } 582 }
472 } 583 }
473 584
474 info.is_array = 585 info.is_array =
475 (size > 1 || 586 (size > 1 ||
476 (info.name.size() > 3 && 587 (info.name.size() > 3 &&
477 info.name.rfind(kArraySpec) == info.name.size() - 3)); 588 info.name.rfind(kArraySpec) == info.name.size() - 3));
478 589
479 return &info; 590 if (info.IsSampler()) {
591 sampler_indices_.push_back(info.fake_location_base);
592 }
593 max_uniform_name_length_ =
594 std::max(max_uniform_name_length_,
595 static_cast<GLsizei>(info.name.size()));
596
597 while (*next_available_index < uniform_infos_.size() &&
598 uniform_infos_[*next_available_index].IsValid()) {
599 *next_available_index = *next_available_index + 1;
600 }
601
602 return true;
603 }
604
605 const ProgramManager::ProgramInfo::UniformInfo*
606 ProgramManager::ProgramInfo::GetUniformInfo(
607 GLint index) const {
608 if (static_cast<size_t>(index) >= uniform_infos_.size()) {
609 return NULL;
610 }
611
612 const UniformInfo& info = uniform_infos_[index];
613 return info.IsValid() ? &info : NULL;
480 } 614 }
481 615
482 bool ProgramManager::ProgramInfo::SetSamplers( 616 bool ProgramManager::ProgramInfo::SetSamplers(
483 GLint num_texture_units, GLint fake_location, 617 GLint num_texture_units, GLint fake_location,
484 GLsizei count, const GLint* value) { 618 GLsizei count, const GLint* value) {
485 if (fake_location < 0) { 619 if (fake_location < 0) {
486 return true; 620 return true;
487 } 621 }
488 GLint uniform_index = GetUniformInfoIndexFromFakeLocation(fake_location); 622 GLint uniform_index = GetUniformInfoIndexFromFakeLocation(fake_location);
489 if (uniform_index >= 0 && 623 if (uniform_index >= 0 &&
490 static_cast<size_t>(uniform_index) < uniform_infos_.size()) { 624 static_cast<size_t>(uniform_index) < uniform_infos_.size()) {
491 UniformInfo& info = uniform_infos_[uniform_index]; 625 UniformInfo& info = uniform_infos_[uniform_index];
626 if (!info.IsValid()) {
627 return false;
628 }
492 GLint element_index = GetArrayElementIndexFromFakeLocation(fake_location); 629 GLint element_index = GetArrayElementIndexFromFakeLocation(fake_location);
493 if (element_index < info.size) { 630 if (element_index < info.size) {
494 count = std::min(info.size - element_index, count); 631 count = std::min(info.size - element_index, count);
495 if (info.IsSampler() && count > 0) { 632 if (info.IsSampler() && count > 0) {
496 for (GLsizei ii = 0; ii < count; ++ii) { 633 for (GLsizei ii = 0; ii < count; ++ii) {
497 if (value[ii] < 0 || value[ii] >= num_texture_units) { 634 if (value[ii] < 0 || value[ii] >= num_texture_units) {
498 return false; 635 return false;
499 } 636 }
500 } 637 }
501 std::copy(value, value + count, 638 std::copy(value, value + count,
502 info.texture_units.begin() + element_index); 639 info.texture_units.begin() + element_index);
503 return true; 640 return true;
504 } 641 }
505 } 642 }
506 } 643 }
507 return true; 644 return true;
508 } 645 }
509 646
510 void ProgramManager::ProgramInfo::GetProgramiv(GLenum pname, GLint* params) { 647 void ProgramManager::ProgramInfo::GetProgramiv(GLenum pname, GLint* params) {
511 switch (pname) { 648 switch (pname) {
512 case GL_ACTIVE_ATTRIBUTES: 649 case GL_ACTIVE_ATTRIBUTES:
513 *params = attrib_infos_.size(); 650 *params = attrib_infos_.size();
514 break; 651 break;
515 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: 652 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
516 // Notice +1 to accomodate NULL terminator. 653 // Notice +1 to accomodate NULL terminator.
517 *params = max_attrib_name_length_ + 1; 654 *params = max_attrib_name_length_ + 1;
518 break; 655 break;
519 case GL_ACTIVE_UNIFORMS: 656 case GL_ACTIVE_UNIFORMS:
520 *params = uniform_infos_.size(); 657 *params = num_uniforms_;
521 break; 658 break;
522 case GL_ACTIVE_UNIFORM_MAX_LENGTH: 659 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
523 // Notice +1 to accomodate NULL terminator. 660 // Notice +1 to accomodate NULL terminator.
524 *params = max_uniform_name_length_ + 1; 661 *params = max_uniform_name_length_ + 1;
525 break; 662 break;
526 case GL_LINK_STATUS: 663 case GL_LINK_STATUS:
527 *params = link_status_; 664 *params = link_status_;
528 break; 665 break;
529 case GL_INFO_LOG_LENGTH: 666 case GL_INFO_LOG_LENGTH:
530 // Notice +1 to accomodate NULL terminator. 667 // Notice +1 to accomodate NULL terminator.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 for (int ii = 0; ii < kMaxAttachedShaders; ++ii) { 723 for (int ii = 0; ii < kMaxAttachedShaders; ++ii) {
587 if (!attached_shaders_[ii] || !attached_shaders_[ii]->IsValid()) { 724 if (!attached_shaders_[ii] || !attached_shaders_[ii]->IsValid()) {
588 return false; 725 return false;
589 } 726 }
590 } 727 }
591 return true; 728 return true;
592 } 729 }
593 730
594 bool ProgramManager::ProgramInfo::DetectAttribLocationBindingConflicts() const { 731 bool ProgramManager::ProgramInfo::DetectAttribLocationBindingConflicts() const {
595 std::set<GLint> location_binding_used; 732 std::set<GLint> location_binding_used;
596 for (std::map<std::string, GLint>::const_iterator it = 733 for (LocationMap::const_iterator it = bind_attrib_location_map_.begin();
597 bind_attrib_location_map_.begin();
598 it != bind_attrib_location_map_.end(); ++it) { 734 it != bind_attrib_location_map_.end(); ++it) {
599 // Find out if an attribute is declared in this program's shaders. 735 // Find out if an attribute is declared in this program's shaders.
600 bool active = false; 736 bool active = false;
601 for (int ii = 0; ii < kMaxAttachedShaders; ++ii) { 737 for (int ii = 0; ii < kMaxAttachedShaders; ++ii) {
602 if (!attached_shaders_[ii] || !attached_shaders_[ii]->IsValid()) 738 if (!attached_shaders_[ii] || !attached_shaders_[ii]->IsValid())
603 continue; 739 continue;
604 if (attached_shaders_[ii]->GetAttribInfo(it->first)) { 740 if (attached_shaders_[ii]->GetAttribInfo(it->first)) {
605 active = true; 741 active = true;
606 break; 742 break;
607 } 743 }
(...skipping 23 matching lines...) Expand all
631 uint32 total_string_size = 0; 767 uint32 total_string_size = 0;
632 768
633 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { 769 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) {
634 const VertexAttribInfo& info = attrib_infos_[ii]; 770 const VertexAttribInfo& info = attrib_infos_[ii];
635 num_locations += 1; 771 num_locations += 1;
636 total_string_size += info.name.size(); 772 total_string_size += info.name.size();
637 } 773 }
638 774
639 for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { 775 for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) {
640 const UniformInfo& info = uniform_infos_[ii]; 776 const UniformInfo& info = uniform_infos_[ii];
641 num_locations += info.element_locations.size(); 777 if (info.IsValid()) {
642 total_string_size += info.name.size(); 778 num_locations += info.element_locations.size();
779 total_string_size += info.name.size();
780 }
643 } 781 }
644 782
645 uint32 num_inputs = attrib_infos_.size() + uniform_infos_.size(); 783 uint32 num_inputs = attrib_infos_.size() + num_uniforms_;
646 uint32 input_size = num_inputs * sizeof(ProgramInput); 784 uint32 input_size = num_inputs * sizeof(ProgramInput);
647 uint32 location_size = num_locations * sizeof(int32); 785 uint32 location_size = num_locations * sizeof(int32);
648 uint32 size = sizeof(ProgramInfoHeader) + 786 uint32 size = sizeof(ProgramInfoHeader) +
649 input_size + location_size + total_string_size; 787 input_size + location_size + total_string_size;
650 788
651 bucket->SetSize(size); 789 bucket->SetSize(size);
652 ProgramInfoHeader* header = bucket->GetDataAs<ProgramInfoHeader*>(0, size); 790 ProgramInfoHeader* header = bucket->GetDataAs<ProgramInfoHeader*>(0, size);
653 ProgramInput* inputs = bucket->GetDataAs<ProgramInput*>( 791 ProgramInput* inputs = bucket->GetDataAs<ProgramInput*>(
654 sizeof(ProgramInfoHeader), input_size); 792 sizeof(ProgramInfoHeader), input_size);
655 int32* locations = bucket->GetDataAs<int32*>( 793 int32* locations = bucket->GetDataAs<int32*>(
656 sizeof(ProgramInfoHeader) + input_size, location_size); 794 sizeof(ProgramInfoHeader) + input_size, location_size);
657 char* strings = bucket->GetDataAs<char*>( 795 char* strings = bucket->GetDataAs<char*>(
658 sizeof(ProgramInfoHeader) + input_size + location_size, 796 sizeof(ProgramInfoHeader) + input_size + location_size,
659 total_string_size); 797 total_string_size);
660 DCHECK(header); 798 DCHECK(header);
661 DCHECK(inputs); 799 DCHECK(inputs);
662 DCHECK(locations); 800 DCHECK(locations);
663 DCHECK(strings); 801 DCHECK(strings);
664 802
665 header->link_status = link_status_; 803 header->link_status = link_status_;
666 header->num_attribs = attrib_infos_.size(); 804 header->num_attribs = attrib_infos_.size();
667 header->num_uniforms = uniform_infos_.size(); 805 header->num_uniforms = num_uniforms_;
668 806
669 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { 807 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) {
670 const VertexAttribInfo& info = attrib_infos_[ii]; 808 const VertexAttribInfo& info = attrib_infos_[ii];
671 inputs->size = info.size; 809 inputs->size = info.size;
672 inputs->type = info.type; 810 inputs->type = info.type;
673 inputs->location_offset = ComputeOffset(header, locations); 811 inputs->location_offset = ComputeOffset(header, locations);
674 inputs->name_offset = ComputeOffset(header, strings); 812 inputs->name_offset = ComputeOffset(header, strings);
675 inputs->name_length = info.name.size(); 813 inputs->name_length = info.name.size();
676 *locations++ = info.location; 814 *locations++ = info.location;
677 memcpy(strings, info.name.c_str(), info.name.size()); 815 memcpy(strings, info.name.c_str(), info.name.size());
678 strings += info.name.size(); 816 strings += info.name.size();
679 ++inputs; 817 ++inputs;
680 } 818 }
681 819
682 for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { 820 for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) {
683 const UniformInfo& info = uniform_infos_[ii]; 821 const UniformInfo& info = uniform_infos_[ii];
684 inputs->size = info.size; 822 if (info.IsValid()) {
685 inputs->type = info.type; 823 inputs->size = info.size;
686 inputs->location_offset = ComputeOffset(header, locations); 824 inputs->type = info.type;
687 inputs->name_offset = ComputeOffset(header, strings); 825 inputs->location_offset = ComputeOffset(header, locations);
688 inputs->name_length = info.name.size(); 826 inputs->name_offset = ComputeOffset(header, strings);
689 DCHECK(static_cast<size_t>(info.size) == info.element_locations.size()); 827 inputs->name_length = info.name.size();
690 for (size_t jj = 0; jj < info.element_locations.size(); ++jj) { 828 DCHECK(static_cast<size_t>(info.size) == info.element_locations.size());
691 *locations++ = GLES2Util::SwizzleLocation( 829 for (size_t jj = 0; jj < info.element_locations.size(); ++jj) {
692 GLES2Util::MakeFakeLocation(ii, jj)); 830 *locations++ = ProgramManager::MakeFakeLocation(ii, jj);
831 }
832 memcpy(strings, info.name.c_str(), info.name.size());
833 strings += info.name.size();
834 ++inputs;
693 } 835 }
694 memcpy(strings, info.name.c_str(), info.name.size());
695 strings += info.name.size();
696 ++inputs;
697 } 836 }
698 837
699 DCHECK_EQ(ComputeOffset(header, strings), size); 838 DCHECK_EQ(ComputeOffset(header, strings), size);
700 } 839 }
701 840
702 ProgramManager::ProgramInfo::~ProgramInfo() { 841 ProgramManager::ProgramInfo::~ProgramInfo() {
703 if (manager_) { 842 if (manager_) {
704 if (manager_->have_context_) { 843 if (manager_->have_context_) {
705 glDeleteProgram(service_id()); 844 glDeleteProgram(service_id());
706 } 845 }
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 RemoveProgramInfoIfUnused(shader_manager, info); 955 RemoveProgramInfoIfUnused(shader_manager, info);
817 } 956 }
818 957
819 void ProgramManager::ClearUniforms(ProgramManager::ProgramInfo* info) { 958 void ProgramManager::ClearUniforms(ProgramManager::ProgramInfo* info) {
820 DCHECK(info); 959 DCHECK(info);
821 if (!disable_workarounds_) { 960 if (!disable_workarounds_) {
822 info->ClearUniforms(&zero_); 961 info->ClearUniforms(&zero_);
823 } 962 }
824 } 963 }
825 964
965 int32 ProgramManager::MakeFakeLocation(int32 index, int32 element) {
966 return index + element * 0x10000;
967 }
968
826 } // namespace gles2 969 } // namespace gles2
827 } // namespace gpu 970 } // namespace gpu
828 971
829 972
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/program_manager.h ('k') | gpu/command_buffer/service/program_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698