summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer/service/program_manager.cc
diff options
context:
space:
mode:
authorgman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-07 02:54:54 +0000
committergman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-07 02:54:54 +0000
commita471878e54f1195ab917995c2881314c9cda0844 (patch)
tree095d25c98fb468aba8e6dd4b4067a556fb6d9be0 /gpu/command_buffer/service/program_manager.cc
parent0ea7c9ae1a462fb2a01df11400ca1afe7592b0dc (diff)
downloadchromium_src-a471878e54f1195ab917995c2881314c9cda0844.zip
chromium_src-a471878e54f1195ab917995c2881314c9cda0844.tar.gz
chromium_src-a471878e54f1195ab917995c2881314c9cda0844.tar.bz2
Fix uniform array support.
The issues fixed are 2 fold. 1) OpenGL ES 2.0 requires that array names be returned as "name[0]" where as OpenGL implementations sometimes return just "name" 2) When the name is an array name as in "array[0]" we need to match both "array" and "array[0]" TEST=various unit tests BUG=40172 Review URL: http://codereview.chromium.org/1607007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@43805 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu/command_buffer/service/program_manager.cc')
-rw-r--r--gpu/command_buffer/service/program_manager.cc46
1 files changed, 35 insertions, 11 deletions
diff --git a/gpu/command_buffer/service/program_manager.cc b/gpu/command_buffer/service/program_manager.cc
index b53938f..88dd714 100644
--- a/gpu/command_buffer/service/program_manager.cc
+++ b/gpu/command_buffer/service/program_manager.cc
@@ -77,16 +77,23 @@ void ProgramManager::ProgramInfo::Update() {
}
}
-GLint ProgramManager::ProgramInfo::GetUniformLocation(const std::string& name) {
+GLint ProgramManager::ProgramInfo::GetUniformLocation(
+ const std::string& name) const {
for (GLuint ii = 0; ii < uniform_infos_.size(); ++ii) {
const UniformInfo& info = uniform_infos_[ii];
- if (info.name == name) {
+ if (info.name == name ||
+ (info.is_array &&
+ info.name.compare(0, info.name.size() - 3, name) == 0)) {
return info.element_locations[0];
- } else if (name.size() >= 3 && name[name.size() - 1] == ']') {
- // Look for an array specfication.
+ } else if (info.is_array &&
+ name.size() >= 3 && name[name.size() - 1] == ']') {
+ // Look for an array specification.
size_t open_pos = name.find_last_of('[');
- if (open_pos != std::string::npos && open_pos < name.size() - 2) {
- GLuint index = 0;
+ if (open_pos != std::string::npos &&
+ open_pos < name.size() - 2 &&
+ info.name.size() > open_pos &&
+ name.compare(0, open_pos, info.name, 0, open_pos) == 0) {
+ GLint index = 0;
size_t last = name.size() - 1;
bool bad = false;
for (size_t pos = open_pos + 1; pos < last; ++pos) {
@@ -97,8 +104,8 @@ GLint ProgramManager::ProgramInfo::GetUniformLocation(const std::string& name) {
}
index = index * 10 + digit;
}
- if (!bad) {
- return index;
+ if (!bad && index >= 0 && index < info.size) {
+ return info.element_locations[index];
}
}
}
@@ -134,6 +141,7 @@ void ProgramManager::ProgramInfo::SetUniformInfo(
GLint index, GLsizei size, GLenum type, GLint location,
const std::string& name) {
DCHECK(static_cast<unsigned>(index) < uniform_infos_.size());
+ const char* kArraySpec = "[0]";
UniformInfo& info = uniform_infos_[index];
info.size = size;
info.type = type;
@@ -144,16 +152,32 @@ void ProgramManager::ProgramInfo::SetUniformInfo(
info.texture_units.clear();
info.texture_units.resize(num_texture_units, 0);
- // Go through the array element locations looking for a match.
- // We can skip the first element because it's the same as the
- // the location without the array operators.
if (size > 1) {
for (GLsizei ii = 1; ii < info.size; ++ii) {
std::string element_name(name + "[" + IntToString(ii) + "]");
info.element_locations[ii] =
glGetUniformLocation(program_id_, element_name.c_str());
}
+ // Sadly there is no way to tell if this is an array except if the name
+ // has an array string or the size > 1. That means an array of size 1 can
+ // be ambiguous.
+ //
+ // For now we just make sure that if the size is > 1 then the name must have
+ // an array spec.
+
+ // Go through the array element locations looking for a match.
+ // We can skip the first element because it's the same as the
+ // the location without the array operators.
+ size_t array_pos = name.rfind(kArraySpec);
+ if (name.size() > 3 && array_pos != name.size() - 3) {
+ info.name = name + kArraySpec;
+ }
}
+
+ info.is_array =
+ (size > 1 ||
+ (info.name.size() > 3 &&
+ info.name.rfind(kArraySpec) == info.name.size() - 3));
}
bool ProgramManager::ProgramInfo::SetSamplers(