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> |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 uint32 ComputeOffset(const void* start, const void* position) { | 112 uint32 ComputeOffset(const void* start, const void* position) { |
113 return static_cast<const uint8*>(position) - | 113 return static_cast<const uint8*>(position) - |
114 static_cast<const uint8*>(start); | 114 static_cast<const uint8*>(start); |
115 } | 115 } |
116 | 116 |
117 } // anonymous namespace. | 117 } // anonymous namespace. |
118 | 118 |
119 Program::UniformInfo::UniformInfo() | 119 Program::UniformInfo::UniformInfo() |
120 : size(0), | 120 : size(0), |
121 type(GL_NONE), | 121 type(GL_NONE), |
| 122 accepts_api_type(0), |
122 fake_location_base(0), | 123 fake_location_base(0), |
123 is_array(false) { | 124 is_array(false) {} |
124 } | |
125 | 125 |
126 Program::UniformInfo::UniformInfo(GLsizei _size, | 126 Program::UniformInfo::UniformInfo(const std::string& client_name, |
| 127 int client_location_base, |
127 GLenum _type, | 128 GLenum _type, |
128 int _fake_location_base, | 129 bool _is_array, |
129 const std::string& _name) | 130 const std::vector<GLint>& service_locations) |
130 : size(_size), | 131 : size(service_locations.size()), |
131 type(_type), | 132 type(_type), |
132 accepts_api_type(0), | 133 accepts_api_type(0), |
133 fake_location_base(_fake_location_base), | 134 fake_location_base(client_location_base), |
134 is_array(false), | 135 is_array(_is_array), |
135 name(_name) { | 136 name(client_name), |
| 137 element_locations(service_locations) { |
136 switch (type) { | 138 switch (type) { |
137 case GL_INT: | 139 case GL_INT: |
138 accepts_api_type = kUniform1i; | 140 accepts_api_type = kUniform1i; |
139 break; | 141 break; |
140 case GL_INT_VEC2: | 142 case GL_INT_VEC2: |
141 accepts_api_type = kUniform2i; | 143 accepts_api_type = kUniform2i; |
142 break; | 144 break; |
143 case GL_INT_VEC3: | 145 case GL_INT_VEC3: |
144 accepts_api_type = kUniform3i; | 146 accepts_api_type = kUniform3i; |
145 break; | 147 break; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 case GL_UNSIGNED_INT_SAMPLER_3D: | 233 case GL_UNSIGNED_INT_SAMPLER_3D: |
232 case GL_UNSIGNED_INT_SAMPLER_CUBE: | 234 case GL_UNSIGNED_INT_SAMPLER_CUBE: |
233 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: | 235 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: |
234 accepts_api_type = kUniform1i; | 236 accepts_api_type = kUniform1i; |
235 break; | 237 break; |
236 | 238 |
237 default: | 239 default: |
238 NOTREACHED() << "Unhandled UniformInfo type " << type; | 240 NOTREACHED() << "Unhandled UniformInfo type " << type; |
239 break; | 241 break; |
240 } | 242 } |
| 243 DCHECK_LT(0, size); |
| 244 DCHECK(is_array || size == 1); |
| 245 |
| 246 size_t num_texture_units = IsSampler() ? static_cast<size_t>(size) : 0u; |
| 247 texture_units.clear(); |
| 248 texture_units.resize(num_texture_units, 0); |
241 } | 249 } |
242 | |
243 Program::UniformInfo::~UniformInfo() {} | 250 Program::UniformInfo::~UniformInfo() {} |
244 | 251 |
245 bool ProgramManager::IsInvalidPrefix(const char* name, size_t length) { | 252 bool ProgramManager::IsInvalidPrefix(const char* name, size_t length) { |
246 static const char kInvalidPrefix[] = { 'g', 'l', '_' }; | 253 static const char kInvalidPrefix[] = { 'g', 'l', '_' }; |
247 return (length >= sizeof(kInvalidPrefix) && | 254 return (length >= sizeof(kInvalidPrefix) && |
248 memcmp(name, kInvalidPrefix, sizeof(kInvalidPrefix)) == 0); | 255 memcmp(name, kInvalidPrefix, sizeof(kInvalidPrefix)) == 0); |
249 } | 256 } |
250 | 257 |
251 Program::Program(ProgramManager* manager, GLuint service_id) | 258 Program::Program(ProgramManager* manager, GLuint service_id) |
252 : manager_(manager), | 259 : manager_(manager), |
253 use_count_(0), | 260 use_count_(0), |
254 max_attrib_name_length_(0), | 261 max_attrib_name_length_(0), |
255 max_uniform_name_length_(0), | 262 max_uniform_name_length_(0), |
256 service_id_(service_id), | 263 service_id_(service_id), |
257 deleted_(false), | 264 deleted_(false), |
258 valid_(false), | 265 valid_(false), |
259 link_status_(false), | 266 link_status_(false), |
260 uniforms_cleared_(false), | 267 uniforms_cleared_(false), |
261 num_uniforms_(0), | |
262 transform_feedback_buffer_mode_(GL_NONE) { | 268 transform_feedback_buffer_mode_(GL_NONE) { |
263 manager_->StartTracking(this); | 269 manager_->StartTracking(this); |
264 } | 270 } |
265 | 271 |
266 void Program::Reset() { | 272 void Program::Reset() { |
267 valid_ = false; | 273 valid_ = false; |
268 link_status_ = false; | 274 link_status_ = false; |
269 num_uniforms_ = 0; | |
270 max_uniform_name_length_ = 0; | 275 max_uniform_name_length_ = 0; |
271 max_attrib_name_length_ = 0; | 276 max_attrib_name_length_ = 0; |
272 attrib_infos_.clear(); | 277 attrib_infos_.clear(); |
273 uniform_infos_.clear(); | 278 uniform_infos_.clear(); |
| 279 uniform_locations_.clear(); |
274 fragment_input_infos_.clear(); | 280 fragment_input_infos_.clear(); |
275 sampler_indices_.clear(); | 281 sampler_indices_.clear(); |
276 attrib_location_to_index_map_.clear(); | 282 attrib_location_to_index_map_.clear(); |
277 } | 283 } |
278 | 284 |
279 std::string Program::ProcessLogInfo( | 285 std::string Program::ProcessLogInfo( |
280 const std::string& log) { | 286 const std::string& log) { |
281 std::string output; | 287 std::string output; |
282 re2::StringPiece input(log); | 288 re2::StringPiece input(log); |
283 std::string prior_log; | 289 std::string prior_log; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 set_log_info(ProcessLogInfo(log).c_str()); | 321 set_log_info(ProcessLogInfo(log).c_str()); |
316 } | 322 } |
317 | 323 |
318 void Program::ClearUniforms( | 324 void Program::ClearUniforms( |
319 std::vector<uint8>* zero_buffer) { | 325 std::vector<uint8>* zero_buffer) { |
320 DCHECK(zero_buffer); | 326 DCHECK(zero_buffer); |
321 if (uniforms_cleared_) { | 327 if (uniforms_cleared_) { |
322 return; | 328 return; |
323 } | 329 } |
324 uniforms_cleared_ = true; | 330 uniforms_cleared_ = true; |
325 for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { | 331 for (const UniformInfo& uniform_info : uniform_infos_) { |
326 const UniformInfo& uniform_info = uniform_infos_[ii]; | |
327 if (!uniform_info.IsValid()) { | |
328 continue; | |
329 } | |
330 GLint location = uniform_info.element_locations[0]; | 332 GLint location = uniform_info.element_locations[0]; |
331 GLsizei size = uniform_info.size; | 333 GLsizei size = uniform_info.size; |
332 uint32 unit_size = | 334 uint32 unit_size = |
333 GLES2Util::GetElementCountForUniformType(uniform_info.type) * | 335 GLES2Util::GetElementCountForUniformType(uniform_info.type) * |
334 GLES2Util::GetElementSizeForUniformType(uniform_info.type); | 336 GLES2Util::GetElementSizeForUniformType(uniform_info.type); |
335 DCHECK_LT(0u, unit_size); | 337 DCHECK_LT(0u, unit_size); |
336 uint32 size_needed = size * unit_size; | 338 uint32 size_needed = size * unit_size; |
337 if (size_needed > zero_buffer->size()) { | 339 if (size_needed > zero_buffer->size()) { |
338 zero_buffer->resize(size_needed, 0u); | 340 zero_buffer->resize(size_needed, 0u); |
339 } | 341 } |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 location, size, false, reinterpret_cast<const GLfloat*>(zero)); | 439 location, size, false, reinterpret_cast<const GLfloat*>(zero)); |
438 break; | 440 break; |
439 | 441 |
440 default: | 442 default: |
441 NOTREACHED(); | 443 NOTREACHED(); |
442 break; | 444 break; |
443 } | 445 } |
444 } | 446 } |
445 } | 447 } |
446 | 448 |
447 namespace { | |
448 | |
449 struct UniformData { | |
450 UniformData() : size(-1), type(GL_NONE), location(0), added(false) { | |
451 } | |
452 std::string queried_name; | |
453 std::string corrected_name; | |
454 std::string original_name; | |
455 GLsizei size; | |
456 GLenum type; | |
457 GLint location; | |
458 bool added; | |
459 }; | |
460 | |
461 } // anonymous namespace | |
462 | |
463 void Program::Update() { | 449 void Program::Update() { |
464 Reset(); | 450 Reset(); |
465 UpdateLogInfo(); | 451 UpdateLogInfo(); |
466 link_status_ = true; | 452 link_status_ = true; |
467 uniforms_cleared_ = false; | 453 uniforms_cleared_ = false; |
468 GLint num_attribs = 0; | 454 GLint num_attribs = 0; |
469 GLint max_len = 0; | 455 GLint max_len = 0; |
470 GLint max_location = -1; | 456 GLint max_location = -1; |
471 glGetProgramiv(service_id_, GL_ACTIVE_ATTRIBUTES, &num_attribs); | 457 glGetProgramiv(service_id_, GL_ACTIVE_ATTRIBUTES, &num_attribs); |
472 glGetProgramiv(service_id_, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_len); | 458 glGetProgramiv(service_id_, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_len); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 DVLOG(1) << "----: attribs for service_id: " << service_id(); | 494 DVLOG(1) << "----: attribs for service_id: " << service_id(); |
509 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { | 495 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { |
510 const VertexAttrib& info = attrib_infos_[ii]; | 496 const VertexAttrib& info = attrib_infos_[ii]; |
511 DVLOG(1) << ii << ": loc = " << info.location | 497 DVLOG(1) << ii << ": loc = " << info.location |
512 << ", size = " << info.size | 498 << ", size = " << info.size |
513 << ", type = " << GLES2Util::GetStringEnum(info.type) | 499 << ", type = " << GLES2Util::GetStringEnum(info.type) |
514 << ", name = " << info.name; | 500 << ", name = " << info.name; |
515 } | 501 } |
516 } | 502 } |
517 #endif | 503 #endif |
518 | 504 UpdateUniforms(); |
519 max_len = 0; | |
520 GLint num_uniforms = 0; | |
521 glGetProgramiv(service_id_, GL_ACTIVE_UNIFORMS, &num_uniforms); | |
522 glGetProgramiv(service_id_, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_len); | |
523 DCHECK(num_uniforms <= 0 || max_len > 0); | |
524 name_buffer.reset(new char[max_len]); | |
525 | |
526 // Reads all the names. | |
527 std::vector<UniformData> uniform_data; | |
528 for (GLint ii = 0; ii < num_uniforms; ++ii) { | |
529 GLsizei length = 0; | |
530 UniformData data; | |
531 glGetActiveUniform( | |
532 service_id_, ii, max_len, &length, | |
533 &data.size, &data.type, name_buffer.get()); | |
534 DCHECK(length < max_len); | |
535 DCHECK(length == 0 || name_buffer[length] == '\0'); | |
536 data.queried_name = std::string(name_buffer.get()); | |
537 GetCorrectedUniformData(data.queried_name, &data.corrected_name, | |
538 &data.original_name, &data.size, &data.type); | |
539 uniform_data.push_back(data); | |
540 } | |
541 | |
542 // NOTE: We don't care if 2 uniforms are bound to the same location. | |
543 // One of them will take preference. The spec allows this, same as | |
544 // BindAttribLocation. | |
545 // | |
546 // The reason we don't check is if we were to fail we'd have to | |
547 // restore the previous program but since we've already linked successfully | |
548 // at this point the previous program is gone. | |
549 | |
550 // Assigns the uniforms with bindings. | |
551 size_t next_available_index = 0; | |
552 for (size_t ii = 0; ii < uniform_data.size(); ++ii) { | |
553 UniformData& data = uniform_data[ii]; | |
554 // Force builtin uniforms (gl_DepthRange) to have invalid location. | |
555 if (ProgramManager::IsInvalidPrefix(data.queried_name.c_str(), | |
556 data.queried_name.size())) { | |
557 data.location = -1; | |
558 } else { | |
559 data.location = | |
560 glGetUniformLocation(service_id_, data.queried_name.c_str()); | |
561 } | |
562 // remove "[0]" | |
563 std::string short_name; | |
564 int element_index = 0; | |
565 bool good = GetUniformNameSansElement(data.original_name, &element_index, | |
566 &short_name); | |
567 DCHECK(good); | |
568 LocationMap::const_iterator it = bind_uniform_location_map_.find( | |
569 short_name); | |
570 if (it != bind_uniform_location_map_.end()) { | |
571 AddUniformInfo( | |
572 data.size, data.type, data.location, it->second, data.corrected_name, | |
573 data.original_name, &next_available_index); | |
574 data.added = true; | |
575 } | |
576 } | |
577 | |
578 // Assigns the uniforms that were not bound. | |
579 for (size_t ii = 0; ii < uniform_data.size(); ++ii) { | |
580 const UniformData& data = uniform_data[ii]; | |
581 if (!data.added) { | |
582 AddUniformInfo( | |
583 data.size, data.type, data.location, -1, data.corrected_name, | |
584 data.original_name, &next_available_index); | |
585 } | |
586 } | |
587 | 505 |
588 #if !defined(NDEBUG) | 506 #if !defined(NDEBUG) |
589 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 507 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
590 switches::kEnableGPUServiceLoggingGPU)) { | 508 switches::kEnableGPUServiceLoggingGPU)) { |
591 DVLOG(1) << "----: uniforms for service_id: " << service_id(); | 509 DVLOG(1) << "----: uniforms for service_id: " << service_id(); |
592 for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { | 510 size_t ii = 0; |
593 const UniformInfo& info = uniform_infos_[ii]; | 511 for (const UniformInfo& info : uniform_infos_) { |
594 if (info.IsValid()) { | 512 DVLOG(1) << ii++ << ": loc = " << info.element_locations[0] |
595 DVLOG(1) << ii << ": loc = " << info.element_locations[0] | 513 << ", size = " << info.size |
596 << ", size = " << info.size | 514 << ", type = " << GLES2Util::GetStringEnum(info.type) |
597 << ", type = " << GLES2Util::GetStringEnum(info.type) | 515 << ", name = " << info.name; |
598 << ", name = " << info.name; | |
599 } | |
600 } | 516 } |
601 } | 517 } |
602 #endif | 518 #endif |
603 | 519 |
604 UpdateFragmentInputs(); | 520 UpdateFragmentInputs(); |
605 | 521 |
606 valid_ = true; | 522 valid_ = true; |
607 } | 523 } |
608 | 524 |
| 525 void Program::UpdateUniforms() { |
| 526 // Reserve each client-bound uniform location. This way unbound uniforms will |
| 527 // not be allocated to locations that user expects bound uniforms to be, even |
| 528 // if the expected uniforms are optimized away by the driver. |
| 529 for (const auto& binding : bind_uniform_location_map_) { |
| 530 if (binding.second < 0) |
| 531 continue; |
| 532 size_t client_location = static_cast<size_t>(binding.second); |
| 533 if (uniform_locations_.size() <= client_location) |
| 534 uniform_locations_.resize(client_location + 1); |
| 535 uniform_locations_[client_location].SetInactive(); |
| 536 } |
| 537 |
| 538 GLint num_uniforms = 0; |
| 539 glGetProgramiv(service_id_, GL_ACTIVE_UNIFORMS, &num_uniforms); |
| 540 if (num_uniforms <= 0) |
| 541 return; |
| 542 |
| 543 uniform_infos_.resize(num_uniforms); |
| 544 |
| 545 GLint name_buffer_length = 0; |
| 546 glGetProgramiv(service_id_, GL_ACTIVE_UNIFORM_MAX_LENGTH, |
| 547 &name_buffer_length); |
| 548 DCHECK(name_buffer_length > 0); |
| 549 scoped_ptr<char[]> name_buffer(new char[name_buffer_length]); |
| 550 |
| 551 size_t unused_client_location_cursor = 0; |
| 552 |
| 553 for (GLint uniform_index = 0; uniform_index < num_uniforms; ++uniform_index) { |
| 554 GLsizei name_length = 0; |
| 555 GLsizei size = 0; |
| 556 GLenum type = GL_NONE; |
| 557 glGetActiveUniform(service_id_, uniform_index, name_buffer_length, |
| 558 &name_length, &size, &type, name_buffer.get()); |
| 559 DCHECK(name_length < name_buffer_length); |
| 560 DCHECK(name_length == 0 || name_buffer[name_length] == '\0'); |
| 561 std::string service_name(name_buffer.get(), name_length); |
| 562 |
| 563 GLint service_location = -1; |
| 564 // Force builtin uniforms (gl_DepthRange) to have invalid location. |
| 565 if (!ProgramManager::IsInvalidPrefix(service_name.c_str(), |
| 566 service_name.size())) { |
| 567 service_location = |
| 568 glGetUniformLocation(service_id_, service_name.c_str()); |
| 569 } |
| 570 |
| 571 // Determine the client name of the uniform and whether it is an array |
| 572 // or not. |
| 573 bool is_array = false; |
| 574 std::string client_name; |
| 575 for (size_t i = 0; i < kMaxAttachedShaders && client_name.empty(); ++i) { |
| 576 const auto& shader = attached_shaders_[i]; |
| 577 if (!shader) |
| 578 continue; |
| 579 const sh::ShaderVariable* info = nullptr; |
| 580 const sh::Uniform* uniform = shader->GetUniformInfo(service_name); |
| 581 if (uniform && |
| 582 uniform->findInfoByMappedName(service_name, &info, &client_name)) { |
| 583 DCHECK(!client_name.empty()); |
| 584 is_array = info->arraySize > 0; |
| 585 type = info->type; |
| 586 size = std::max(1u, info->arraySize); |
| 587 } |
| 588 } |
| 589 if (client_name.empty()) { |
| 590 // This happens only in cases where we do not have ANGLE or run unit tests |
| 591 // (or ANGLE has a severe bug). |
| 592 client_name = service_name; |
| 593 GLSLArrayName parsed_service_name(service_name); |
| 594 is_array = size > 1 || parsed_service_name.IsArrayName(); |
| 595 } |
| 596 |
| 597 std::string service_base_name = service_name; |
| 598 std::string client_base_name = client_name; |
| 599 if (is_array) { |
| 600 // Some drivers incorrectly return an uniform name of size-1 array without |
| 601 // "[0]". In this case, we correct the service name by appending "[0]" to |
| 602 // it. |
| 603 GLSLArrayName parsed_service_name(service_name); |
| 604 if (parsed_service_name.IsArrayName()) { |
| 605 service_base_name = parsed_service_name.base_name(); |
| 606 GLSLArrayName parsed_client_name(client_name); |
| 607 client_base_name = parsed_client_name.base_name(); |
| 608 } else { |
| 609 service_name += "[0]"; |
| 610 client_name += "[0]"; |
| 611 } |
| 612 } |
| 613 |
| 614 // Assign a location for the uniform: use either client-bound |
| 615 // location or automatically assigned to an unused location. |
| 616 size_t client_location_base = 0; |
| 617 LocationMap::const_iterator it = |
| 618 bind_uniform_location_map_.find(client_base_name); |
| 619 if (it != bind_uniform_location_map_.end()) { |
| 620 client_location_base = it->second; |
| 621 } else { |
| 622 while (unused_client_location_cursor < uniform_locations_.size() && |
| 623 !uniform_locations_[unused_client_location_cursor].IsUnused()) |
| 624 unused_client_location_cursor++; |
| 625 if (unused_client_location_cursor == uniform_locations_.size()) |
| 626 uniform_locations_.resize(unused_client_location_cursor + 1); |
| 627 client_location_base = unused_client_location_cursor; |
| 628 unused_client_location_cursor++; |
| 629 } |
| 630 |
| 631 // Populate the uniform list entry. |
| 632 std::vector<GLint> service_locations; |
| 633 service_locations.resize(size); |
| 634 service_locations[0] = service_location; |
| 635 |
| 636 if (size > 1) { |
| 637 for (GLsizei ii = 1; ii < size; ++ii) { |
| 638 std::string element_name(service_base_name + "[" + |
| 639 base::IntToString(ii) + "]"); |
| 640 service_locations[ii] = |
| 641 glGetUniformLocation(service_id_, element_name.c_str()); |
| 642 } |
| 643 } |
| 644 |
| 645 UniformInfo& info = uniform_infos_[uniform_index]; |
| 646 info = UniformInfo(client_name, client_location_base, type, is_array, |
| 647 service_locations); |
| 648 if (info.IsSampler()) { |
| 649 sampler_indices_.push_back(uniform_index); |
| 650 } |
| 651 |
| 652 // Populate the uniform location list entry. |
| 653 // Before linking, we already validated that no two statically used uniforms |
| 654 // are bound to the same location. |
| 655 DCHECK(!uniform_locations_[client_location_base].IsActive()); |
| 656 uniform_locations_[client_location_base].SetActive(&info); |
| 657 |
| 658 max_uniform_name_length_ = std::max(max_uniform_name_length_, |
| 659 static_cast<GLsizei>(info.name.size())); |
| 660 } |
| 661 } |
| 662 |
609 void Program::UpdateFragmentInputs() { | 663 void Program::UpdateFragmentInputs() { |
610 if (!feature_info().feature_flags().chromium_path_rendering) | 664 if (!feature_info().feature_flags().chromium_path_rendering) |
611 return; | 665 return; |
612 GLint num_fragment_inputs = 0; | 666 GLint num_fragment_inputs = 0; |
613 glGetProgramInterfaceiv(service_id_, GL_FRAGMENT_INPUT_NV, | 667 glGetProgramInterfaceiv(service_id_, GL_FRAGMENT_INPUT_NV, |
614 GL_ACTIVE_RESOURCES, &num_fragment_inputs); | 668 GL_ACTIVE_RESOURCES, &num_fragment_inputs); |
615 if (num_fragment_inputs <= 0) | 669 if (num_fragment_inputs <= 0) |
616 return; | 670 return; |
617 GLint max_len = 0; | 671 GLint max_len = 0; |
618 glGetProgramInterfaceiv(service_id_, GL_FRAGMENT_INPUT_NV, GL_MAX_NAME_LENGTH, | 672 glGetProgramInterfaceiv(service_id_, GL_FRAGMENT_INPUT_NV, GL_MAX_NAME_LENGTH, |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
910 return; | 964 return; |
911 } | 965 } |
912 glValidateProgram(service_id()); | 966 glValidateProgram(service_id()); |
913 UpdateLogInfo(); | 967 UpdateLogInfo(); |
914 } | 968 } |
915 | 969 |
916 GLint Program::GetUniformFakeLocation( | 970 GLint Program::GetUniformFakeLocation( |
917 const std::string& name) const { | 971 const std::string& name) const { |
918 GLSLArrayName parsed_name(name); | 972 GLSLArrayName parsed_name(name); |
919 | 973 |
920 for (GLuint ii = 0; ii < uniform_infos_.size(); ++ii) { | 974 for (const UniformInfo& info : uniform_infos_) { |
921 const UniformInfo& info = uniform_infos_[ii]; | |
922 if (!info.IsValid()) { | |
923 continue; | |
924 } | |
925 if (info.name == name || | 975 if (info.name == name || |
926 (info.is_array && | 976 (info.is_array && |
927 info.name.compare(0, info.name.size() - 3, name) == 0)) { | 977 info.name.compare(0, info.name.size() - 3, name) == 0)) { |
928 return info.fake_location_base; | 978 return info.fake_location_base; |
929 } else if (parsed_name.IsArrayName() && info.is_array) { | 979 } else if (parsed_name.IsArrayName() && info.is_array) { |
930 // Look for an array specification. | 980 // Look for an array specification. |
931 size_t open_pos = info.name.find_last_of('['); | 981 size_t open_pos = info.name.find_last_of('['); |
932 if (info.name.compare(0, open_pos, parsed_name.base_name()) == 0) { | 982 if (info.name.compare(0, open_pos, parsed_name.base_name()) == 0) { |
933 int index = parsed_name.element_index(); | 983 int index = parsed_name.element_index(); |
934 DCHECK(index >= 0); | |
935 if (index < info.size) { | 984 if (index < info.size) { |
936 DCHECK_GT(static_cast<int>(info.element_locations.size()), index); | 985 DCHECK_GT(static_cast<int>(info.element_locations.size()), index); |
937 if (info.element_locations[index] == -1) | 986 if (info.element_locations[index] == -1) |
938 return -1; | 987 return -1; |
939 return ProgramManager::MakeFakeLocation( | 988 return ProgramManager::MakeFakeLocation( |
940 info.fake_location_base, index); | 989 info.fake_location_base, index); |
941 } | 990 } |
942 } | 991 } |
943 } | 992 } |
944 } | 993 } |
945 return -1; | 994 return -1; |
946 } | 995 } |
947 | 996 |
948 GLint Program::GetAttribLocation( | 997 GLint Program::GetAttribLocation( |
949 const std::string& original_name) const { | 998 const std::string& original_name) const { |
950 for (GLuint ii = 0; ii < attrib_infos_.size(); ++ii) { | 999 for (GLuint ii = 0; ii < attrib_infos_.size(); ++ii) { |
951 const VertexAttrib& info = attrib_infos_[ii]; | 1000 const VertexAttrib& info = attrib_infos_[ii]; |
952 if (info.name == original_name) { | 1001 if (info.name == original_name) { |
953 return info.location; | 1002 return info.location; |
954 } | 1003 } |
955 } | 1004 } |
956 return -1; | 1005 return -1; |
957 } | 1006 } |
958 | 1007 |
959 const Program::UniformInfo* | 1008 const Program::UniformInfo* |
960 Program::GetUniformInfoByFakeLocation( | 1009 Program::GetUniformInfoByFakeLocation( |
961 GLint fake_location, GLint* real_location, GLint* array_index) const { | 1010 GLint fake_location, GLint* real_location, GLint* array_index) const { |
962 DCHECK(real_location); | 1011 DCHECK(real_location); |
963 DCHECK(array_index); | 1012 DCHECK(array_index); |
964 if (fake_location < 0) { | 1013 if (fake_location < 0) |
965 return NULL; | 1014 return nullptr; |
966 } | 1015 size_t location_index = |
| 1016 GetUniformLocationIndexFromFakeLocation(fake_location); |
| 1017 if (location_index >= uniform_locations_.size()) |
| 1018 return nullptr; |
967 | 1019 |
968 GLint uniform_index = GetUniformInfoIndexFromFakeLocation(fake_location); | 1020 if (!uniform_locations_[location_index].IsActive()) |
969 if (uniform_index >= 0 && | 1021 return nullptr; |
970 static_cast<size_t>(uniform_index) < uniform_infos_.size()) { | 1022 |
971 const UniformInfo& uniform_info = uniform_infos_[uniform_index]; | 1023 const UniformInfo* info = uniform_locations_[location_index].uniform(); |
972 if (!uniform_info.IsValid()) { | 1024 size_t element_index = GetArrayElementIndexFromFakeLocation(fake_location); |
973 return NULL; | 1025 if (static_cast<GLsizei>(element_index) >= info->size) |
974 } | 1026 return nullptr; |
975 GLint element_index = GetArrayElementIndexFromFakeLocation(fake_location); | 1027 *real_location = info->element_locations[element_index]; |
976 if (element_index < uniform_info.size) { | 1028 *array_index = element_index; |
977 *real_location = uniform_info.element_locations[element_index]; | 1029 return info; |
978 *array_index = element_index; | 1030 } |
979 return &uniform_info; | 1031 |
980 } | 1032 bool Program::IsInactiveUniformLocationByFakeLocation( |
981 } | 1033 GLint fake_location) const { |
982 return NULL; | 1034 if (fake_location < 0) |
| 1035 return true; |
| 1036 size_t location_index = |
| 1037 GetUniformLocationIndexFromFakeLocation(fake_location); |
| 1038 if (location_index >= uniform_locations_.size()) |
| 1039 return false; |
| 1040 return uniform_locations_[location_index].IsInactive(); |
983 } | 1041 } |
984 | 1042 |
985 const std::string* Program::GetAttribMappedName( | 1043 const std::string* Program::GetAttribMappedName( |
986 const std::string& original_name) const { | 1044 const std::string& original_name) const { |
987 for (auto shader : attached_shaders_) { | 1045 for (auto shader : attached_shaders_) { |
988 if (shader) { | 1046 if (shader) { |
989 const std::string* mapped_name = | 1047 const std::string* mapped_name = |
990 shader->GetAttribMappedName(original_name); | 1048 shader->GetAttribMappedName(original_name); |
991 if (mapped_name) | 1049 if (mapped_name) |
992 return mapped_name; | 1050 return mapped_name; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1052 // string would exactly match the name of the variable if the suffix "[0]" | 1110 // string would exactly match the name of the variable if the suffix "[0]" |
1053 // were appended to the string". | 1111 // were appended to the string". |
1054 | 1112 |
1055 // At this point we can not know if the string identifies a simple variable, | 1113 // At this point we can not know if the string identifies a simple variable, |
1056 // a base name of an array, or nothing. Store both, so if user overwrites | 1114 // a base name of an array, or nothing. Store both, so if user overwrites |
1057 // either, both still work correctly. | 1115 // either, both still work correctly. |
1058 bind_fragment_input_location_map_[name] = location; | 1116 bind_fragment_input_location_map_[name] = location; |
1059 bind_fragment_input_location_map_[name + "[0]"] = location; | 1117 bind_fragment_input_location_map_[name + "[0]"] = location; |
1060 } | 1118 } |
1061 | 1119 |
1062 // Note: This is only valid to call right after a program has been linked | |
1063 // successfully. | |
1064 void Program::GetCorrectedUniformData( | |
1065 const std::string& name, | |
1066 std::string* corrected_name, std::string* original_name, | |
1067 GLsizei* size, GLenum* type) const { | |
1068 DCHECK(corrected_name && original_name && size && type); | |
1069 for (auto shader : attached_shaders_) { | |
1070 if (!shader) | |
1071 continue; | |
1072 const sh::ShaderVariable* info = NULL; | |
1073 const sh::Uniform* uniform = shader->GetUniformInfo(name); | |
1074 bool found = false; | |
1075 if (uniform) | |
1076 found = uniform->findInfoByMappedName(name, &info, original_name); | |
1077 if (found) { | |
1078 const std::string kArraySpec("[0]"); | |
1079 if (info->arraySize > 0 && | |
1080 !base::EndsWith(name, kArraySpec, base::CompareCase::SENSITIVE)) { | |
1081 *corrected_name = name + kArraySpec; | |
1082 *original_name += kArraySpec; | |
1083 } else { | |
1084 *corrected_name = name; | |
1085 } | |
1086 *type = info->type; | |
1087 *size = std::max(1u, info->arraySize); | |
1088 return; | |
1089 } | |
1090 } | |
1091 // TODO(zmo): this path should never be reached unless there is a serious | |
1092 // bug in the driver or in ANGLE translator. | |
1093 *corrected_name = name; | |
1094 *original_name = name; | |
1095 } | |
1096 | |
1097 void Program::GetVertexAttribData( | 1120 void Program::GetVertexAttribData( |
1098 const std::string& name, std::string* original_name, GLenum* type) const { | 1121 const std::string& name, std::string* original_name, GLenum* type) const { |
1099 DCHECK(original_name); | 1122 DCHECK(original_name); |
1100 DCHECK(type); | 1123 DCHECK(type); |
1101 Shader* shader = attached_shaders_[ShaderTypeToIndex(GL_VERTEX_SHADER)].get(); | 1124 Shader* shader = attached_shaders_[ShaderTypeToIndex(GL_VERTEX_SHADER)].get(); |
1102 if (shader) { | 1125 if (shader) { |
1103 // Vertex attributes can not be arrays or structs (GLSL ES 3.00.4, section | 1126 // Vertex attributes can not be arrays or structs (GLSL ES 3.00.4, section |
1104 // 4.3.4, "Input Variables"), so the top level sh::Attribute returns the | 1127 // 4.3.4, "Input Variables"), so the top level sh::Attribute returns the |
1105 // information we need. | 1128 // information we need. |
1106 const sh::Attribute* info = shader->GetAttribInfo(name); | 1129 const sh::Attribute* info = shader->GetAttribInfo(name); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1170 | 1193 |
1171 if (visited_list.find(block.name) != visited_list.end()) | 1194 if (visited_list.find(block.name) != visited_list.end()) |
1172 continue; | 1195 continue; |
1173 | 1196 |
1174 GetUniformBlockFromInterfaceBlock(shader.get(), block); | 1197 GetUniformBlockFromInterfaceBlock(shader.get(), block); |
1175 visited_list.insert(block.name); | 1198 visited_list.insert(block.name); |
1176 } | 1199 } |
1177 } | 1200 } |
1178 } | 1201 } |
1179 | 1202 |
1180 void Program::AddUniformInfo( | |
1181 GLsizei size, GLenum type, GLint location, GLint fake_base_location, | |
1182 const std::string& name, const std::string& original_name, | |
1183 size_t* next_available_index) { | |
1184 DCHECK(next_available_index); | |
1185 const char* kArraySpec = "[0]"; | |
1186 size_t uniform_index = | |
1187 fake_base_location >= 0 ? fake_base_location : *next_available_index; | |
1188 if (uniform_infos_.size() < uniform_index + 1) { | |
1189 uniform_infos_.resize(uniform_index + 1); | |
1190 } | |
1191 | |
1192 // Before linking, we already validated that no two statically used uniforms | |
1193 // are bound to the same location. | |
1194 DCHECK(!uniform_infos_[uniform_index].IsValid()); | |
1195 | |
1196 uniform_infos_[uniform_index] = UniformInfo( | |
1197 size, type, uniform_index, original_name); | |
1198 ++num_uniforms_; | |
1199 | |
1200 UniformInfo& info = uniform_infos_[uniform_index]; | |
1201 info.element_locations.resize(size); | |
1202 info.element_locations[0] = location; | |
1203 DCHECK_LE(0, size); | |
1204 size_t num_texture_units = info.IsSampler() ? static_cast<size_t>(size) : 0u; | |
1205 info.texture_units.clear(); | |
1206 info.texture_units.resize(num_texture_units, 0); | |
1207 | |
1208 if (size > 1) { | |
1209 // Go through the array element locations looking for a match. | |
1210 // We can skip the first element because it's the same as the | |
1211 // the location without the array operators. | |
1212 size_t array_pos = name.rfind(kArraySpec); | |
1213 std::string base_name = name; | |
1214 if (name.size() > 3) { | |
1215 if (array_pos != name.size() - 3) { | |
1216 info.name = name + kArraySpec; | |
1217 } else { | |
1218 base_name = name.substr(0, name.size() - 3); | |
1219 } | |
1220 } | |
1221 for (GLsizei ii = 1; ii < info.size; ++ii) { | |
1222 std::string element_name(base_name + "[" + base::IntToString(ii) + "]"); | |
1223 info.element_locations[ii] = | |
1224 glGetUniformLocation(service_id_, element_name.c_str()); | |
1225 } | |
1226 } | |
1227 | |
1228 info.is_array = | |
1229 (size > 1 || | |
1230 (info.name.size() > 3 && | |
1231 info.name.rfind(kArraySpec) == info.name.size() - 3)); | |
1232 | |
1233 if (info.IsSampler()) { | |
1234 sampler_indices_.push_back(info.fake_location_base); | |
1235 } | |
1236 max_uniform_name_length_ = | |
1237 std::max(max_uniform_name_length_, | |
1238 static_cast<GLsizei>(info.name.size())); | |
1239 | |
1240 while (*next_available_index < uniform_infos_.size() && | |
1241 uniform_infos_[*next_available_index].IsValid()) { | |
1242 *next_available_index = *next_available_index + 1; | |
1243 } | |
1244 } | |
1245 | |
1246 const Program::UniformInfo* | 1203 const Program::UniformInfo* |
1247 Program::GetUniformInfo( | 1204 Program::GetUniformInfo( |
1248 GLint index) const { | 1205 GLint index) const { |
1249 if (static_cast<size_t>(index) >= uniform_infos_.size()) { | 1206 if (static_cast<size_t>(index) >= uniform_infos_.size()) { |
1250 return NULL; | 1207 return NULL; |
1251 } | 1208 } |
1252 | 1209 return &uniform_infos_[index]; |
1253 const UniformInfo& info = uniform_infos_[index]; | |
1254 return info.IsValid() ? &info : NULL; | |
1255 } | 1210 } |
1256 | 1211 |
1257 bool Program::SetSamplers( | 1212 bool Program::SetSamplers( |
1258 GLint num_texture_units, GLint fake_location, | 1213 GLint num_texture_units, GLint fake_location, |
1259 GLsizei count, const GLint* value) { | 1214 GLsizei count, const GLint* value) { |
1260 if (fake_location < 0) { | 1215 if (fake_location < 0) { |
1261 return true; | 1216 return true; |
1262 } | 1217 } |
1263 GLint uniform_index = GetUniformInfoIndexFromFakeLocation(fake_location); | 1218 size_t location_index = |
1264 if (uniform_index >= 0 && | 1219 GetUniformLocationIndexFromFakeLocation(fake_location); |
1265 static_cast<size_t>(uniform_index) < uniform_infos_.size()) { | 1220 if (location_index >= uniform_infos_.size()) |
1266 UniformInfo& info = uniform_infos_[uniform_index]; | 1221 return false; |
1267 if (!info.IsValid()) { | 1222 |
1268 return false; | 1223 if (!uniform_locations_[location_index].IsActive()) |
1269 } | 1224 return false; |
1270 GLint element_index = GetArrayElementIndexFromFakeLocation(fake_location); | 1225 |
1271 if (element_index < info.size) { | 1226 UniformInfo* info = uniform_locations_[location_index].uniform(); |
1272 count = std::min(info.size - element_index, count); | 1227 |
1273 if (info.IsSampler() && count > 0) { | 1228 size_t element_index = GetArrayElementIndexFromFakeLocation(fake_location); |
1274 for (GLsizei ii = 0; ii < count; ++ii) { | 1229 if (static_cast<GLsizei>(element_index) >= info->size) |
1275 if (value[ii] < 0 || value[ii] >= num_texture_units) { | 1230 return true; |
1276 return false; | 1231 count = std::min(info->size - static_cast<GLsizei>(element_index), count); |
1277 } | 1232 if (info->IsSampler() && count > 0) { |
1278 } | 1233 for (GLsizei ii = 0; ii < count; ++ii) { |
1279 std::copy(value, value + count, | 1234 if (value[ii] < 0 || value[ii] >= num_texture_units) { |
1280 info.texture_units.begin() + element_index); | 1235 return false; |
1281 return true; | |
1282 } | 1236 } |
1283 } | 1237 } |
| 1238 std::copy(value, value + count, |
| 1239 info->texture_units.begin() + element_index); |
| 1240 return true; |
1284 } | 1241 } |
1285 return true; | 1242 return true; |
1286 } | 1243 } |
1287 | 1244 |
1288 void Program::GetProgramiv(GLenum pname, GLint* params) { | 1245 void Program::GetProgramiv(GLenum pname, GLint* params) { |
1289 switch (pname) { | 1246 switch (pname) { |
1290 case GL_ACTIVE_ATTRIBUTES: | 1247 case GL_ACTIVE_ATTRIBUTES: |
1291 *params = attrib_infos_.size(); | 1248 *params = attrib_infos_.size(); |
1292 break; | 1249 break; |
1293 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: | 1250 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: |
1294 // Notice +1 to accomodate NULL terminator. | 1251 // Notice +1 to accomodate NULL terminator. |
1295 *params = max_attrib_name_length_ + 1; | 1252 *params = max_attrib_name_length_ + 1; |
1296 break; | 1253 break; |
1297 case GL_ACTIVE_UNIFORMS: | 1254 case GL_ACTIVE_UNIFORMS: |
1298 *params = num_uniforms_; | 1255 *params = uniform_infos_.size(); |
1299 break; | 1256 break; |
1300 case GL_ACTIVE_UNIFORM_MAX_LENGTH: | 1257 case GL_ACTIVE_UNIFORM_MAX_LENGTH: |
1301 // Notice +1 to accomodate NULL terminator. | 1258 // Notice +1 to accomodate NULL terminator. |
1302 *params = max_uniform_name_length_ + 1; | 1259 *params = max_uniform_name_length_ + 1; |
1303 break; | 1260 break; |
1304 case GL_LINK_STATUS: | 1261 case GL_LINK_STATUS: |
1305 *params = link_status_; | 1262 *params = link_status_; |
1306 break; | 1263 break; |
1307 case GL_INFO_LOG_LENGTH: | 1264 case GL_INFO_LOG_LENGTH: |
1308 // Notice +1 to accomodate NULL terminator. | 1265 // Notice +1 to accomodate NULL terminator. |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1650 // of an identifier is 256 characters. | 1607 // of an identifier is 256 characters. |
1651 uint32 num_locations = 0; | 1608 uint32 num_locations = 0; |
1652 uint32 total_string_size = 0; | 1609 uint32 total_string_size = 0; |
1653 | 1610 |
1654 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { | 1611 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { |
1655 const VertexAttrib& info = attrib_infos_[ii]; | 1612 const VertexAttrib& info = attrib_infos_[ii]; |
1656 num_locations += 1; | 1613 num_locations += 1; |
1657 total_string_size += info.name.size(); | 1614 total_string_size += info.name.size(); |
1658 } | 1615 } |
1659 | 1616 |
1660 for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { | 1617 for (const UniformInfo& info : uniform_infos_) { |
1661 const UniformInfo& info = uniform_infos_[ii]; | 1618 num_locations += info.element_locations.size(); |
1662 if (info.IsValid()) { | 1619 total_string_size += info.name.size(); |
1663 num_locations += info.element_locations.size(); | |
1664 total_string_size += info.name.size(); | |
1665 } | |
1666 } | 1620 } |
1667 | 1621 |
1668 uint32 num_inputs = attrib_infos_.size() + num_uniforms_; | 1622 uint32 num_inputs = attrib_infos_.size() + uniform_infos_.size(); |
1669 uint32 input_size = num_inputs * sizeof(ProgramInput); | 1623 uint32 input_size = num_inputs * sizeof(ProgramInput); |
1670 uint32 location_size = num_locations * sizeof(int32); | 1624 uint32 location_size = num_locations * sizeof(int32); |
1671 uint32 size = sizeof(ProgramInfoHeader) + | 1625 uint32 size = sizeof(ProgramInfoHeader) + |
1672 input_size + location_size + total_string_size; | 1626 input_size + location_size + total_string_size; |
1673 | 1627 |
1674 bucket->SetSize(size); | 1628 bucket->SetSize(size); |
1675 ProgramInfoHeader* header = bucket->GetDataAs<ProgramInfoHeader*>(0, size); | 1629 ProgramInfoHeader* header = bucket->GetDataAs<ProgramInfoHeader*>(0, size); |
1676 ProgramInput* inputs = bucket->GetDataAs<ProgramInput*>( | 1630 ProgramInput* inputs = bucket->GetDataAs<ProgramInput*>( |
1677 sizeof(ProgramInfoHeader), input_size); | 1631 sizeof(ProgramInfoHeader), input_size); |
1678 int32* locations = bucket->GetDataAs<int32*>( | 1632 int32* locations = bucket->GetDataAs<int32*>( |
1679 sizeof(ProgramInfoHeader) + input_size, location_size); | 1633 sizeof(ProgramInfoHeader) + input_size, location_size); |
1680 char* strings = bucket->GetDataAs<char*>( | 1634 char* strings = bucket->GetDataAs<char*>( |
1681 sizeof(ProgramInfoHeader) + input_size + location_size, | 1635 sizeof(ProgramInfoHeader) + input_size + location_size, |
1682 total_string_size); | 1636 total_string_size); |
1683 DCHECK(header); | 1637 DCHECK(header); |
1684 DCHECK(inputs); | 1638 DCHECK(inputs); |
1685 DCHECK(locations); | 1639 DCHECK(locations); |
1686 DCHECK(strings); | 1640 DCHECK(strings); |
1687 | 1641 |
1688 header->link_status = link_status_; | 1642 header->link_status = link_status_; |
1689 header->num_attribs = attrib_infos_.size(); | 1643 header->num_attribs = attrib_infos_.size(); |
1690 header->num_uniforms = num_uniforms_; | 1644 header->num_uniforms = uniform_infos_.size(); |
1691 | 1645 |
1692 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { | 1646 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { |
1693 const VertexAttrib& info = attrib_infos_[ii]; | 1647 const VertexAttrib& info = attrib_infos_[ii]; |
1694 inputs->size = info.size; | 1648 inputs->size = info.size; |
1695 inputs->type = info.type; | 1649 inputs->type = info.type; |
1696 inputs->location_offset = ComputeOffset(header, locations); | 1650 inputs->location_offset = ComputeOffset(header, locations); |
1697 inputs->name_offset = ComputeOffset(header, strings); | 1651 inputs->name_offset = ComputeOffset(header, strings); |
1698 inputs->name_length = info.name.size(); | 1652 inputs->name_length = info.name.size(); |
1699 *locations++ = info.location; | 1653 *locations++ = info.location; |
1700 memcpy(strings, info.name.c_str(), info.name.size()); | 1654 memcpy(strings, info.name.c_str(), info.name.size()); |
1701 strings += info.name.size(); | 1655 strings += info.name.size(); |
1702 ++inputs; | 1656 ++inputs; |
1703 } | 1657 } |
1704 | 1658 |
1705 for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { | 1659 for (const UniformInfo& info : uniform_infos_) { |
1706 const UniformInfo& info = uniform_infos_[ii]; | 1660 inputs->size = info.size; |
1707 if (info.IsValid()) { | 1661 inputs->type = info.type; |
1708 inputs->size = info.size; | 1662 inputs->location_offset = ComputeOffset(header, locations); |
1709 inputs->type = info.type; | 1663 inputs->name_offset = ComputeOffset(header, strings); |
1710 inputs->location_offset = ComputeOffset(header, locations); | 1664 inputs->name_length = info.name.size(); |
1711 inputs->name_offset = ComputeOffset(header, strings); | 1665 DCHECK(static_cast<size_t>(info.size) == info.element_locations.size()); |
1712 inputs->name_length = info.name.size(); | 1666 for (size_t jj = 0; jj < info.element_locations.size(); ++jj) { |
1713 DCHECK(static_cast<size_t>(info.size) == info.element_locations.size()); | 1667 if (info.element_locations[jj] == -1) |
1714 for (size_t jj = 0; jj < info.element_locations.size(); ++jj) { | 1668 *locations++ = -1; |
1715 if (info.element_locations[jj] == -1) | 1669 else |
1716 *locations++ = -1; | 1670 *locations++ = |
1717 else | 1671 ProgramManager::MakeFakeLocation(info.fake_location_base, jj); |
1718 *locations++ = ProgramManager::MakeFakeLocation(ii, jj); | |
1719 } | |
1720 memcpy(strings, info.name.c_str(), info.name.size()); | |
1721 strings += info.name.size(); | |
1722 ++inputs; | |
1723 } | 1672 } |
| 1673 memcpy(strings, info.name.c_str(), info.name.size()); |
| 1674 strings += info.name.size(); |
| 1675 ++inputs; |
1724 } | 1676 } |
| 1677 // NOTE: currently we do not pass inactive uniform binding locations |
| 1678 // through the program info call. |
1725 | 1679 |
1726 // NOTE: currently we do not pass fragment input infos through the program | 1680 // NOTE: currently we do not pass fragment input infos through the program |
1727 // info call, because they are not exposed through any getter function. | 1681 // info call, because they are not exposed through any getter function. |
1728 | 1682 |
1729 DCHECK_EQ(ComputeOffset(header, strings), size); | 1683 DCHECK_EQ(ComputeOffset(header, strings), size); |
1730 } | 1684 } |
1731 | 1685 |
1732 bool Program::GetUniformBlocks(CommonDecoder::Bucket* bucket) const { | 1686 bool Program::GetUniformBlocks(CommonDecoder::Bucket* bucket) const { |
1733 // The data is packed into the bucket in the following order | 1687 // The data is packed into the bucket in the following order |
1734 // 1) header | 1688 // 1) header |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2168 DCHECK(program); | 2122 DCHECK(program); |
2169 program->ClearUniforms(&zero_); | 2123 program->ClearUniforms(&zero_); |
2170 } | 2124 } |
2171 | 2125 |
2172 int32 ProgramManager::MakeFakeLocation(int32 index, int32 element) { | 2126 int32 ProgramManager::MakeFakeLocation(int32 index, int32 element) { |
2173 return index + element * 0x10000; | 2127 return index + element * 0x10000; |
2174 } | 2128 } |
2175 | 2129 |
2176 } // namespace gles2 | 2130 } // namespace gles2 |
2177 } // namespace gpu | 2131 } // namespace gpu |
OLD | NEW |