| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
| 12 #include "base/rand_util.h" |
| 12 #include "base/string_number_conversions.h" | 13 #include "base/string_number_conversions.h" |
| 13 #include "gpu/command_buffer/common/gles2_cmd_format.h" | 14 #include "gpu/command_buffer/common/gles2_cmd_format.h" |
| 14 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 15 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| 15 | 16 |
| 16 namespace gpu { | 17 namespace gpu { |
| 17 namespace gles2 { | 18 namespace gles2 { |
| 18 | 19 |
| 19 static int ShaderTypeToIndex(GLenum shader_type) { | 20 static int ShaderTypeToIndex(GLenum shader_type) { |
| 20 switch (shader_type) { | 21 switch (shader_type) { |
| 21 case GL_VERTEX_SHADER: | 22 case GL_VERTEX_SHADER: |
| (...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 } | 444 } |
| 444 return true; | 445 return true; |
| 445 } | 446 } |
| 446 | 447 |
| 447 static uint32 ComputeOffset(const void* start, const void* position) { | 448 static uint32 ComputeOffset(const void* start, const void* position) { |
| 448 return static_cast<const uint8*>(position) - | 449 return static_cast<const uint8*>(position) - |
| 449 static_cast<const uint8*>(start); | 450 static_cast<const uint8*>(start); |
| 450 } | 451 } |
| 451 | 452 |
| 452 void ProgramManager::ProgramInfo::GetProgramInfo( | 453 void ProgramManager::ProgramInfo::GetProgramInfo( |
| 453 CommonDecoder::Bucket* bucket) const { | 454 ProgramManager* manager, CommonDecoder::Bucket* bucket) const { |
| 454 // NOTE: It seems to me the math in here does not need check for overflow | 455 // NOTE: It seems to me the math in here does not need check for overflow |
| 455 // because the data being calucated from has various small limits. The max | 456 // because the data being calucated from has various small limits. The max |
| 456 // number of attribs + uniforms is somewhere well under 1024. The maximum size | 457 // number of attribs + uniforms is somewhere well under 1024. The maximum size |
| 457 // of an identifier is 256 characters. | 458 // of an identifier is 256 characters. |
| 458 uint32 num_locations = 0; | 459 uint32 num_locations = 0; |
| 459 uint32 total_string_size = 0; | 460 uint32 total_string_size = 0; |
| 460 | 461 |
| 461 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { | 462 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { |
| 462 const VertexAttribInfo& info = attrib_infos_[ii]; | 463 const VertexAttribInfo& info = attrib_infos_[ii]; |
| 463 num_locations += 1; | 464 num_locations += 1; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 | 510 |
| 510 for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { | 511 for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { |
| 511 const UniformInfo& info = uniform_infos_[ii]; | 512 const UniformInfo& info = uniform_infos_[ii]; |
| 512 inputs->size = info.size; | 513 inputs->size = info.size; |
| 513 inputs->type = info.type; | 514 inputs->type = info.type; |
| 514 inputs->location_offset = ComputeOffset(header, locations); | 515 inputs->location_offset = ComputeOffset(header, locations); |
| 515 inputs->name_offset = ComputeOffset(header, strings); | 516 inputs->name_offset = ComputeOffset(header, strings); |
| 516 inputs->name_length = info.name.size(); | 517 inputs->name_length = info.name.size(); |
| 517 DCHECK(static_cast<size_t>(info.size) == info.element_locations.size()); | 518 DCHECK(static_cast<size_t>(info.size) == info.element_locations.size()); |
| 518 for (size_t jj = 0; jj < info.element_locations.size(); ++jj) { | 519 for (size_t jj = 0; jj < info.element_locations.size(); ++jj) { |
| 519 *locations++ = info.element_locations[jj]; | 520 *locations++ = manager->SwizzleLocation(info.element_locations[jj]); |
| 520 } | 521 } |
| 521 memcpy(strings, info.name.c_str(), info.name.size()); | 522 memcpy(strings, info.name.c_str(), info.name.size()); |
| 522 strings += info.name.size(); | 523 strings += info.name.size(); |
| 523 ++inputs; | 524 ++inputs; |
| 524 } | 525 } |
| 525 | 526 |
| 526 DCHECK_EQ(ComputeOffset(header, strings), size); | 527 DCHECK_EQ(ComputeOffset(header, strings), size); |
| 527 } | 528 } |
| 528 | 529 |
| 529 ProgramManager::ProgramInfo::~ProgramInfo() {} | 530 ProgramManager::ProgramInfo::~ProgramInfo() {} |
| 530 | 531 |
| 531 ProgramManager::ProgramManager() {} | 532 ProgramManager::ProgramManager() |
| 533 : uniform_swizzle_(base::RandInt(0, 15)) { |
| 534 } |
| 532 | 535 |
| 533 ProgramManager::~ProgramManager() { | 536 ProgramManager::~ProgramManager() { |
| 534 DCHECK(program_infos_.empty()); | 537 DCHECK(program_infos_.empty()); |
| 535 } | 538 } |
| 536 | 539 |
| 537 void ProgramManager::Destroy(bool have_context) { | 540 void ProgramManager::Destroy(bool have_context) { |
| 538 while (!program_infos_.empty()) { | 541 while (!program_infos_.empty()) { |
| 539 if (have_context) { | 542 if (have_context) { |
| 540 ProgramInfo* info = program_infos_.begin()->second; | 543 ProgramInfo* info = program_infos_.begin()->second; |
| 541 if (!info->IsDeleted()) { | 544 if (!info->IsDeleted()) { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 621 void ProgramManager::UnuseProgram( | 624 void ProgramManager::UnuseProgram( |
| 622 ShaderManager* shader_manager, | 625 ShaderManager* shader_manager, |
| 623 ProgramManager::ProgramInfo* info) { | 626 ProgramManager::ProgramInfo* info) { |
| 624 DCHECK(shader_manager); | 627 DCHECK(shader_manager); |
| 625 DCHECK(info); | 628 DCHECK(info); |
| 626 DCHECK(IsOwned(info)); | 629 DCHECK(IsOwned(info)); |
| 627 info->DecUseCount(); | 630 info->DecUseCount(); |
| 628 RemoveProgramInfoIfUnused(shader_manager, info); | 631 RemoveProgramInfoIfUnused(shader_manager, info); |
| 629 } | 632 } |
| 630 | 633 |
| 634 // Swizzles the locations to prevent developers from assuming they |
| 635 // can do math on uniforms. According to the OpenGL ES 2.0 spec |
| 636 // the location of "someuniform[1]" is not 1 more than "someuniform[0]". |
| 637 static GLint Swizzle(GLint location) { |
| 638 return (location & 0xFFFF0000U) | |
| 639 ((location & 0x0000AAAAU) >> 1) | |
| 640 ((location & 0x00005555U) << 1); |
| 641 } |
| 642 |
| 643 // Adds uniform_swizzle_ to prevent developers from assuming that locations are |
| 644 // always the same across GPUs and drivers. |
| 645 GLint ProgramManager::SwizzleLocation(GLint v) const { |
| 646 return v < 0 ? v : (Swizzle(v) + uniform_swizzle_); |
| 647 } |
| 648 |
| 649 GLint ProgramManager::UnswizzleLocation(GLint v) const { |
| 650 return v < 0 ? v : Swizzle(v - uniform_swizzle_); |
| 651 } |
| 652 |
| 631 } // namespace gles2 | 653 } // namespace gles2 |
| 632 } // namespace gpu | 654 } // namespace gpu |
| 633 | 655 |
| 634 | 656 |
| OLD | NEW |