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-02-25 03:20:50 +0000
committergman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-25 03:20:50 +0000
commit3916c97e1bb1ef3fecfdcaf9d80f239016756c06 (patch)
tree5c756aa2feec17d4a5609bcf2a16a06a12b828e8 /gpu/command_buffer/service/program_manager.cc
parent84aebedeaa91c3fadf523260c12afa136420c7d3 (diff)
downloadchromium_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.cc94
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);
}
}