Index: gpu/command_buffer/service/program_manager.cc |
diff --git a/gpu/command_buffer/service/program_manager.cc b/gpu/command_buffer/service/program_manager.cc |
index 5d504a4afc97ae20a14c43f529ec652a37b86332..0eb90a332a6c1d838380186cf2cabcd14580d155 100644 |
--- a/gpu/command_buffer/service/program_manager.cc |
+++ b/gpu/command_buffer/service/program_manager.cc |
@@ -6,6 +6,7 @@ |
#include <algorithm> |
#include <set> |
+#include <vector> |
#include "base/basictypes.h" |
#include "base/command_line.h" |
@@ -163,6 +164,24 @@ void ProgramManager::ProgramInfo::ClearUniforms( |
} |
} |
+namespace { |
+ |
+struct UniformData { |
+ std::string queried_name; |
+ std::string corrected_name; |
+ std::string original_name; |
+ GLsizei size; |
+ GLenum type; |
+}; |
+ |
+struct UniformDataComparer { |
+ bool operator()(const UniformData& lhs, const UniformData& rhs) const { |
+ return lhs.queried_name < rhs.queried_name; |
+ } |
+}; |
+ |
+} // anonymous namespace |
+ |
void ProgramManager::ProgramInfo::Update() { |
Reset(); |
UpdateLogInfo(); |
@@ -215,31 +234,42 @@ void ProgramManager::ProgramInfo::Update() { |
glGetProgramiv(service_id_, GL_ACTIVE_UNIFORMS, &num_uniforms); |
glGetProgramiv(service_id_, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_len); |
name_buffer.reset(new char[max_len]); |
+ |
+ // Read all the names first and sort them so we get a consistent list |
+ std::vector<UniformData> uniform_data_; |
for (GLint ii = 0; ii < num_uniforms; ++ii) { |
GLsizei length = 0; |
- GLsizei size = 0; |
- GLenum type = 0; |
+ UniformData data; |
glGetActiveUniform( |
- service_id_, ii, max_len, &length, &size, &type, name_buffer.get()); |
+ service_id_, ii, max_len, &length, |
+ &data.size, &data.type, name_buffer.get()); |
DCHECK(max_len == 0 || length < max_len); |
DCHECK(length == 0 || name_buffer[length] == '\0'); |
- // TODO(gman): Should we check for error? |
if (!IsInvalidPrefix(name_buffer.get(), length)) { |
- GLint location = glGetUniformLocation(service_id_, name_buffer.get()); |
- std::string name; |
- std::string original_name; |
+ data.queried_name = std::string(name_buffer.get()); |
GetCorrectedVariableInfo( |
- true, name_buffer.get(), &name, &original_name, &size, &type); |
- const UniformInfo* info = AddUniformInfo( |
- size, type, location, name, original_name); |
- if (info->IsSampler()) { |
- sampler_indices_.push_back(info->fake_location_base); |
- } |
- max_uniform_name_length_ = |
- std::max(max_uniform_name_length_, |
- static_cast<GLsizei>(info->name.size())); |
+ true, name_buffer.get(), &data.corrected_name, &data.original_name, |
+ &data.size, &data.type); |
+ uniform_data_.push_back(data); |
} |
} |
+ |
+ std::sort(uniform_data_.begin(), uniform_data_.end(), UniformDataComparer()); |
+ |
+ for (size_t ii = 0; ii < uniform_data_.size(); ++ii) { |
+ const UniformData& data = uniform_data_[ii]; |
+ GLint location = glGetUniformLocation( |
+ service_id_, data.queried_name.c_str()); |
+ const UniformInfo* info = AddUniformInfo( |
+ data.size, data.type, location, data.corrected_name, |
+ data.original_name); |
+ if (info->IsSampler()) { |
+ sampler_indices_.push_back(info->fake_location_base); |
+ } |
+ max_uniform_name_length_ = |
+ std::max(max_uniform_name_length_, |
+ static_cast<GLsizei>(info->name.size())); |
+ } |
valid_ = true; |
} |
@@ -312,7 +342,7 @@ GLint ProgramManager::ProgramInfo::GetUniformFakeLocation( |
index = index * 10 + digit; |
} |
if (!bad && index >= 0 && index < info.size) { |
- return GetFakeLocation(info.fake_location_base, index); |
+ return GLES2Util::MakeFakeLocation(info.fake_location_base, index); |
} |
} |
} |
@@ -658,7 +688,8 @@ void ProgramManager::ProgramInfo::GetProgramInfo( |
inputs->name_length = info.name.size(); |
DCHECK(static_cast<size_t>(info.size) == info.element_locations.size()); |
for (size_t jj = 0; jj < info.element_locations.size(); ++jj) { |
- *locations++ = manager->SwizzleLocation(ii + jj * 0x10000); |
+ *locations++ = GLES2Util::SwizzleLocation( |
+ GLES2Util::MakeFakeLocation(ii, jj)); |
} |
memcpy(strings, info.name.c_str(), info.name.size()); |
strings += info.name.size(); |
@@ -678,14 +709,8 @@ ProgramManager::ProgramInfo::~ProgramInfo() { |
} |
} |
-// TODO(gman): make this some kind of random number. Base::RandInt is not |
-// callable because of the sandbox. What matters is that it's possibly different |
-// by at least 1 bit each time chrome is run. |
-static int uniform_random_offset_ = 3; |
- |
ProgramManager::ProgramManager() |
- : uniform_swizzle_(uniform_random_offset_++ % 15), |
- program_info_count_(0), |
+ : program_info_count_(0), |
have_context_(true), |
disable_workarounds_( |
CommandLine::ForCurrentProcess()->HasSwitch( |
@@ -798,25 +823,6 @@ void ProgramManager::ClearUniforms(ProgramManager::ProgramInfo* info) { |
} |
} |
-// Swizzles the locations to prevent developers from assuming they |
-// can do math on uniforms. According to the OpenGL ES 2.0 spec |
-// the location of "someuniform[1]" is not 'n' more than "someuniform[0]". |
-static GLint Swizzle(GLint location) { |
- return (location & 0xF0000000U) | |
- ((location & 0x0AAAAAAAU) >> 1) | |
- ((location & 0x05555555U) << 1); |
-} |
- |
-// Adds uniform_swizzle_ to prevent developers from assuming that locations are |
-// always the same across GPUs and drivers. |
-GLint ProgramManager::SwizzleLocation(GLint v) const { |
- return v < 0 ? v : (Swizzle(v) + uniform_swizzle_); |
-} |
- |
-GLint ProgramManager::UnswizzleLocation(GLint v) const { |
- return v < 0 ? v : Swizzle(v - uniform_swizzle_); |
-} |
- |
} // namespace gles2 |
} // namespace gpu |