| 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 4dd4bc4d68f4076c8371127fac2f5a45e317f6e8..2d2bf6e638e1f4a98524551ef92bf851635cfde8 100644
|
| --- a/gpu/command_buffer/service/program_manager.cc
|
| +++ b/gpu/command_buffer/service/program_manager.cc
|
| @@ -15,6 +15,7 @@
|
| #include "base/memory/scoped_ptr.h"
|
| #include "base/metrics/histogram.h"
|
| #include "base/strings/string_number_conversions.h"
|
| +#include "base/strings/string_util.h"
|
| #include "base/time/time.h"
|
| #include "gpu/command_buffer/common/gles2_cmd_format.h"
|
| #include "gpu/command_buffer/common/gles2_cmd_utils.h"
|
| @@ -33,28 +34,6 @@ namespace gles2 {
|
|
|
| namespace {
|
|
|
| -struct UniformType {
|
| - explicit UniformType(const ShaderTranslator::VariableInfo uniform)
|
| - : type(uniform.type),
|
| - size(uniform.size),
|
| - precision(uniform.precision) { }
|
| -
|
| - UniformType()
|
| - : type(0),
|
| - size(0),
|
| - precision(SH_PRECISION_MEDIUMP) { }
|
| -
|
| - bool operator==(const UniformType& other) const {
|
| - return type == other.type &&
|
| - size == other.size &&
|
| - precision == other.precision;
|
| - }
|
| -
|
| - int type;
|
| - int size;
|
| - int precision;
|
| -};
|
| -
|
| int ShaderTypeToIndex(GLenum shader_type) {
|
| switch (shader_type) {
|
| case GL_VERTEX_SHADER:
|
| @@ -389,17 +368,15 @@ void Program::Update() {
|
| DCHECK(max_len == 0 || length < max_len);
|
| DCHECK(length == 0 || name_buffer[length] == '\0');
|
| if (!ProgramManager::IsInvalidPrefix(name_buffer.get(), length)) {
|
| - std::string name;
|
| std::string original_name;
|
| - GetCorrectedVariableInfo(
|
| - false, name_buffer.get(), &name, &original_name, &size, &type);
|
| + GetVertexAttribData(name_buffer.get(), &original_name, &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(
|
| - VertexAttrib(size, type, original_name, location));
|
| + VertexAttrib(1, type, original_name, location));
|
| max_attrib_name_length_ = std::max(
|
| max_attrib_name_length_, static_cast<GLsizei>(original_name.size()));
|
| }
|
| @@ -447,9 +424,9 @@ void Program::Update() {
|
| DCHECK(length == 0 || name_buffer[length] == '\0');
|
| if (!ProgramManager::IsInvalidPrefix(name_buffer.get(), length)) {
|
| data.queried_name = std::string(name_buffer.get());
|
| - GetCorrectedVariableInfo(
|
| - true, name_buffer.get(), &data.corrected_name, &data.original_name,
|
| - &data.size, &data.type);
|
| + GetCorrectedUniformData(
|
| + data.queried_name,
|
| + &data.corrected_name, &data.original_name, &data.size, &data.type);
|
| uniform_data.push_back(data);
|
| }
|
| }
|
| @@ -757,41 +734,60 @@ bool Program::SetUniformLocationBinding(
|
|
|
| // Note: This is only valid to call right after a program has been linked
|
| // successfully.
|
| -void Program::GetCorrectedVariableInfo(
|
| - bool use_uniforms,
|
| - const std::string& name, std::string* corrected_name,
|
| - std::string* original_name,
|
| +void Program::GetCorrectedUniformData(
|
| + 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]";
|
| - for (int jj = 0; jj < 2; ++jj) {
|
| - std::string test_name(name + ((jj == 1) ? kArraySpec : ""));
|
| - for (int ii = 0; ii < kMaxAttachedShaders; ++ii) {
|
| - Shader* shader = attached_shaders_[ii].get();
|
| - if (shader) {
|
| - const Shader::VariableInfo* variable_info =
|
| - use_uniforms ? shader->GetUniformInfo(test_name) :
|
| - shader->GetAttribInfo(test_name);
|
| - // Note: There is an assuption here that if an attrib is defined in more
|
| - // than 1 attached shader their types and sizes match. Should we check
|
| - // for that case?
|
| - if (variable_info) {
|
| - *corrected_name = test_name;
|
| - *original_name = variable_info->name;
|
| - *type = variable_info->type;
|
| - *size = variable_info->size;
|
| - return;
|
| - }
|
| + DCHECK(corrected_name && original_name && size && type);
|
| + for (int ii = 0; ii < kMaxAttachedShaders; ++ii) {
|
| + Shader* shader = attached_shaders_[ii].get();
|
| + if (!shader)
|
| + continue;
|
| + const sh::ShaderVariable* info = NULL;
|
| + const sh::Uniform* uniform = shader->GetUniformInfo(name);
|
| + bool found = false;
|
| + if (uniform)
|
| + found = uniform->findInfoByMappedName(name, &info, original_name);
|
| + if (found) {
|
| + const std::string kArraySpec("[0]");
|
| + if (info->arraySize > 0 && !EndsWith(name, kArraySpec, true)) {
|
| + *corrected_name = name + kArraySpec;
|
| + *original_name += kArraySpec;
|
| + } else {
|
| + *corrected_name = name;
|
| }
|
| + *type = info->type;
|
| + *size = std::max(1u, info->arraySize);
|
| + return;
|
| }
|
| }
|
| + // TODO(zmo): this path should never be reached unless there is a serious
|
| + // bug in the driver or in ANGLE translator.
|
| *corrected_name = name;
|
| *original_name = name;
|
| }
|
|
|
| +void Program::GetVertexAttribData(
|
| + const std::string& name, std::string* original_name, GLenum* type) const {
|
| + DCHECK(original_name);
|
| + DCHECK(type);
|
| + Shader* shader = attached_shaders_[ShaderTypeToIndex(GL_VERTEX_SHADER)].get();
|
| + if (shader) {
|
| + // Vertex attributes can not be arrays or structs (GLSL ES 3.00.4, section
|
| + // 4.3.4, "Input Variables"), so the top level sh::Attribute returns the
|
| + // information we need.
|
| + const sh::Attribute* info = shader->GetAttribInfo(name);
|
| + if (info) {
|
| + *original_name = info->name;
|
| + *type = info->type;
|
| + return;
|
| + }
|
| + }
|
| + // TODO(zmo): this path should never be reached unless there is a serious
|
| + // bug in the driver or in ANGLE translator.
|
| + *original_name = name;
|
| +}
|
| +
|
| bool Program::AddUniformInfo(
|
| GLsizei size, GLenum type, GLint location, GLint fake_base_location,
|
| const std::string& name, const std::string& original_name,
|
| @@ -1014,23 +1010,20 @@ bool Program::DetectAttribLocationBindingConflicts() const {
|
| }
|
|
|
| bool Program::DetectUniformsMismatch(std::string* conflicting_name) const {
|
| - typedef std::map<std::string, UniformType> UniformMap;
|
| - UniformMap uniform_map;
|
| + typedef std::map<std::string, const sh::Uniform*> UniformPointerMap;
|
| + UniformPointerMap uniform_pointer_map;
|
| for (int ii = 0; ii < kMaxAttachedShaders; ++ii) {
|
| - const ShaderTranslator::VariableMap& shader_uniforms =
|
| - attached_shaders_[ii]->uniform_map();
|
| - for (ShaderTranslator::VariableMap::const_iterator iter =
|
| - shader_uniforms.begin();
|
| + const UniformMap& shader_uniforms = attached_shaders_[ii]->uniform_map();
|
| + for (UniformMap::const_iterator iter = shader_uniforms.begin();
|
| iter != shader_uniforms.end(); ++iter) {
|
| const std::string& name = iter->first;
|
| - UniformType type(iter->second);
|
| - UniformMap::iterator map_entry = uniform_map.find(name);
|
| - if (map_entry == uniform_map.end()) {
|
| - uniform_map[name] = type;
|
| + UniformPointerMap::iterator hit = uniform_pointer_map.find(name);
|
| + if (hit == uniform_pointer_map.end()) {
|
| + uniform_pointer_map[name] = &(iter->second);
|
| } else {
|
| - // If a uniform is already in the map, i.e., it has already been
|
| - // declared by other shader, then the type and precision must match.
|
| - if (map_entry->second == type)
|
| + // If a uniform is in the map, i.e., it has already been declared by
|
| + // another shader, then the type, precision, etc. must match.
|
| + if (hit->second->isSameUniformAtLinkTime(iter->second))
|
| continue;
|
| *conflicting_name = name;
|
| return true;
|
| @@ -1045,30 +1038,25 @@ bool Program::DetectVaryingsMismatch(std::string* conflicting_name) const {
|
| attached_shaders_[0]->shader_type() == GL_VERTEX_SHADER &&
|
| attached_shaders_[1].get() &&
|
| attached_shaders_[1]->shader_type() == GL_FRAGMENT_SHADER);
|
| - const ShaderTranslator::VariableMap* vertex_varyings =
|
| - &(attached_shaders_[0]->varying_map());
|
| - const ShaderTranslator::VariableMap* fragment_varyings =
|
| - &(attached_shaders_[1]->varying_map());
|
| + const VaryingMap* vertex_varyings = &(attached_shaders_[0]->varying_map());
|
| + const VaryingMap* fragment_varyings = &(attached_shaders_[1]->varying_map());
|
|
|
| - for (ShaderTranslator::VariableMap::const_iterator iter =
|
| - fragment_varyings->begin();
|
| + for (VaryingMap::const_iterator iter = fragment_varyings->begin();
|
| iter != fragment_varyings->end(); ++iter) {
|
| const std::string& name = iter->first;
|
| if (IsBuiltInVarying(name))
|
| continue;
|
|
|
| - ShaderTranslator::VariableMap::const_iterator hit =
|
| - vertex_varyings->find(name);
|
| + VaryingMap::const_iterator hit = vertex_varyings->find(name);
|
| if (hit == vertex_varyings->end()) {
|
| - if (iter->second.static_use) {
|
| + if (iter->second.staticUse) {
|
| *conflicting_name = name;
|
| return true;
|
| }
|
| continue;
|
| }
|
|
|
| - if (hit->second.type != iter->second.type ||
|
| - hit->second.size != iter->second.size) {
|
| + if (!hit->second.isSameVaryingAtLinkTime(iter->second)) {
|
| *conflicting_name = name;
|
| return true;
|
| }
|
| @@ -1082,14 +1070,14 @@ bool Program::DetectGlobalNameConflicts(std::string* conflicting_name) const {
|
| attached_shaders_[0]->shader_type() == GL_VERTEX_SHADER &&
|
| attached_shaders_[1].get() &&
|
| attached_shaders_[1]->shader_type() == GL_FRAGMENT_SHADER);
|
| - const ShaderTranslator::VariableMap* uniforms[2];
|
| + const UniformMap* uniforms[2];
|
| uniforms[0] = &(attached_shaders_[0]->uniform_map());
|
| uniforms[1] = &(attached_shaders_[1]->uniform_map());
|
| - const ShaderTranslator::VariableMap* attribs =
|
| + const AttributeMap* attribs =
|
| &(attached_shaders_[0]->attrib_map());
|
|
|
| - for (ShaderTranslator::VariableMap::const_iterator iter =
|
| - attribs->begin(); iter != attribs->end(); ++iter) {
|
| + for (AttributeMap::const_iterator iter = attribs->begin();
|
| + iter != attribs->end(); ++iter) {
|
| for (int ii = 0; ii < 2; ++ii) {
|
| if (uniforms[ii]->find(iter->first) != uniforms[ii]->end()) {
|
| *conflicting_name = iter->first;
|
| @@ -1106,30 +1094,27 @@ bool Program::CheckVaryingsPacking(
|
| attached_shaders_[0]->shader_type() == GL_VERTEX_SHADER &&
|
| attached_shaders_[1].get() &&
|
| attached_shaders_[1]->shader_type() == GL_FRAGMENT_SHADER);
|
| - const ShaderTranslator::VariableMap* vertex_varyings =
|
| - &(attached_shaders_[0]->varying_map());
|
| - const ShaderTranslator::VariableMap* fragment_varyings =
|
| - &(attached_shaders_[1]->varying_map());
|
| + const VaryingMap* vertex_varyings = &(attached_shaders_[0]->varying_map());
|
| + const VaryingMap* fragment_varyings = &(attached_shaders_[1]->varying_map());
|
|
|
| std::map<std::string, ShVariableInfo> combined_map;
|
|
|
| - for (ShaderTranslator::VariableMap::const_iterator iter =
|
| - fragment_varyings->begin();
|
| + for (VaryingMap::const_iterator iter = fragment_varyings->begin();
|
| iter != fragment_varyings->end(); ++iter) {
|
| - if (!iter->second.static_use && option == kCountOnlyStaticallyUsed)
|
| + if (!iter->second.staticUse && option == kCountOnlyStaticallyUsed)
|
| continue;
|
| if (!IsBuiltInVarying(iter->first)) {
|
| - ShaderTranslator::VariableMap::const_iterator vertex_iter =
|
| + VaryingMap::const_iterator vertex_iter =
|
| vertex_varyings->find(iter->first);
|
| if (vertex_iter == vertex_varyings->end() ||
|
| - (!vertex_iter->second.static_use &&
|
| + (!vertex_iter->second.staticUse &&
|
| option == kCountOnlyStaticallyUsed))
|
| continue;
|
| }
|
|
|
| ShVariableInfo var;
|
| var.type = static_cast<sh::GLenum>(iter->second.type);
|
| - var.size = iter->second.size;
|
| + var.size = std::max(1u, iter->second.arraySize);
|
| combined_map[iter->first] = var;
|
| }
|
|
|
|
|