diff options
author | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-25 03:20:50 +0000 |
---|---|---|
committer | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-25 03:20:50 +0000 |
commit | 3916c97e1bb1ef3fecfdcaf9d80f239016756c06 (patch) | |
tree | 5c756aa2feec17d4a5609bcf2a16a06a12b828e8 /gpu/command_buffer/service/program_manager.cc | |
parent | 84aebedeaa91c3fadf523260c12afa136420c7d3 (diff) | |
download | chromium_src-3916c97e1bb1ef3fecfdcaf9d80f239016756c06.zip chromium_src-3916c97e1bb1ef3fecfdcaf9d80f239016756c06.tar.gz chromium_src-3916c97e1bb1ef3fecfdcaf9d80f239016756c06.tar.bz2 |
Reorangizing the GLES2 code to handle shared
resources and non-renderable texture situations.
I haven't written enough unit tests for this
but the CL is already too big.
TEST=none
BUG=none
Review URL: http://codereview.chromium.org/646070
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39984 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu/command_buffer/service/program_manager.cc')
-rw-r--r-- | gpu/command_buffer/service/program_manager.cc | 94 |
1 files changed, 69 insertions, 25 deletions
diff --git a/gpu/command_buffer/service/program_manager.cc b/gpu/command_buffer/service/program_manager.cc index ade12e2..b53938f 100644 --- a/gpu/command_buffer/service/program_manager.cc +++ b/gpu/command_buffer/service/program_manager.cc @@ -7,6 +7,7 @@ #include "base/logging.h" #include "base/scoped_ptr.h" #include "base/string_util.h" +#include "gpu/command_buffer/service/gles2_cmd_decoder.h" namespace gpu { namespace gles2 { @@ -20,9 +21,9 @@ bool ProgramManager::IsInvalidPrefix(const char* name, size_t length) { void ProgramManager::ProgramInfo::Update() { GLint num_attribs = 0; GLint max_len = 0; - glGetProgramiv(program_, GL_ACTIVE_ATTRIBUTES, &num_attribs); - SetNumAttributes(num_attribs); - glGetProgramiv(program_, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_len); + glGetProgramiv(program_id_, GL_ACTIVE_ATTRIBUTES, &num_attribs); + attrib_infos_.resize(num_attribs); + glGetProgramiv(program_id_, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_len); // TODO(gman): Should we check for error? scoped_array<char> name_buffer(new char[max_len]); for (GLint ii = 0; ii < num_attribs; ++ii) { @@ -30,27 +31,49 @@ void ProgramManager::ProgramInfo::Update() { GLsizei size; GLenum type; glGetActiveAttrib( - program_, ii, max_len, &length, &size, &type, name_buffer.get()); + program_id_, ii, max_len, &length, &size, &type, name_buffer.get()); // TODO(gman): Should we check for error? GLint location = IsInvalidPrefix(name_buffer.get(), length) ? -1 : - glGetAttribLocation(program_, name_buffer.get()); + glGetAttribLocation(program_id_, name_buffer.get()); SetAttributeInfo(ii, size, type, location, name_buffer.get()); } GLint num_uniforms; - glGetProgramiv(program_, GL_ACTIVE_UNIFORMS, &num_uniforms); - SetNumUniforms(num_uniforms); - glGetProgramiv(program_, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_len); + glGetProgramiv(program_id_, GL_ACTIVE_UNIFORMS, &num_uniforms); + uniform_infos_.resize(num_uniforms); + sampler_indices_.clear(); + glGetProgramiv(program_id_, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_len); name_buffer.reset(new char[max_len]); + GLint max_location = -1; for (GLint ii = 0; ii < num_uniforms; ++ii) { GLsizei length; GLsizei size; GLenum type; glGetActiveUniform( - program_, ii, max_len, &length, &size, &type, name_buffer.get()); + program_id_, ii, max_len, &length, &size, &type, name_buffer.get()); // TODO(gman): Should we check for error? GLint location = IsInvalidPrefix(name_buffer.get(), length) ? -1 : - glGetUniformLocation(program_, name_buffer.get()); + glGetUniformLocation(program_id_, name_buffer.get()); SetUniformInfo(ii, size, type, location, name_buffer.get()); + const UniformInfo& info = uniform_infos_[ii]; + for (size_t jj = 0; jj < info.element_locations.size(); ++jj) { + if (info.element_locations[jj] > max_location) { + max_location = info.element_locations[jj]; + } + } + if (info.IsSampler()) { + sampler_indices_.push_back(ii); + } + } + // Create location to index map. + location_to_index_map_.resize(max_location + 1); + for (GLint ii = 0; ii <= max_location; ++ii) { + location_to_index_map_[ii] = -1; + } + for (GLint ii = 0; ii < num_uniforms; ++ii) { + const UniformInfo& info = uniform_infos_[ii]; + for (size_t jj = 0; jj < info.element_locations.size(); ++jj) { + location_to_index_map_[info.element_locations[jj]] = ii; + } } } @@ -96,13 +119,12 @@ GLint ProgramManager::ProgramInfo::GetAttribLocation( bool ProgramManager::ProgramInfo::GetUniformTypeByLocation( GLint location, GLenum* type) const { - for (GLuint ii = 0; ii < uniform_infos_.size(); ++ii) { - const UniformInfo& info = uniform_infos_[ii]; - for (GLsizei jj = 0; jj < info.size; ++jj) { - if (info.element_locations[jj] == location) { - *type = info.type; - return true; - } + if (location >= 0 && + static_cast<size_t>(location) < location_to_index_map_.size()) { + GLint index = location_to_index_map_[location]; + if (index >= 0) { + *type = uniform_infos_[index].type; + return true; } } return false; @@ -118,6 +140,10 @@ void ProgramManager::ProgramInfo::SetUniformInfo( info.name = name; info.element_locations.resize(size); info.element_locations[0] = location; + size_t num_texture_units = info.IsSampler() ? size : 0u; + 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. @@ -125,26 +151,44 @@ void ProgramManager::ProgramInfo::SetUniformInfo( for (GLsizei ii = 1; ii < info.size; ++ii) { std::string element_name(name + "[" + IntToString(ii) + "]"); info.element_locations[ii] = - glGetUniformLocation(program_, element_name.c_str()); + glGetUniformLocation(program_id_, element_name.c_str()); + } + } +} + +bool ProgramManager::ProgramInfo::SetSamplers( + GLint location, GLsizei count, const GLint* value) { + if (location >= 0 && + static_cast<size_t>(location) < location_to_index_map_.size()) { + GLint index = location_to_index_map_[location]; + if (index >= 0) { + UniformInfo& info = uniform_infos_[index]; + if (info.IsSampler() && count <= info.size) { + std::copy(value, value + count, info.texture_units.begin()); + return true; + } } } + return false; } -void ProgramManager::CreateProgramInfo(GLuint program) { +void ProgramManager::CreateProgramInfo(GLuint program_id) { std::pair<ProgramInfoMap::iterator, bool> result = program_infos_.insert( - std::make_pair(program, ProgramInfo(program))); + std::make_pair(program_id, + ProgramInfo::Ref(new ProgramInfo(program_id)))); DCHECK(result.second); } -ProgramManager::ProgramInfo* ProgramManager::GetProgramInfo(GLuint program) { - ProgramInfoMap::iterator it = program_infos_.find(program); - return it != program_infos_.end() ? &it->second : NULL; +ProgramManager::ProgramInfo* ProgramManager::GetProgramInfo(GLuint program_id) { + ProgramInfoMap::iterator it = program_infos_.find(program_id); + return it != program_infos_.end() ? it->second : NULL; } -void ProgramManager::RemoveProgramInfo(GLuint program) { - ProgramInfoMap::iterator it = program_infos_.find(program); +void ProgramManager::RemoveProgramInfo(GLuint program_id) { + ProgramInfoMap::iterator it = program_infos_.find(program_id); if (it != program_infos_.end()) { + it->second->MarkAsDeleted(); program_infos_.erase(it); } } |