summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzmo@google.com <zmo@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-04 00:18:08 +0000
committerzmo@google.com <zmo@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-04 00:18:08 +0000
commit5b6f52fae391c57efaedc0d4a359466760247d10 (patch)
tree3b2e81e1dee71605e722104ff6821522eb311b73
parent9400c64565586091f67d4131850fd0836b18b511 (diff)
downloadchromium_src-5b6f52fae391c57efaedc0d4a359466760247d10.zip
chromium_src-5b6f52fae391c57efaedc0d4a359466760247d10.tar.gz
chromium_src-5b6f52fae391c57efaedc0d4a359466760247d10.tar.bz2
Hook up shader long variable name mapping with GPU command buffer port.
shader long variable name mapping is implemented in Angle shader translator. We should hook up the feature with GPU command buffer so long names won't cause shader compile/link failure or crashes. BUG=84753 TEST=tree green, webgl's conformance/glsl-conformance.html and conformance/glsl-long-variable-names pass on all platforms (Mac/Win/Linux), gles2 conformance test suites run ok. Review URL: http://codereview.chromium.org/6969100 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@87899 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--gpu/command_buffer/service/program_manager.cc33
-rw-r--r--gpu/command_buffer/service/program_manager.h5
-rw-r--r--gpu/command_buffer/service/program_manager_unittest.cc14
-rw-r--r--gpu/command_buffer/service/shader_manager_unittest.cc10
-rw-r--r--gpu/command_buffer/service/shader_translator.cc19
-rw-r--r--gpu/command_buffer/service/shader_translator.h6
-rw-r--r--gpu/command_buffer/service/shader_translator_unittest.cc3
7 files changed, 55 insertions, 35 deletions
diff --git a/gpu/command_buffer/service/program_manager.cc b/gpu/command_buffer/service/program_manager.cc
index 3591e4d..530fc37 100644
--- a/gpu/command_buffer/service/program_manager.cc
+++ b/gpu/command_buffer/service/program_manager.cc
@@ -102,14 +102,18 @@ void ProgramManager::ProgramInfo::Update() {
DCHECK(length == 0 || name_buffer[length] == '\0');
if (!IsInvalidPrefix(name_buffer.get(), length)) {
std::string name;
- GetCorrectedVariableInfo(false, name_buffer.get(), &name, &size, &type);
+ std::string original_name;
+ GetCorrectedVariableInfo(
+ false, name_buffer.get(), &name, &original_name, &size, &type);
// TODO(gman): Should we check for error?
GLint location = glGetAttribLocation(service_id_, name_buffer.get());
if (location > max_location) {
max_location = location;
}
- attrib_infos_.push_back(VertexAttribInfo(size, type, name, location));
- max_attrib_name_length_ = std::max(max_attrib_name_length_, length);
+ attrib_infos_.push_back(
+ VertexAttribInfo(size, type, original_name, location));
+ max_attrib_name_length_ = std::max(
+ max_attrib_name_length_, static_cast<GLsizei>(original_name.size()));
}
}
@@ -142,8 +146,11 @@ void ProgramManager::ProgramInfo::Update() {
if (!IsInvalidPrefix(name_buffer.get(), length)) {
GLint location = glGetUniformLocation(service_id_, name_buffer.get());
std::string name;
- GetCorrectedVariableInfo(true, name_buffer.get(), &name, &size, &type);
- const UniformInfo* info = AddUniformInfo(size, type, location, name);
+ std::string original_name;
+ GetCorrectedVariableInfo(
+ true, name_buffer.get(), &name, &original_name, &size, &type);
+ const UniformInfo* info =
+ AddUniformInfo(size, type, location, name, original_name);
for (size_t jj = 0; jj < info->element_locations.size(); ++jj) {
if (info->element_locations[jj] > max_location) {
max_location = info->element_locations[jj];
@@ -264,8 +271,10 @@ const ProgramManager::ProgramInfo::UniformInfo*
void ProgramManager::ProgramInfo::GetCorrectedVariableInfo(
bool use_uniforms,
const std::string& name, std::string* corrected_name,
+ std::string* original_name,
GLsizei* size, GLenum* type) const {
DCHECK(corrected_name);
+ DCHECK(original_name);
DCHECK(size);
DCHECK(type);
const char* kArraySpec = "[0]";
@@ -282,6 +291,7 @@ void ProgramManager::ProgramInfo::GetCorrectedVariableInfo(
// for that case?
if (variable_info) {
*corrected_name = test_name;
+ *original_name = variable_info->name;
*type = variable_info->type;
*size = variable_info->size;
return;
@@ -290,13 +300,15 @@ void ProgramManager::ProgramInfo::GetCorrectedVariableInfo(
}
}
*corrected_name = name;
+ *original_name = name;
}
const ProgramManager::ProgramInfo::UniformInfo*
ProgramManager::ProgramInfo::AddUniformInfo(
- GLsizei size, GLenum type, GLint location, const std::string& name) {
+ GLsizei size, GLenum type, GLint location, const std::string& name,
+ const std::string& original_name) {
const char* kArraySpec = "[0]";
- uniform_infos_.push_back(UniformInfo(size, type, name));
+ uniform_infos_.push_back(UniformInfo(size, type, original_name));
UniformInfo& info = uniform_infos_.back();
info.element_locations.resize(size);
info.element_locations[0] = location;
@@ -306,13 +318,6 @@ const ProgramManager::ProgramInfo::UniformInfo*
info.texture_units.resize(num_texture_units, 0);
if (size > 1) {
- // 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.
diff --git a/gpu/command_buffer/service/program_manager.h b/gpu/command_buffer/service/program_manager.h
index 4344a88..a584177 100644
--- a/gpu/command_buffer/service/program_manager.h
+++ b/gpu/command_buffer/service/program_manager.h
@@ -196,11 +196,12 @@ class ProgramManager {
void UpdateLogInfo();
const UniformInfo* AddUniformInfo(
- GLsizei size, GLenum type, GLint location, const std::string& name);
+ GLsizei size, GLenum type, GLint location, const std::string& name,
+ const std::string& original_name);
void GetCorrectedVariableInfo(
bool use_uniforms, const std::string& name, std::string* corrected_name,
- GLsizei* size, GLenum* type) const;
+ std::string* original_name, GLsizei* size, GLenum* type) const;
void DetachShaders(ShaderManager* manager);
diff --git a/gpu/command_buffer/service/program_manager_unittest.cc b/gpu/command_buffer/service/program_manager_unittest.cc
index bb3fb0f..85d5d4a 100644
--- a/gpu/command_buffer/service/program_manager_unittest.cc
+++ b/gpu/command_buffer/service/program_manager_unittest.cc
@@ -623,17 +623,17 @@ TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsWrongTypeInfo) {
ShaderTranslator::VariableMap attrib_map;
ShaderTranslator::VariableMap uniform_map;
attrib_map[kAttrib1Name] = ShaderTranslatorInterface::VariableInfo(
- kAttrib1Type, kAttrib1Size);
+ kAttrib1Type, kAttrib1Size, kAttrib1Name);
attrib_map[kAttrib2Name] = ShaderTranslatorInterface::VariableInfo(
- kAttrib2GoodType, kAttrib2Size);
+ kAttrib2GoodType, kAttrib2Size, kAttrib2Name);
attrib_map[kAttrib3Name] = ShaderTranslatorInterface::VariableInfo(
- kAttrib3Type, kAttrib3Size);
+ kAttrib3Type, kAttrib3Size, kAttrib3Name);
uniform_map[kUniform1Name] = ShaderTranslatorInterface::VariableInfo(
- kUniform1Type, kUniform1Size);
+ kUniform1Type, kUniform1Size, kUniform1Name);
uniform_map[kUniform2Name] = ShaderTranslatorInterface::VariableInfo(
- kUniform2GoodType, kUniform2Size);
+ kUniform2GoodType, kUniform2Size, kUniform2Name);
uniform_map[kUniform3GoodName] = ShaderTranslatorInterface::VariableInfo(
- kUniform3Type, kUniform3Size);
+ kUniform3Type, kUniform3Size, kUniform3GoodName);
EXPECT_CALL(shader_translator, attrib_map())
.WillRepeatedly(ReturnRef(attrib_map));
EXPECT_CALL(shader_translator, uniform_map())
@@ -684,6 +684,7 @@ TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsWrongTypeInfo) {
EXPECT_EQ(it->first, attrib_info->name);
EXPECT_EQ(static_cast<GLenum>(it->second.type), attrib_info->type);
EXPECT_EQ(it->second.size, attrib_info->size);
+ EXPECT_EQ(it->second.name, attrib_info->name);
}
// Check Uniforms
for (unsigned index = 0; index < kNumUniforms; ++index) {
@@ -696,6 +697,7 @@ TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsWrongTypeInfo) {
EXPECT_EQ(it->first, uniform_info->name);
EXPECT_EQ(static_cast<GLenum>(it->second.type), uniform_info->type);
EXPECT_EQ(it->second.size, uniform_info->size);
+ EXPECT_EQ(it->second.name, uniform_info->name);
}
}
diff --git a/gpu/command_buffer/service/shader_manager_unittest.cc b/gpu/command_buffer/service/shader_manager_unittest.cc
index ea1fcf5..23590b78 100644
--- a/gpu/command_buffer/service/shader_manager_unittest.cc
+++ b/gpu/command_buffer/service/shader_manager_unittest.cc
@@ -142,14 +142,14 @@ TEST_F(ShaderManagerTest, GetInfo) {
MockShaderTranslator shader_translator;
ShaderTranslator::VariableMap attrib_map;
attrib_map[kAttrib1Name] = ShaderTranslatorInterface::VariableInfo(
- kAttrib1Type, kAttrib1Size);
+ kAttrib1Type, kAttrib1Size, kAttrib1Name);
attrib_map[kAttrib2Name] = ShaderTranslatorInterface::VariableInfo(
- kAttrib2Type, kAttrib2Size);
+ kAttrib2Type, kAttrib2Size, kAttrib2Name);
ShaderTranslator::VariableMap uniform_map;
uniform_map[kUniform1Name] = ShaderTranslatorInterface::VariableInfo(
- kUniform1Type, kUniform1Size);
+ kUniform1Type, kUniform1Size, kUniform1Name);
uniform_map[kUniform2Name] = ShaderTranslatorInterface::VariableInfo(
- kUniform2Type, kUniform2Size);
+ kUniform2Type, kUniform2Size, kUniform2Name);
EXPECT_CALL(shader_translator, attrib_map())
.WillRepeatedly(ReturnRef(attrib_map));
EXPECT_CALL(shader_translator, uniform_map())
@@ -169,6 +169,7 @@ TEST_F(ShaderManagerTest, GetInfo) {
ASSERT_TRUE(variable_info != NULL);
EXPECT_EQ(it->second.type, variable_info->type);
EXPECT_EQ(it->second.size, variable_info->size);
+ EXPECT_EQ(it->second.name, variable_info->name);
}
for (ShaderTranslator::VariableMap::const_iterator it = uniform_map.begin();
it != uniform_map.end(); ++it) {
@@ -177,6 +178,7 @@ TEST_F(ShaderManagerTest, GetInfo) {
ASSERT_TRUE(variable_info != NULL);
EXPECT_EQ(it->second.type, variable_info->type);
EXPECT_EQ(it->second.size, variable_info->size);
+ EXPECT_EQ(it->second.name, variable_info->name);
}
// Check attrib and uniform get cleared.
info1->SetStatus(true, NULL, NULL);
diff --git a/gpu/command_buffer/service/shader_translator.cc b/gpu/command_buffer/service/shader_translator.cc
index 1ef73fc..c11dcbd 100644
--- a/gpu/command_buffer/service/shader_translator.cc
+++ b/gpu/command_buffer/service/shader_translator.cc
@@ -26,7 +26,7 @@ bool InitializeShaderTranslator() {
using gpu::gles2::ShaderTranslator;
void GetVariableInfo(ShHandle compiler, ShShaderInfo var_type,
ShaderTranslator::VariableMap* var_map) {
- int name_len = 0;
+ int name_len = 0, mapped_name_len = 0;
switch (var_type) {
case SH_ACTIVE_ATTRIBUTES:
ShGetInfo(compiler, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &name_len);
@@ -36,8 +36,10 @@ void GetVariableInfo(ShHandle compiler, ShShaderInfo var_type,
break;
default: NOTREACHED();
}
- if (name_len <= 1) return;
+ ShGetInfo(compiler, SH_MAPPED_NAME_MAX_LENGTH, &mapped_name_len);
+ if (name_len <= 1 || mapped_name_len <= 1) return;
scoped_array<char> name(new char[name_len]);
+ scoped_array<char> mapped_name(new char[mapped_name_len]);
int num_vars = 0;
ShGetInfo(compiler, var_type, &num_vars);
@@ -47,16 +49,18 @@ void GetVariableInfo(ShHandle compiler, ShShaderInfo var_type,
switch (var_type) {
case SH_ACTIVE_ATTRIBUTES:
- ShGetActiveAttrib(compiler, i, NULL, &size, &type, name.get(), NULL);
+ ShGetActiveAttrib(
+ compiler, i, NULL, &size, &type, name.get(), mapped_name.get());
break;
case SH_ACTIVE_UNIFORMS:
- ShGetActiveUniform(compiler, i, NULL, &size, &type, name.get(), NULL);
+ ShGetActiveUniform(
+ compiler, i, NULL, &size, &type, name.get(), mapped_name.get());
break;
default: NOTREACHED();
}
- ShaderTranslator::VariableInfo info(type, size);
- (*var_map)[name.get()] = info;
+ ShaderTranslator::VariableInfo info(type, size, name.get());
+ (*var_map)[mapped_name.get()] = info;
}
}
} // namespace
@@ -99,7 +103,8 @@ bool ShaderTranslator::Translate(const char* shader) {
ClearResults();
bool success = false;
- int compile_options = SH_OBJECT_CODE | SH_ATTRIBUTES_UNIFORMS;
+ int compile_options =
+ SH_OBJECT_CODE | SH_ATTRIBUTES_UNIFORMS | SH_MAP_LONG_VARIABLE_NAMES;
if (ShCompile(compiler_, &shader, 1, compile_options)) {
success = true;
if (!implementation_is_glsl_es_) {
diff --git a/gpu/command_buffer/service/shader_translator.h b/gpu/command_buffer/service/shader_translator.h
index 7e89e8d..cca5aa6 100644
--- a/gpu/command_buffer/service/shader_translator.h
+++ b/gpu/command_buffer/service/shader_translator.h
@@ -45,12 +45,14 @@ class ShaderTranslatorInterface {
: type(0),
size(0) {
}
- VariableInfo(int _type, int _size)
+ VariableInfo(int _type, int _size, std::string _name)
: type(_type),
- size(_size) {
+ size(_size),
+ name(_name) {
}
int type;
int size;
+ std::string name; // name in the original shader source.
};
// Mapping between variable name and info.
typedef base::hash_map<std::string, VariableInfo> VariableMap;
diff --git a/gpu/command_buffer/service/shader_translator_unittest.cc b/gpu/command_buffer/service/shader_translator_unittest.cc
index 9fdabd4..f7468d7 100644
--- a/gpu/command_buffer/service/shader_translator_unittest.cc
+++ b/gpu/command_buffer/service/shader_translator_unittest.cc
@@ -144,6 +144,7 @@ TEST_F(ShaderTranslatorTest, GetAttributes) {
EXPECT_TRUE(iter != attrib_map.end());
EXPECT_EQ(SH_FLOAT_VEC4, iter->second.type);
EXPECT_EQ(1, iter->second.size);
+ EXPECT_EQ("vPosition", iter->second.name);
}
TEST_F(ShaderTranslatorTest, GetUniforms) {
@@ -180,11 +181,13 @@ TEST_F(ShaderTranslatorTest, GetUniforms) {
EXPECT_TRUE(iter != uniform_map.end());
EXPECT_EQ(SH_FLOAT_VEC4, iter->second.type);
EXPECT_EQ(1, iter->second.size);
+ EXPECT_EQ("bar[0].foo.color[0]", iter->second.name);
// Second uniform.
iter = uniform_map.find("bar[1].foo.color[0]");
EXPECT_TRUE(iter != uniform_map.end());
EXPECT_EQ(SH_FLOAT_VEC4, iter->second.type);
EXPECT_EQ(1, iter->second.size);
+ EXPECT_EQ("bar[1].foo.color[0]", iter->second.name);
}
} // namespace gles2