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 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
110 uint32 ComputeOffset(const void* start, const void* position) { | 110 uint32 ComputeOffset(const void* start, const void* position) { |
111 return static_cast<const uint8*>(position) - | 111 return static_cast<const uint8*>(position) - |
112 static_cast<const uint8*>(start); | 112 static_cast<const uint8*>(start); |
113 } | 113 } |
114 | 114 |
115 } // anonymous namespace. | 115 } // anonymous namespace. |
116 | 116 |
117 Program::UniformInfo::UniformInfo() | 117 Program::UniformInfo::UniformInfo() |
118 : size(0), | 118 : size(0), |
119 type(GL_NONE), | 119 type(GL_NONE), |
120 accepts_api_type(0), | |
120 fake_location_base(0), | 121 fake_location_base(0), |
121 is_array(false) { | 122 is_array(false) {} |
122 } | |
123 | 123 |
124 Program::UniformInfo::UniformInfo(GLsizei _size, | 124 Program::UniformInfo::UniformInfo(const std::string& client_name, |
125 int client_location_base, | |
125 GLenum _type, | 126 GLenum _type, |
126 int _fake_location_base, | 127 bool _is_array, |
127 const std::string& _name) | 128 const std::vector<GLint>& service_locations) |
128 : size(_size), | 129 : size(service_locations.size()), |
129 type(_type), | 130 type(_type), |
130 accepts_api_type(0), | 131 accepts_api_type(0), |
131 fake_location_base(_fake_location_base), | 132 fake_location_base(client_location_base), |
132 is_array(false), | 133 is_array(_is_array), |
133 name(_name) { | 134 name(client_name), |
135 element_locations(service_locations) { | |
134 switch (type) { | 136 switch (type) { |
135 case GL_INT: | 137 case GL_INT: |
136 accepts_api_type = kUniform1i; | 138 accepts_api_type = kUniform1i; |
137 break; | 139 break; |
138 case GL_INT_VEC2: | 140 case GL_INT_VEC2: |
139 accepts_api_type = kUniform2i; | 141 accepts_api_type = kUniform2i; |
140 break; | 142 break; |
141 case GL_INT_VEC3: | 143 case GL_INT_VEC3: |
142 accepts_api_type = kUniform3i; | 144 accepts_api_type = kUniform3i; |
143 break; | 145 break; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
229 case GL_UNSIGNED_INT_SAMPLER_3D: | 231 case GL_UNSIGNED_INT_SAMPLER_3D: |
230 case GL_UNSIGNED_INT_SAMPLER_CUBE: | 232 case GL_UNSIGNED_INT_SAMPLER_CUBE: |
231 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: | 233 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: |
232 accepts_api_type = kUniform1i; | 234 accepts_api_type = kUniform1i; |
233 break; | 235 break; |
234 | 236 |
235 default: | 237 default: |
236 NOTREACHED() << "Unhandled UniformInfo type " << type; | 238 NOTREACHED() << "Unhandled UniformInfo type " << type; |
237 break; | 239 break; |
238 } | 240 } |
241 DCHECK_LT(0, size); | |
242 DCHECK(is_array || size == 1); | |
243 | |
244 size_t num_texture_units = IsSampler() ? static_cast<size_t>(size) : 0u; | |
245 texture_units.clear(); | |
246 texture_units.resize(num_texture_units, 0); | |
239 } | 247 } |
240 | |
241 Program::UniformInfo::~UniformInfo() {} | 248 Program::UniformInfo::~UniformInfo() {} |
242 | 249 |
243 bool ProgramManager::IsInvalidPrefix(const char* name, size_t length) { | 250 bool ProgramManager::IsInvalidPrefix(const char* name, size_t length) { |
244 static const char kInvalidPrefix[] = { 'g', 'l', '_' }; | 251 static const char kInvalidPrefix[] = { 'g', 'l', '_' }; |
245 return (length >= sizeof(kInvalidPrefix) && | 252 return (length >= sizeof(kInvalidPrefix) && |
246 memcmp(name, kInvalidPrefix, sizeof(kInvalidPrefix)) == 0); | 253 memcmp(name, kInvalidPrefix, sizeof(kInvalidPrefix)) == 0); |
247 } | 254 } |
248 | 255 |
249 Program::Program(ProgramManager* manager, GLuint service_id) | 256 Program::Program(ProgramManager* manager, GLuint service_id) |
250 : manager_(manager), | 257 : manager_(manager), |
251 use_count_(0), | 258 use_count_(0), |
252 max_attrib_name_length_(0), | 259 max_attrib_name_length_(0), |
253 max_uniform_name_length_(0), | 260 max_uniform_name_length_(0), |
254 service_id_(service_id), | 261 service_id_(service_id), |
255 deleted_(false), | 262 deleted_(false), |
256 valid_(false), | 263 valid_(false), |
257 link_status_(false), | 264 link_status_(false), |
258 uniforms_cleared_(false), | 265 uniforms_cleared_(false), |
259 num_uniforms_(0), | |
260 transform_feedback_buffer_mode_(GL_NONE) { | 266 transform_feedback_buffer_mode_(GL_NONE) { |
261 manager_->StartTracking(this); | 267 manager_->StartTracking(this); |
262 } | 268 } |
263 | 269 |
264 void Program::Reset() { | 270 void Program::Reset() { |
265 valid_ = false; | 271 valid_ = false; |
266 link_status_ = false; | 272 link_status_ = false; |
267 num_uniforms_ = 0; | |
268 max_uniform_name_length_ = 0; | 273 max_uniform_name_length_ = 0; |
269 max_attrib_name_length_ = 0; | 274 max_attrib_name_length_ = 0; |
270 attrib_infos_.clear(); | 275 attrib_infos_.clear(); |
271 uniform_infos_.clear(); | 276 uniform_infos_.clear(); |
277 uniform_locations_.clear(); | |
272 fragment_input_infos_.clear(); | 278 fragment_input_infos_.clear(); |
273 sampler_indices_.clear(); | 279 sampler_indices_.clear(); |
274 attrib_location_to_index_map_.clear(); | 280 attrib_location_to_index_map_.clear(); |
275 } | 281 } |
276 | 282 |
277 std::string Program::ProcessLogInfo( | 283 std::string Program::ProcessLogInfo( |
278 const std::string& log) { | 284 const std::string& log) { |
279 std::string output; | 285 std::string output; |
280 re2::StringPiece input(log); | 286 re2::StringPiece input(log); |
281 std::string prior_log; | 287 std::string prior_log; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
313 set_log_info(ProcessLogInfo(log).c_str()); | 319 set_log_info(ProcessLogInfo(log).c_str()); |
314 } | 320 } |
315 | 321 |
316 void Program::ClearUniforms( | 322 void Program::ClearUniforms( |
317 std::vector<uint8>* zero_buffer) { | 323 std::vector<uint8>* zero_buffer) { |
318 DCHECK(zero_buffer); | 324 DCHECK(zero_buffer); |
319 if (uniforms_cleared_) { | 325 if (uniforms_cleared_) { |
320 return; | 326 return; |
321 } | 327 } |
322 uniforms_cleared_ = true; | 328 uniforms_cleared_ = true; |
323 for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { | 329 for (const UniformInfo& uniform_info : uniform_infos_) { |
324 const UniformInfo& uniform_info = uniform_infos_[ii]; | |
325 if (!uniform_info.IsValid()) { | |
326 continue; | |
327 } | |
328 GLint location = uniform_info.element_locations[0]; | 330 GLint location = uniform_info.element_locations[0]; |
329 GLsizei size = uniform_info.size; | 331 GLsizei size = uniform_info.size; |
330 uint32 unit_size = | 332 uint32 unit_size = |
331 GLES2Util::GetElementCountForUniformType(uniform_info.type) * | 333 GLES2Util::GetElementCountForUniformType(uniform_info.type) * |
332 GLES2Util::GetElementSizeForUniformType(uniform_info.type); | 334 GLES2Util::GetElementSizeForUniformType(uniform_info.type); |
333 DCHECK_LT(0u, unit_size); | 335 DCHECK_LT(0u, unit_size); |
334 uint32 size_needed = size * unit_size; | 336 uint32 size_needed = size * unit_size; |
335 if (size_needed > zero_buffer->size()) { | 337 if (size_needed > zero_buffer->size()) { |
336 zero_buffer->resize(size_needed, 0u); | 338 zero_buffer->resize(size_needed, 0u); |
337 } | 339 } |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
435 location, size, false, reinterpret_cast<const GLfloat*>(zero)); | 437 location, size, false, reinterpret_cast<const GLfloat*>(zero)); |
436 break; | 438 break; |
437 | 439 |
438 default: | 440 default: |
439 NOTREACHED(); | 441 NOTREACHED(); |
440 break; | 442 break; |
441 } | 443 } |
442 } | 444 } |
443 } | 445 } |
444 | 446 |
445 namespace { | |
446 | |
447 struct UniformData { | |
448 UniformData() : size(-1), type(GL_NONE), location(0), added(false) { | |
449 } | |
450 std::string queried_name; | |
451 std::string corrected_name; | |
452 std::string original_name; | |
453 GLsizei size; | |
454 GLenum type; | |
455 GLint location; | |
456 bool added; | |
457 }; | |
458 | |
459 } // anonymous namespace | |
460 | |
461 void Program::Update() { | 447 void Program::Update() { |
462 Reset(); | 448 Reset(); |
463 UpdateLogInfo(); | 449 UpdateLogInfo(); |
464 link_status_ = true; | 450 link_status_ = true; |
465 uniforms_cleared_ = false; | 451 uniforms_cleared_ = false; |
466 GLint num_attribs = 0; | 452 GLint num_attribs = 0; |
467 GLint max_len = 0; | 453 GLint max_len = 0; |
468 GLint max_location = -1; | 454 GLint max_location = -1; |
469 glGetProgramiv(service_id_, GL_ACTIVE_ATTRIBUTES, &num_attribs); | 455 glGetProgramiv(service_id_, GL_ACTIVE_ATTRIBUTES, &num_attribs); |
470 glGetProgramiv(service_id_, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_len); | 456 glGetProgramiv(service_id_, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_len); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
506 DVLOG(1) << "----: attribs for service_id: " << service_id(); | 492 DVLOG(1) << "----: attribs for service_id: " << service_id(); |
507 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { | 493 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { |
508 const VertexAttrib& info = attrib_infos_[ii]; | 494 const VertexAttrib& info = attrib_infos_[ii]; |
509 DVLOG(1) << ii << ": loc = " << info.location | 495 DVLOG(1) << ii << ": loc = " << info.location |
510 << ", size = " << info.size | 496 << ", size = " << info.size |
511 << ", type = " << GLES2Util::GetStringEnum(info.type) | 497 << ", type = " << GLES2Util::GetStringEnum(info.type) |
512 << ", name = " << info.name; | 498 << ", name = " << info.name; |
513 } | 499 } |
514 } | 500 } |
515 #endif | 501 #endif |
516 | 502 UpdateUniforms(); |
517 max_len = 0; | |
518 GLint num_uniforms = 0; | |
519 glGetProgramiv(service_id_, GL_ACTIVE_UNIFORMS, &num_uniforms); | |
520 glGetProgramiv(service_id_, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_len); | |
521 DCHECK(num_uniforms <= 0 || max_len > 0); | |
522 name_buffer.reset(new char[max_len]); | |
523 | |
524 // Reads all the names. | |
525 std::vector<UniformData> uniform_data; | |
526 for (GLint ii = 0; ii < num_uniforms; ++ii) { | |
527 GLsizei length = 0; | |
528 UniformData data; | |
529 glGetActiveUniform( | |
530 service_id_, ii, max_len, &length, | |
531 &data.size, &data.type, name_buffer.get()); | |
532 DCHECK(length < max_len); | |
533 DCHECK(length == 0 || name_buffer[length] == '\0'); | |
534 data.queried_name = std::string(name_buffer.get()); | |
535 GetCorrectedUniformData(data.queried_name, &data.corrected_name, | |
536 &data.original_name, &data.size, &data.type); | |
537 uniform_data.push_back(data); | |
538 } | |
539 | |
540 // NOTE: We don't care if 2 uniforms are bound to the same location. | |
541 // One of them will take preference. The spec allows this, same as | |
542 // BindAttribLocation. | |
543 // | |
544 // The reason we don't check is if we were to fail we'd have to | |
545 // restore the previous program but since we've already linked successfully | |
546 // at this point the previous program is gone. | |
547 | |
548 // Assigns the uniforms with bindings. | |
549 size_t next_available_index = 0; | |
550 for (size_t ii = 0; ii < uniform_data.size(); ++ii) { | |
551 UniformData& data = uniform_data[ii]; | |
552 // Force builtin uniforms (gl_DepthRange) to have invalid location. | |
553 if (ProgramManager::IsInvalidPrefix(data.queried_name.c_str(), | |
554 data.queried_name.size())) { | |
555 data.location = -1; | |
556 } else { | |
557 data.location = | |
558 glGetUniformLocation(service_id_, data.queried_name.c_str()); | |
559 } | |
560 // remove "[0]" | |
561 std::string short_name; | |
562 int element_index = 0; | |
563 bool good = GetUniformNameSansElement(data.original_name, &element_index, | |
564 &short_name); | |
565 DCHECK(good); | |
566 LocationMap::const_iterator it = bind_uniform_location_map_.find( | |
567 short_name); | |
568 if (it != bind_uniform_location_map_.end()) { | |
569 AddUniformInfo( | |
570 data.size, data.type, data.location, it->second, data.corrected_name, | |
571 data.original_name, &next_available_index); | |
572 data.added = true; | |
573 } | |
574 } | |
575 | |
576 // Assigns the uniforms that were not bound. | |
577 for (size_t ii = 0; ii < uniform_data.size(); ++ii) { | |
578 const UniformData& data = uniform_data[ii]; | |
579 if (!data.added) { | |
580 AddUniformInfo( | |
581 data.size, data.type, data.location, -1, data.corrected_name, | |
582 data.original_name, &next_available_index); | |
583 } | |
584 } | |
585 | 503 |
586 #if !defined(NDEBUG) | 504 #if !defined(NDEBUG) |
587 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 505 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
588 switches::kEnableGPUServiceLoggingGPU)) { | 506 switches::kEnableGPUServiceLoggingGPU)) { |
589 DVLOG(1) << "----: uniforms for service_id: " << service_id(); | 507 DVLOG(1) << "----: uniforms for service_id: " << service_id(); |
590 for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { | 508 size_t ii = 0; |
591 const UniformInfo& info = uniform_infos_[ii]; | 509 for (const UniformInfo& info : uniform_infos_) { |
592 if (info.IsValid()) { | 510 DVLOG(1) << ii++ << ": loc = " << info.element_locations[0] |
593 DVLOG(1) << ii << ": loc = " << info.element_locations[0] | 511 << ", size = " << info.size |
594 << ", size = " << info.size | 512 << ", type = " << GLES2Util::GetStringEnum(info.type) |
595 << ", type = " << GLES2Util::GetStringEnum(info.type) | 513 << ", name = " << info.name; |
596 << ", name = " << info.name; | |
597 } | |
598 } | 514 } |
599 } | 515 } |
600 #endif | 516 #endif |
601 | 517 |
602 UpdateFragmentInputs(); | 518 UpdateFragmentInputs(); |
603 | 519 |
604 valid_ = true; | 520 valid_ = true; |
605 } | 521 } |
606 | 522 |
523 void Program::UpdateUniforms() { | |
524 // Reserve each client-bound uniform location. This way unbound uniforms will | |
525 // not be allocated to locations that user expects bound uniforms to be, even | |
526 // if the expected uniforms are optimized away by the driver. | |
527 for (const auto& binding : bind_uniform_location_map_) { | |
528 if (binding.second < 0) | |
529 continue; | |
530 size_t client_location = static_cast<size_t>(binding.second); | |
531 if (uniform_locations_.size() <= client_location) | |
532 uniform_locations_.resize(client_location + 1); | |
533 uniform_locations_[client_location].SetInactive(); | |
534 } | |
535 | |
536 GLint num_uniforms = 0; | |
537 glGetProgramiv(service_id_, GL_ACTIVE_UNIFORMS, &num_uniforms); | |
538 if (num_uniforms <= 0) | |
539 return; | |
540 | |
541 uniform_infos_.resize(num_uniforms); | |
542 | |
543 GLint name_buffer_length = 0; | |
544 glGetProgramiv(service_id_, GL_ACTIVE_UNIFORM_MAX_LENGTH, | |
545 &name_buffer_length); | |
546 DCHECK(name_buffer_length > 0); | |
547 scoped_ptr<char[]> name_buffer(new char[name_buffer_length]); | |
548 | |
549 size_t unused_client_location_cursor = 0; | |
550 | |
551 for (GLint uniform_index = 0; uniform_index < num_uniforms; ++uniform_index) { | |
552 GLsizei name_length = 0; | |
553 GLsizei size = 0; | |
554 GLenum type = GL_NONE; | |
555 glGetActiveUniform(service_id_, uniform_index, name_buffer_length, | |
556 &name_length, &size, &type, name_buffer.get()); | |
557 DCHECK(name_length < name_buffer_length); | |
558 DCHECK(name_length == 0 || name_buffer[name_length] == '\0'); | |
559 std::string service_name(name_buffer.get(), name_length); | |
560 | |
561 GLint service_location = -1; | |
562 // Force builtin uniforms (gl_DepthRange) to have invalid location. | |
563 if (!ProgramManager::IsInvalidPrefix(service_name.c_str(), | |
564 service_name.size())) { | |
565 service_location = | |
566 glGetUniformLocation(service_id_, service_name.c_str()); | |
567 } | |
568 | |
569 // Determine the client name of the uniform and whether it is an array | |
570 // or not. | |
571 bool is_array; | |
572 std::string client_name; | |
573 for (size_t i = 0; i < kMaxAttachedShaders && client_name.empty(); ++i) { | |
574 const auto& shader = attached_shaders_[i]; | |
575 if (!shader) | |
576 continue; | |
577 const sh::ShaderVariable* info = nullptr; | |
578 const sh::Uniform* uniform = shader->GetUniformInfo(service_name); | |
579 if (uniform && | |
580 uniform->findInfoByMappedName(service_name, &info, &client_name)) { | |
581 DCHECK(!client_name.empty()); | |
582 is_array = info->arraySize > 0; | |
583 type = info->type; | |
584 size = std::max(1u, info->arraySize); | |
585 } | |
586 } | |
587 if (client_name.empty()) { | |
588 // This happens only in cases where we do not have ANGLE or run unit tests | |
589 // (or ANGLE has a severe bug). | |
590 client_name = service_name; | |
591 GLSLArrayName parsed_service_name(service_name); | |
592 is_array = size > 1 || parsed_service_name.IsArrayName(); | |
593 } | |
594 | |
595 std::string service_base_name = service_name; | |
596 std::string client_base_name = client_name; | |
597 if (is_array) { | |
598 // Some drivers incorrectly return an uniform name of size-1 array without | |
599 // "[0]". In this case, we correct the service name by appending "[0]" to | |
600 // it. | |
601 GLSLArrayName parsed_service_name(service_name); | |
602 if (parsed_service_name.IsArrayName()) { | |
603 service_base_name = parsed_service_name.base_name(); | |
604 GLSLArrayName parsed_client_name(client_name); | |
605 client_base_name = parsed_client_name.base_name(); | |
606 } else { | |
607 service_name += "[0]"; | |
608 client_name += "[0]"; | |
609 } | |
610 } | |
611 | |
612 // Assign a location for the uniform: use either client-bound | |
613 // location or automatically assigned to an unused location. | |
614 size_t client_location_base = 0; | |
615 LocationMap::const_iterator it = | |
616 bind_uniform_location_map_.find(client_base_name); | |
617 if (it != bind_uniform_location_map_.end()) { | |
618 client_location_base = it->second; | |
619 } else { | |
620 while (unused_client_location_cursor < uniform_locations_.size() && | |
621 !uniform_locations_[unused_client_location_cursor].IsUnused()) | |
622 unused_client_location_cursor++; | |
623 if (unused_client_location_cursor == uniform_locations_.size()) | |
624 uniform_locations_.resize(unused_client_location_cursor + 1); | |
625 client_location_base = unused_client_location_cursor; | |
626 unused_client_location_cursor++; | |
627 } | |
628 | |
629 // Populate the uniform list entry. | |
630 std::vector<GLint> service_locations; | |
631 service_locations.resize(size); | |
632 service_locations[0] = service_location; | |
633 | |
634 if (size > 1) { | |
635 for (GLsizei ii = 1; ii < size; ++ii) { | |
636 std::string element_name(service_base_name + "[" + | |
637 base::IntToString(ii) + "]"); | |
638 service_locations[ii] = | |
639 glGetUniformLocation(service_id_, element_name.c_str()); | |
640 } | |
641 } | |
642 | |
643 UniformInfo& info = uniform_infos_[uniform_index]; | |
644 info = UniformInfo(client_name, client_location_base, type, is_array, | |
645 service_locations); | |
646 if (info.IsSampler()) { | |
647 sampler_indices_.push_back(uniform_index); | |
648 } | |
649 | |
650 // Populate the uniform location list entry. | |
651 // Before linking, we already validated that no two statically used uniforms | |
652 // are bound to the same location. | |
653 DCHECK(!uniform_locations_[client_location_base].IsActive()); | |
654 uniform_locations_[client_location_base].SetActive(&info); | |
655 | |
656 max_uniform_name_length_ = std::max(max_uniform_name_length_, | |
657 static_cast<GLsizei>(info.name.size())); | |
658 } | |
659 } | |
660 | |
607 void Program::UpdateFragmentInputs() { | 661 void Program::UpdateFragmentInputs() { |
608 if (!feature_info().feature_flags().chromium_path_rendering) | 662 if (!feature_info().feature_flags().chromium_path_rendering) |
609 return; | 663 return; |
610 GLint num_fragment_inputs = 0; | 664 GLint num_fragment_inputs = 0; |
611 glGetProgramInterfaceiv(service_id_, GL_FRAGMENT_INPUT_NV, | 665 glGetProgramInterfaceiv(service_id_, GL_FRAGMENT_INPUT_NV, |
612 GL_ACTIVE_RESOURCES, &num_fragment_inputs); | 666 GL_ACTIVE_RESOURCES, &num_fragment_inputs); |
613 if (num_fragment_inputs <= 0) | 667 if (num_fragment_inputs <= 0) |
614 return; | 668 return; |
615 GLint max_len = 0; | 669 GLint max_len = 0; |
616 glGetProgramInterfaceiv(service_id_, GL_FRAGMENT_INPUT_NV, GL_MAX_NAME_LENGTH, | 670 glGetProgramInterfaceiv(service_id_, GL_FRAGMENT_INPUT_NV, GL_MAX_NAME_LENGTH, |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
907 return; | 961 return; |
908 } | 962 } |
909 glValidateProgram(service_id()); | 963 glValidateProgram(service_id()); |
910 UpdateLogInfo(); | 964 UpdateLogInfo(); |
911 } | 965 } |
912 | 966 |
913 GLint Program::GetUniformFakeLocation( | 967 GLint Program::GetUniformFakeLocation( |
914 const std::string& name) const { | 968 const std::string& name) const { |
915 GLSLArrayName parsed_name(name); | 969 GLSLArrayName parsed_name(name); |
916 | 970 |
917 for (GLuint ii = 0; ii < uniform_infos_.size(); ++ii) { | 971 for (const UniformInfo& info : uniform_infos_) { |
918 const UniformInfo& info = uniform_infos_[ii]; | |
919 if (!info.IsValid()) { | |
920 continue; | |
921 } | |
922 if (info.name == name || | 972 if (info.name == name || |
923 (info.is_array && | 973 (info.is_array && |
924 info.name.compare(0, info.name.size() - 3, name) == 0)) { | 974 info.name.compare(0, info.name.size() - 3, name) == 0)) { |
925 return info.fake_location_base; | 975 return info.fake_location_base; |
926 } else if (parsed_name.IsArrayName() && info.is_array) { | 976 } else if (parsed_name.IsArrayName() && info.is_array) { |
927 // Look for an array specification. | 977 // Look for an array specification. |
928 size_t open_pos = info.name.find_last_of('['); | 978 size_t open_pos = info.name.find_last_of('['); |
929 if (info.name.compare(0, open_pos, parsed_name.base_name()) == 0) { | 979 if (info.name.compare(0, open_pos, parsed_name.base_name()) == 0) { |
930 int index = parsed_name.element_index(); | 980 int index = parsed_name.element_index(); |
931 DCHECK(index >= 0); | |
932 if (index < info.size) { | 981 if (index < info.size) { |
933 DCHECK_GT(static_cast<int>(info.element_locations.size()), index); | 982 DCHECK_GT(static_cast<int>(info.element_locations.size()), index); |
934 if (info.element_locations[index] == -1) | 983 if (info.element_locations[index] == -1) |
935 return -1; | 984 return -1; |
936 return ProgramManager::MakeFakeLocation( | 985 return ProgramManager::MakeFakeLocation( |
937 info.fake_location_base, index); | 986 info.fake_location_base, index); |
938 } | 987 } |
939 } | 988 } |
940 } | 989 } |
941 } | 990 } |
942 return -1; | 991 return -1; |
943 } | 992 } |
944 | 993 |
945 GLint Program::GetAttribLocation( | 994 GLint Program::GetAttribLocation( |
946 const std::string& original_name) const { | 995 const std::string& original_name) const { |
947 for (GLuint ii = 0; ii < attrib_infos_.size(); ++ii) { | 996 for (GLuint ii = 0; ii < attrib_infos_.size(); ++ii) { |
948 const VertexAttrib& info = attrib_infos_[ii]; | 997 const VertexAttrib& info = attrib_infos_[ii]; |
949 if (info.name == original_name) { | 998 if (info.name == original_name) { |
950 return info.location; | 999 return info.location; |
951 } | 1000 } |
952 } | 1001 } |
953 return -1; | 1002 return -1; |
954 } | 1003 } |
955 | 1004 |
956 const Program::UniformInfo* | 1005 const Program::UniformInfo* |
957 Program::GetUniformInfoByFakeLocation( | 1006 Program::GetUniformInfoByFakeLocation( |
958 GLint fake_location, GLint* real_location, GLint* array_index) const { | 1007 GLint fake_location, GLint* real_location, GLint* array_index) const { |
959 DCHECK(real_location); | 1008 DCHECK(real_location); |
960 DCHECK(array_index); | 1009 DCHECK(array_index); |
961 if (fake_location < 0) { | 1010 if (fake_location < 0) |
962 return NULL; | 1011 return nullptr; |
963 } | 1012 size_t location_index = |
1013 GetUniformLocationIndexFromFakeLocation(fake_location); | |
1014 if (location_index >= uniform_locations_.size()) | |
1015 return nullptr; | |
964 | 1016 |
965 GLint uniform_index = GetUniformInfoIndexFromFakeLocation(fake_location); | 1017 if (!uniform_locations_[location_index].IsActive()) |
966 if (uniform_index >= 0 && | 1018 return nullptr; |
967 static_cast<size_t>(uniform_index) < uniform_infos_.size()) { | 1019 |
968 const UniformInfo& uniform_info = uniform_infos_[uniform_index]; | 1020 const UniformInfo* info = uniform_locations_[location_index].uniform(); |
969 if (!uniform_info.IsValid()) { | 1021 size_t element_index = GetArrayElementIndexFromFakeLocation(fake_location); |
970 return NULL; | 1022 if (static_cast<GLsizei>(element_index) >= info->size) |
971 } | 1023 return nullptr; |
972 GLint element_index = GetArrayElementIndexFromFakeLocation(fake_location); | 1024 *real_location = info->element_locations[element_index]; |
973 if (element_index < uniform_info.size) { | 1025 *array_index = element_index; |
974 *real_location = uniform_info.element_locations[element_index]; | 1026 return info; |
975 *array_index = element_index; | 1027 } |
976 return &uniform_info; | 1028 |
977 } | 1029 bool Program::IsInactiveUniformLocationByFakeLocation( |
978 } | 1030 GLint fake_location) const { |
979 return NULL; | 1031 if (fake_location < 0) |
1032 return true; | |
1033 size_t location_index = | |
1034 GetUniformLocationIndexFromFakeLocation(fake_location); | |
1035 if (location_index >= uniform_locations_.size()) | |
1036 return false; | |
zmo
2015/11/20 00:23:42
Question: why false here?
Kimmo Kinnunen
2015/11/20 07:56:53
The function returns true only for locations of in
| |
1037 return uniform_locations_[location_index].IsInactive(); | |
980 } | 1038 } |
981 | 1039 |
982 const std::string* Program::GetAttribMappedName( | 1040 const std::string* Program::GetAttribMappedName( |
983 const std::string& original_name) const { | 1041 const std::string& original_name) const { |
984 for (auto shader : attached_shaders_) { | 1042 for (auto shader : attached_shaders_) { |
985 if (shader) { | 1043 if (shader) { |
986 const std::string* mapped_name = | 1044 const std::string* mapped_name = |
987 shader->GetAttribMappedName(original_name); | 1045 shader->GetAttribMappedName(original_name); |
988 if (mapped_name) | 1046 if (mapped_name) |
989 return mapped_name; | 1047 return mapped_name; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1049 // string would exactly match the name of the variable if the suffix "[0]" | 1107 // string would exactly match the name of the variable if the suffix "[0]" |
1050 // were appended to the string". | 1108 // were appended to the string". |
1051 | 1109 |
1052 // At this point we can not know if the string identifies a simple variable, | 1110 // At this point we can not know if the string identifies a simple variable, |
1053 // a base name of an array, or nothing. Store both, so if user overwrites | 1111 // a base name of an array, or nothing. Store both, so if user overwrites |
1054 // either, both still work correctly. | 1112 // either, both still work correctly. |
1055 bind_fragment_input_location_map_[name] = location; | 1113 bind_fragment_input_location_map_[name] = location; |
1056 bind_fragment_input_location_map_[name + "[0]"] = location; | 1114 bind_fragment_input_location_map_[name + "[0]"] = location; |
1057 } | 1115 } |
1058 | 1116 |
1059 // Note: This is only valid to call right after a program has been linked | |
1060 // successfully. | |
1061 void Program::GetCorrectedUniformData( | |
1062 const std::string& name, | |
1063 std::string* corrected_name, std::string* original_name, | |
1064 GLsizei* size, GLenum* type) const { | |
1065 DCHECK(corrected_name && original_name && size && type); | |
1066 for (auto shader : attached_shaders_) { | |
1067 if (!shader) | |
1068 continue; | |
1069 const sh::ShaderVariable* info = NULL; | |
1070 const sh::Uniform* uniform = shader->GetUniformInfo(name); | |
1071 bool found = false; | |
1072 if (uniform) | |
1073 found = uniform->findInfoByMappedName(name, &info, original_name); | |
1074 if (found) { | |
1075 const std::string kArraySpec("[0]"); | |
1076 if (info->arraySize > 0 && | |
1077 !base::EndsWith(name, kArraySpec, base::CompareCase::SENSITIVE)) { | |
1078 *corrected_name = name + kArraySpec; | |
1079 *original_name += kArraySpec; | |
1080 } else { | |
1081 *corrected_name = name; | |
1082 } | |
1083 *type = info->type; | |
1084 *size = std::max(1u, info->arraySize); | |
1085 return; | |
1086 } | |
1087 } | |
1088 // TODO(zmo): this path should never be reached unless there is a serious | |
1089 // bug in the driver or in ANGLE translator. | |
1090 *corrected_name = name; | |
1091 *original_name = name; | |
1092 } | |
1093 | |
1094 void Program::GetVertexAttribData( | 1117 void Program::GetVertexAttribData( |
1095 const std::string& name, std::string* original_name, GLenum* type) const { | 1118 const std::string& name, std::string* original_name, GLenum* type) const { |
1096 DCHECK(original_name); | 1119 DCHECK(original_name); |
1097 DCHECK(type); | 1120 DCHECK(type); |
1098 Shader* shader = attached_shaders_[ShaderTypeToIndex(GL_VERTEX_SHADER)].get(); | 1121 Shader* shader = attached_shaders_[ShaderTypeToIndex(GL_VERTEX_SHADER)].get(); |
1099 if (shader) { | 1122 if (shader) { |
1100 // Vertex attributes can not be arrays or structs (GLSL ES 3.00.4, section | 1123 // Vertex attributes can not be arrays or structs (GLSL ES 3.00.4, section |
1101 // 4.3.4, "Input Variables"), so the top level sh::Attribute returns the | 1124 // 4.3.4, "Input Variables"), so the top level sh::Attribute returns the |
1102 // information we need. | 1125 // information we need. |
1103 const sh::Attribute* info = shader->GetAttribInfo(name); | 1126 const sh::Attribute* info = shader->GetAttribInfo(name); |
1104 if (info) { | 1127 if (info) { |
1105 *original_name = info->name; | 1128 *original_name = info->name; |
1106 *type = info->type; | 1129 *type = info->type; |
1107 return; | 1130 return; |
1108 } | 1131 } |
1109 } | 1132 } |
1110 // TODO(zmo): this path should never be reached unless there is a serious | 1133 // TODO(zmo): this path should never be reached unless there is a serious |
1111 // bug in the driver or in ANGLE translator. | 1134 // bug in the driver or in ANGLE translator. |
1112 *original_name = name; | 1135 *original_name = name; |
1113 } | 1136 } |
1114 | 1137 |
1115 void Program::AddUniformInfo( | |
1116 GLsizei size, GLenum type, GLint location, GLint fake_base_location, | |
1117 const std::string& name, const std::string& original_name, | |
1118 size_t* next_available_index) { | |
1119 DCHECK(next_available_index); | |
1120 const char* kArraySpec = "[0]"; | |
1121 size_t uniform_index = | |
1122 fake_base_location >= 0 ? fake_base_location : *next_available_index; | |
1123 if (uniform_infos_.size() < uniform_index + 1) { | |
1124 uniform_infos_.resize(uniform_index + 1); | |
1125 } | |
1126 | |
1127 // Before linking, we already validated that no two statically used uniforms | |
1128 // are bound to the same location. | |
1129 DCHECK(!uniform_infos_[uniform_index].IsValid()); | |
1130 | |
1131 uniform_infos_[uniform_index] = UniformInfo( | |
1132 size, type, uniform_index, original_name); | |
1133 ++num_uniforms_; | |
1134 | |
1135 UniformInfo& info = uniform_infos_[uniform_index]; | |
1136 info.element_locations.resize(size); | |
1137 info.element_locations[0] = location; | |
1138 DCHECK_LE(0, size); | |
1139 size_t num_texture_units = info.IsSampler() ? static_cast<size_t>(size) : 0u; | |
1140 info.texture_units.clear(); | |
1141 info.texture_units.resize(num_texture_units, 0); | |
1142 | |
1143 if (size > 1) { | |
1144 // Go through the array element locations looking for a match. | |
1145 // We can skip the first element because it's the same as the | |
1146 // the location without the array operators. | |
1147 size_t array_pos = name.rfind(kArraySpec); | |
1148 std::string base_name = name; | |
1149 if (name.size() > 3) { | |
1150 if (array_pos != name.size() - 3) { | |
1151 info.name = name + kArraySpec; | |
1152 } else { | |
1153 base_name = name.substr(0, name.size() - 3); | |
1154 } | |
1155 } | |
1156 for (GLsizei ii = 1; ii < info.size; ++ii) { | |
1157 std::string element_name(base_name + "[" + base::IntToString(ii) + "]"); | |
1158 info.element_locations[ii] = | |
1159 glGetUniformLocation(service_id_, element_name.c_str()); | |
1160 } | |
1161 } | |
1162 | |
1163 info.is_array = | |
1164 (size > 1 || | |
1165 (info.name.size() > 3 && | |
1166 info.name.rfind(kArraySpec) == info.name.size() - 3)); | |
1167 | |
1168 if (info.IsSampler()) { | |
1169 sampler_indices_.push_back(info.fake_location_base); | |
1170 } | |
1171 max_uniform_name_length_ = | |
1172 std::max(max_uniform_name_length_, | |
1173 static_cast<GLsizei>(info.name.size())); | |
1174 | |
1175 while (*next_available_index < uniform_infos_.size() && | |
1176 uniform_infos_[*next_available_index].IsValid()) { | |
1177 *next_available_index = *next_available_index + 1; | |
1178 } | |
1179 } | |
1180 | |
1181 const Program::UniformInfo* | 1138 const Program::UniformInfo* |
1182 Program::GetUniformInfo( | 1139 Program::GetUniformInfo( |
1183 GLint index) const { | 1140 GLint index) const { |
1184 if (static_cast<size_t>(index) >= uniform_infos_.size()) { | 1141 if (static_cast<size_t>(index) >= uniform_infos_.size()) { |
1185 return NULL; | 1142 return NULL; |
1186 } | 1143 } |
1187 | 1144 return &uniform_infos_[index]; |
1188 const UniformInfo& info = uniform_infos_[index]; | |
1189 return info.IsValid() ? &info : NULL; | |
1190 } | 1145 } |
1191 | 1146 |
1192 bool Program::SetSamplers( | 1147 bool Program::SetSamplers( |
1193 GLint num_texture_units, GLint fake_location, | 1148 GLint num_texture_units, GLint fake_location, |
1194 GLsizei count, const GLint* value) { | 1149 GLsizei count, const GLint* value) { |
1195 if (fake_location < 0) { | 1150 if (fake_location < 0) { |
1196 return true; | 1151 return true; |
1197 } | 1152 } |
1198 GLint uniform_index = GetUniformInfoIndexFromFakeLocation(fake_location); | 1153 size_t location_index = |
1199 if (uniform_index >= 0 && | 1154 GetUniformLocationIndexFromFakeLocation(fake_location); |
1200 static_cast<size_t>(uniform_index) < uniform_infos_.size()) { | 1155 if (location_index >= uniform_infos_.size()) |
1201 UniformInfo& info = uniform_infos_[uniform_index]; | 1156 return false; |
1202 if (!info.IsValid()) { | 1157 |
1203 return false; | 1158 if (!uniform_locations_[location_index].IsActive()) |
1204 } | 1159 return false; |
1205 GLint element_index = GetArrayElementIndexFromFakeLocation(fake_location); | 1160 |
1206 if (element_index < info.size) { | 1161 UniformInfo* info = uniform_locations_[location_index].uniform(); |
1207 count = std::min(info.size - element_index, count); | 1162 |
1208 if (info.IsSampler() && count > 0) { | 1163 size_t element_index = GetArrayElementIndexFromFakeLocation(fake_location); |
1209 for (GLsizei ii = 0; ii < count; ++ii) { | 1164 if (static_cast<GLsizei>(element_index) >= info->size) |
1210 if (value[ii] < 0 || value[ii] >= num_texture_units) { | 1165 return true; |
1211 return false; | 1166 count = std::min(info->size - static_cast<GLsizei>(element_index), count); |
1212 } | 1167 if (info->IsSampler() && count > 0) { |
1213 } | 1168 for (GLsizei ii = 0; ii < count; ++ii) { |
1214 std::copy(value, value + count, | 1169 if (value[ii] < 0 || value[ii] >= num_texture_units) { |
1215 info.texture_units.begin() + element_index); | 1170 return false; |
1216 return true; | |
1217 } | 1171 } |
1218 } | 1172 } |
1173 std::copy(value, value + count, | |
1174 info->texture_units.begin() + element_index); | |
1175 return true; | |
1219 } | 1176 } |
1220 return true; | 1177 return true; |
1221 } | 1178 } |
1222 | 1179 |
1223 void Program::GetProgramiv(GLenum pname, GLint* params) { | 1180 void Program::GetProgramiv(GLenum pname, GLint* params) { |
1224 switch (pname) { | 1181 switch (pname) { |
1225 case GL_ACTIVE_ATTRIBUTES: | 1182 case GL_ACTIVE_ATTRIBUTES: |
1226 *params = attrib_infos_.size(); | 1183 *params = attrib_infos_.size(); |
1227 break; | 1184 break; |
1228 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: | 1185 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: |
1229 // Notice +1 to accomodate NULL terminator. | 1186 // Notice +1 to accomodate NULL terminator. |
1230 *params = max_attrib_name_length_ + 1; | 1187 *params = max_attrib_name_length_ + 1; |
1231 break; | 1188 break; |
1232 case GL_ACTIVE_UNIFORMS: | 1189 case GL_ACTIVE_UNIFORMS: |
1233 *params = num_uniforms_; | 1190 *params = uniform_infos_.size(); |
1234 break; | 1191 break; |
1235 case GL_ACTIVE_UNIFORM_MAX_LENGTH: | 1192 case GL_ACTIVE_UNIFORM_MAX_LENGTH: |
1236 // Notice +1 to accomodate NULL terminator. | 1193 // Notice +1 to accomodate NULL terminator. |
1237 *params = max_uniform_name_length_ + 1; | 1194 *params = max_uniform_name_length_ + 1; |
1238 break; | 1195 break; |
1239 case GL_LINK_STATUS: | 1196 case GL_LINK_STATUS: |
1240 *params = link_status_; | 1197 *params = link_status_; |
1241 break; | 1198 break; |
1242 case GL_INFO_LOG_LENGTH: | 1199 case GL_INFO_LOG_LENGTH: |
1243 // Notice +1 to accomodate NULL terminator. | 1200 // Notice +1 to accomodate NULL terminator. |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1585 // of an identifier is 256 characters. | 1542 // of an identifier is 256 characters. |
1586 uint32 num_locations = 0; | 1543 uint32 num_locations = 0; |
1587 uint32 total_string_size = 0; | 1544 uint32 total_string_size = 0; |
1588 | 1545 |
1589 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { | 1546 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { |
1590 const VertexAttrib& info = attrib_infos_[ii]; | 1547 const VertexAttrib& info = attrib_infos_[ii]; |
1591 num_locations += 1; | 1548 num_locations += 1; |
1592 total_string_size += info.name.size(); | 1549 total_string_size += info.name.size(); |
1593 } | 1550 } |
1594 | 1551 |
1595 for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { | 1552 for (const UniformInfo& info : uniform_infos_) { |
1596 const UniformInfo& info = uniform_infos_[ii]; | 1553 num_locations += info.element_locations.size(); |
1597 if (info.IsValid()) { | 1554 total_string_size += info.name.size(); |
1598 num_locations += info.element_locations.size(); | |
1599 total_string_size += info.name.size(); | |
1600 } | |
1601 } | 1555 } |
1602 | 1556 |
1603 uint32 num_inputs = attrib_infos_.size() + num_uniforms_; | 1557 uint32 num_inputs = attrib_infos_.size() + uniform_infos_.size(); |
1604 uint32 input_size = num_inputs * sizeof(ProgramInput); | 1558 uint32 input_size = num_inputs * sizeof(ProgramInput); |
1605 uint32 location_size = num_locations * sizeof(int32); | 1559 uint32 location_size = num_locations * sizeof(int32); |
1606 uint32 size = sizeof(ProgramInfoHeader) + | 1560 uint32 size = sizeof(ProgramInfoHeader) + |
1607 input_size + location_size + total_string_size; | 1561 input_size + location_size + total_string_size; |
1608 | 1562 |
1609 bucket->SetSize(size); | 1563 bucket->SetSize(size); |
1610 ProgramInfoHeader* header = bucket->GetDataAs<ProgramInfoHeader*>(0, size); | 1564 ProgramInfoHeader* header = bucket->GetDataAs<ProgramInfoHeader*>(0, size); |
1611 ProgramInput* inputs = bucket->GetDataAs<ProgramInput*>( | 1565 ProgramInput* inputs = bucket->GetDataAs<ProgramInput*>( |
1612 sizeof(ProgramInfoHeader), input_size); | 1566 sizeof(ProgramInfoHeader), input_size); |
1613 int32* locations = bucket->GetDataAs<int32*>( | 1567 int32* locations = bucket->GetDataAs<int32*>( |
1614 sizeof(ProgramInfoHeader) + input_size, location_size); | 1568 sizeof(ProgramInfoHeader) + input_size, location_size); |
1615 char* strings = bucket->GetDataAs<char*>( | 1569 char* strings = bucket->GetDataAs<char*>( |
1616 sizeof(ProgramInfoHeader) + input_size + location_size, | 1570 sizeof(ProgramInfoHeader) + input_size + location_size, |
1617 total_string_size); | 1571 total_string_size); |
1618 DCHECK(header); | 1572 DCHECK(header); |
1619 DCHECK(inputs); | 1573 DCHECK(inputs); |
1620 DCHECK(locations); | 1574 DCHECK(locations); |
1621 DCHECK(strings); | 1575 DCHECK(strings); |
1622 | 1576 |
1623 header->link_status = link_status_; | 1577 header->link_status = link_status_; |
1624 header->num_attribs = attrib_infos_.size(); | 1578 header->num_attribs = attrib_infos_.size(); |
1625 header->num_uniforms = num_uniforms_; | 1579 header->num_uniforms = uniform_infos_.size(); |
1626 | 1580 |
1627 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { | 1581 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { |
1628 const VertexAttrib& info = attrib_infos_[ii]; | 1582 const VertexAttrib& info = attrib_infos_[ii]; |
1629 inputs->size = info.size; | 1583 inputs->size = info.size; |
1630 inputs->type = info.type; | 1584 inputs->type = info.type; |
1631 inputs->location_offset = ComputeOffset(header, locations); | 1585 inputs->location_offset = ComputeOffset(header, locations); |
1632 inputs->name_offset = ComputeOffset(header, strings); | 1586 inputs->name_offset = ComputeOffset(header, strings); |
1633 inputs->name_length = info.name.size(); | 1587 inputs->name_length = info.name.size(); |
1634 *locations++ = info.location; | 1588 *locations++ = info.location; |
1635 memcpy(strings, info.name.c_str(), info.name.size()); | 1589 memcpy(strings, info.name.c_str(), info.name.size()); |
1636 strings += info.name.size(); | 1590 strings += info.name.size(); |
1637 ++inputs; | 1591 ++inputs; |
1638 } | 1592 } |
1639 | 1593 |
1640 for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { | 1594 for (const UniformInfo& info : uniform_infos_) { |
1641 const UniformInfo& info = uniform_infos_[ii]; | 1595 inputs->size = info.size; |
1642 if (info.IsValid()) { | 1596 inputs->type = info.type; |
1643 inputs->size = info.size; | 1597 inputs->location_offset = ComputeOffset(header, locations); |
1644 inputs->type = info.type; | 1598 inputs->name_offset = ComputeOffset(header, strings); |
1645 inputs->location_offset = ComputeOffset(header, locations); | 1599 inputs->name_length = info.name.size(); |
1646 inputs->name_offset = ComputeOffset(header, strings); | 1600 DCHECK(static_cast<size_t>(info.size) == info.element_locations.size()); |
1647 inputs->name_length = info.name.size(); | 1601 for (size_t jj = 0; jj < info.element_locations.size(); ++jj) { |
1648 DCHECK(static_cast<size_t>(info.size) == info.element_locations.size()); | 1602 if (info.element_locations[jj] == -1) |
1649 for (size_t jj = 0; jj < info.element_locations.size(); ++jj) { | 1603 *locations++ = -1; |
1650 if (info.element_locations[jj] == -1) | 1604 else |
1651 *locations++ = -1; | 1605 *locations++ = |
1652 else | 1606 ProgramManager::MakeFakeLocation(info.fake_location_base, jj); |
1653 *locations++ = ProgramManager::MakeFakeLocation(ii, jj); | |
1654 } | |
1655 memcpy(strings, info.name.c_str(), info.name.size()); | |
1656 strings += info.name.size(); | |
1657 ++inputs; | |
1658 } | 1607 } |
1608 memcpy(strings, info.name.c_str(), info.name.size()); | |
1609 strings += info.name.size(); | |
1610 ++inputs; | |
1659 } | 1611 } |
1612 // NOTE: currently we do not pass inactive uniform binding locations | |
1613 // through the program info call. | |
1660 | 1614 |
1661 // NOTE: currently we do not pass fragment input infos through the program | 1615 // NOTE: currently we do not pass fragment input infos through the program |
1662 // info call, because they are not exposed through any getter function. | 1616 // info call, because they are not exposed through any getter function. |
1663 | 1617 |
1664 DCHECK_EQ(ComputeOffset(header, strings), size); | 1618 DCHECK_EQ(ComputeOffset(header, strings), size); |
1665 } | 1619 } |
1666 | 1620 |
1667 bool Program::GetUniformBlocks(CommonDecoder::Bucket* bucket) const { | 1621 bool Program::GetUniformBlocks(CommonDecoder::Bucket* bucket) const { |
1668 // The data is packed into the bucket in the following order | 1622 // The data is packed into the bucket in the following order |
1669 // 1) header | 1623 // 1) header |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2103 DCHECK(program); | 2057 DCHECK(program); |
2104 program->ClearUniforms(&zero_); | 2058 program->ClearUniforms(&zero_); |
2105 } | 2059 } |
2106 | 2060 |
2107 int32 ProgramManager::MakeFakeLocation(int32 index, int32 element) { | 2061 int32 ProgramManager::MakeFakeLocation(int32 index, int32 element) { |
2108 return index + element * 0x10000; | 2062 return index + element * 0x10000; |
2109 } | 2063 } |
2110 | 2064 |
2111 } // namespace gles2 | 2065 } // namespace gles2 |
2112 } // namespace gpu | 2066 } // namespace gpu |
OLD | NEW |