Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(286)

Unified Diff: gpu/command_buffer/client/program_info_manager.cc

Issue 903273002: Update from https://crrev.com/315085 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: gpu/command_buffer/client/program_info_manager.cc
diff --git a/gpu/command_buffer/client/program_info_manager.cc b/gpu/command_buffer/client/program_info_manager.cc
index 71963721e523d307ca238045eb1599c89a7663d4..04121aa7346ba275391dc30102909c31d47cf304 100644
--- a/gpu/command_buffer/client/program_info_manager.cc
+++ b/gpu/command_buffer/client/program_info_manager.cc
@@ -44,11 +44,23 @@ ProgramInfoManager::Program::UniformInfo::UniformInfo(
ProgramInfoManager::Program::UniformInfo::~UniformInfo() {
}
+ProgramInfoManager::Program::UniformBlock::UniformBlock()
+ : binding(0),
+ data_size(0),
+ referenced_by_vertex_shader(false),
+ referenced_by_fragment_shader(false) {
+}
+
+ProgramInfoManager::Program::UniformBlock::~UniformBlock() {
+}
+
ProgramInfoManager::Program::Program()
- : cached_(false),
+ : cached_es2_(false),
max_attrib_name_length_(0),
max_uniform_name_length_(0),
- link_status_(false) {
+ link_status_(false),
+ cached_es3_uniform_blocks_(false),
+ active_uniform_block_max_name_length_(0) {
}
ProgramInfoManager::Program::~Program() {
@@ -78,6 +90,11 @@ ProgramInfoManager::Program::GetUniformInfo(GLint index) const {
&uniform_infos_[index] : NULL;
}
+const ProgramInfoManager::Program::UniformBlock*
+ProgramInfoManager::Program::GetUniformBlock(GLuint index) const {
+ return (index < uniform_blocks_.size()) ? &uniform_blocks_[index] : NULL;
+}
+
GLint ProgramInfoManager::Program::GetUniformLocation(
const std::string& name) const {
bool getting_array_location = false;
@@ -125,31 +142,45 @@ bool ProgramInfoManager::Program::GetProgramiv(
GLenum pname, GLint* params) {
switch (pname) {
case GL_LINK_STATUS:
- *params = link_status_;
+ *params = static_cast<GLint>(link_status_);
return true;
case GL_ACTIVE_ATTRIBUTES:
- *params = attrib_infos_.size();
+ *params = static_cast<GLint>(attrib_infos_.size());
return true;
case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
- *params = max_attrib_name_length_;
+ *params = static_cast<GLint>(max_attrib_name_length_);
return true;
case GL_ACTIVE_UNIFORMS:
- *params = uniform_infos_.size();
+ *params = static_cast<GLint>(uniform_infos_.size());
return true;
case GL_ACTIVE_UNIFORM_MAX_LENGTH:
- *params = max_uniform_name_length_;
+ *params = static_cast<GLint>(max_uniform_name_length_);
+ return true;
+ case GL_ACTIVE_UNIFORM_BLOCKS:
+ *params = static_cast<GLint>(uniform_blocks_.size());
+ return true;
+ case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
+ *params = static_cast<GLint>(active_uniform_block_max_name_length_);
return true;
default:
+ NOTREACHED();
break;
}
return false;
}
-void ProgramInfoManager::Program::Update(
- GLES2Implementation* gl,
- GLuint program,
- const std::vector<int8>& result) {
- if (cached_) {
+GLuint ProgramInfoManager::Program::GetUniformBlockIndex(
+ const std::string& name) const {
+ for (size_t ii = 0; ii < uniform_blocks_.size(); ++ii) {
+ if (uniform_blocks_[ii].name == name) {
+ return static_cast<GLuint>(ii);
+ }
+ }
+ return GL_INVALID_INDEX;
+}
+
+void ProgramInfoManager::Program::UpdateES2(const std::vector<int8>& result) {
+ if (cached_es2_) {
return;
}
if (result.empty()) {
@@ -200,12 +231,93 @@ void ProgramInfoManager::Program::Update(
++input;
}
DCHECK_EQ(header->num_attribs + header->num_uniforms,
- static_cast<uint32>(input - inputs));
- cached_ = true;
+ static_cast<uint32>(input - inputs));
+ cached_es2_ = true;
}
-bool ProgramInfoManager::Program::cached() const {
- return cached_;
+void ProgramInfoManager::Program::UpdateES3UniformBlocks(
+ const std::vector<int8>& result) {
+ if (cached_es3_uniform_blocks_) {
+ return;
+ }
+ if (result.empty()) {
+ // This should only happen on a lost context.
+ return;
+ }
+ uniform_blocks_.clear();
+ active_uniform_block_max_name_length_ = 0;
+
+ // |result| comes from GPU process. We consider it trusted data. Therefore,
+ // no need to check for overflows as the GPU side did the checks already.
+ uint32_t header_size = sizeof(UniformBlocksHeader);
+ DCHECK_GE(result.size(), header_size);
+ const UniformBlocksHeader* header = LocalGetAs<const UniformBlocksHeader*>(
+ result, 0, header_size);
+ DCHECK(header);
+ if (header->num_uniform_blocks == 0) {
+ DCHECK_EQ(result.size(), header_size);
+ // TODO(zmo): Here we can't tell if no uniform blocks are defined, or
+ // the previous link failed.
+ return;
+ }
+ uniform_blocks_.resize(header->num_uniform_blocks);
+
+ uint32_t entry_size = sizeof(UniformBlockInfo) * header->num_uniform_blocks;
+ DCHECK_GE(result.size(), header_size + entry_size);
+ uint32_t data_size = result.size() - header_size - entry_size;
+ DCHECK_LT(0u, data_size);
+ const UniformBlockInfo* entries = LocalGetAs<const UniformBlockInfo*>(
+ result, header_size, entry_size);
+ DCHECK(entries);
+ const char* data = LocalGetAs<const char*>(
+ result, header_size + entry_size, data_size);
+ DCHECK(data);
+
+ uint32_t size = 0;
+ for (uint32_t ii = 0; ii < header->num_uniform_blocks; ++ii) {
+ uniform_blocks_[ii].binding = static_cast<GLuint>(entries[ii].binding);
+ uniform_blocks_[ii].data_size = static_cast<GLuint>(entries[ii].data_size);
+ uniform_blocks_[ii].active_uniform_indices.resize(
+ entries[ii].active_uniforms);
+ uniform_blocks_[ii].referenced_by_vertex_shader = static_cast<GLboolean>(
+ entries[ii].referenced_by_vertex_shader);
+ uniform_blocks_[ii].referenced_by_fragment_shader = static_cast<GLboolean>(
+ entries[ii].referenced_by_fragment_shader);
+ // Uniform block names can't be empty strings.
+ DCHECK_LT(1u, entries[ii].name_length);
+ if (entries[ii].name_length > active_uniform_block_max_name_length_) {
+ active_uniform_block_max_name_length_ = entries[ii].name_length;
+ }
+ size += entries[ii].name_length;
+ DCHECK_GE(data_size, size);
+ uniform_blocks_[ii].name = std::string(data, entries[ii].name_length - 1);
+ data += entries[ii].name_length;
+ size += entries[ii].active_uniforms * sizeof(uint32_t);
+ DCHECK_GE(data_size, size);
+ const uint32_t* indices = reinterpret_cast<const uint32_t*>(data);
+ for (uint32_t uu = 0; uu < entries[ii].active_uniforms; ++uu) {
+ uniform_blocks_[ii].active_uniform_indices[uu] =
+ static_cast<GLuint>(indices[uu]);
+ }
+ indices += entries[ii].active_uniforms;
+ data = reinterpret_cast<const char*>(indices);
+ }
+ DCHECK_EQ(data_size, size);
+ cached_es3_uniform_blocks_ = true;
+}
+
+bool ProgramInfoManager::Program::IsCached(ProgramInfoType type) const {
+ switch (type) {
+ case kES2:
+ return cached_es2_;
+ case kES3UniformBlocks:
+ return cached_es3_uniform_blocks_;
+ case kNone:
+ return true;
+ default:
+ NOTREACHED();
+ return true;
+ }
}
@@ -216,29 +328,42 @@ ProgramInfoManager::~ProgramInfoManager() {
}
ProgramInfoManager::Program* ProgramInfoManager::GetProgramInfo(
- GLES2Implementation* gl, GLuint program) {
+ GLES2Implementation* gl, GLuint program, ProgramInfoType type) {
lock_.AssertAcquired();
ProgramInfoMap::iterator it = program_infos_.find(program);
if (it == program_infos_.end()) {
return NULL;
}
Program* info = &it->second;
- if (info->cached())
+ if (info->IsCached(type))
return info;
- std::vector<int8> result;
- {
- base::AutoUnlock unlock(lock_);
- // lock_ can't be held across IPC call or else it may deadlock in pepper.
- // http://crbug.com/418651
- gl->GetProgramInfoCHROMIUMHelper(program, &result);
- }
- it = program_infos_.find(program);
- if (it == program_infos_.end()) {
- return NULL;
+ std::vector<int8> result;
+ switch (type) {
+ case kES2:
+ {
+ base::AutoUnlock unlock(lock_);
+ // lock_ can't be held across IPC call or else it may deadlock in
+ // pepper. http://crbug.com/418651
+ gl->GetProgramInfoCHROMIUMHelper(program, &result);
+ }
+ info->UpdateES2(result);
+ break;
+ case kES3UniformBlocks:
+ {
+ base::AutoUnlock unlock(lock_);
+ // lock_ can't be held across IPC call or else it may deadlock in
+ // pepper. http://crbug.com/418651
+
+ // TODO(zmo): Uncomment the below line once GetUniformBlocksCHROMIUM
+ // command is implemented.
+ // gl->GetUniformBlocksCHROMIUMHeler(program, &result);
+ }
+ info->UpdateES3UniformBlocks(result);
+ default:
+ NOTREACHED();
+ return NULL;
}
- info = &it->second;
- info->Update(gl, program, result);
return info;
}
@@ -259,7 +384,23 @@ void ProgramInfoManager::DeleteInfo(GLuint program) {
bool ProgramInfoManager::GetProgramiv(
GLES2Implementation* gl, GLuint program, GLenum pname, GLint* params) {
base::AutoLock auto_lock(lock_);
- Program* info = GetProgramInfo(gl, program);
+ ProgramInfoType type = kNone;
+ switch (pname) {
+ case GL_ACTIVE_ATTRIBUTES:
+ case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
+ case GL_ACTIVE_UNIFORMS:
+ case GL_ACTIVE_UNIFORM_MAX_LENGTH:
+ case GL_LINK_STATUS:
+ type = kES2;
+ break;
+ case GL_ACTIVE_UNIFORM_BLOCKS:
+ case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
+ type = kES3UniformBlocks;
+ break;
+ default:
+ return false;
+ }
+ Program* info = GetProgramInfo(gl, program, type);
if (!info) {
return false;
}
@@ -270,7 +411,7 @@ GLint ProgramInfoManager::GetAttribLocation(
GLES2Implementation* gl, GLuint program, const char* name) {
{
base::AutoLock auto_lock(lock_);
- Program* info = GetProgramInfo(gl, program);
+ Program* info = GetProgramInfo(gl, program, kES2);
if (info) {
return info->GetAttribLocation(name);
}
@@ -282,7 +423,7 @@ GLint ProgramInfoManager::GetUniformLocation(
GLES2Implementation* gl, GLuint program, const char* name) {
{
base::AutoLock auto_lock(lock_);
- Program* info = GetProgramInfo(gl, program);
+ Program* info = GetProgramInfo(gl, program, kES2);
if (info) {
return info->GetUniformLocation(name);
}
@@ -296,7 +437,7 @@ GLint ProgramInfoManager::GetFragDataLocation(
// fetched altogether from the service side. See crbug.com/452104.
{
base::AutoLock auto_lock(lock_);
- Program* info = GetProgramInfo(gl, program);
+ Program* info = GetProgramInfo(gl, program, kNone);
if (info) {
GLint possible_loc = info->GetFragDataLocation(name);
if (possible_loc != -1)
@@ -306,7 +447,7 @@ GLint ProgramInfoManager::GetFragDataLocation(
GLint loc = gl->GetFragDataLocationHelper(program, name);
if (loc != -1) {
base::AutoLock auto_lock(lock_);
- Program* info = GetProgramInfo(gl, program);
+ Program* info = GetProgramInfo(gl, program, kNone);
if (info) {
info->CacheFragDataLocation(name, loc);
}
@@ -320,7 +461,7 @@ bool ProgramInfoManager::GetActiveAttrib(
GLint* size, GLenum* type, char* name) {
{
base::AutoLock auto_lock(lock_);
- Program* info = GetProgramInfo(gl, program);
+ Program* info = GetProgramInfo(gl, program, kES2);
if (info) {
const Program::VertexAttrib* attrib_info = info->GetAttribInfo(index);
if (attrib_info) {
@@ -356,7 +497,7 @@ bool ProgramInfoManager::GetActiveUniform(
GLint* size, GLenum* type, char* name) {
{
base::AutoLock auto_lock(lock_);
- Program* info = GetProgramInfo(gl, program);
+ Program* info = GetProgramInfo(gl, program, kES2);
if (info) {
const Program::UniformInfo* uniform_info = info->GetUniformInfo(index);
if (uniform_info) {
@@ -386,6 +527,119 @@ bool ProgramInfoManager::GetActiveUniform(
program, index, bufsize, length, size, type, name);
}
+GLuint ProgramInfoManager::GetUniformBlockIndex(
+ GLES2Implementation* gl, GLuint program, const char* name) {
+ {
+ base::AutoLock auto_lock(lock_);
+ Program* info = GetProgramInfo(gl, program, kES3UniformBlocks);
+ if (info) {
+ return info->GetUniformBlockIndex(name);
+ }
+ }
+ return gl->GetUniformBlockIndexHelper(program, name);
+}
+
+bool ProgramInfoManager::GetActiveUniformBlockName(
+ GLES2Implementation* gl, GLuint program, GLuint index,
+ GLsizei buf_size, GLsizei* length, char* name) {
+ DCHECK_LE(0, buf_size);
+ if (!name) {
+ buf_size = 0;
+ }
+ {
+ base::AutoLock auto_lock(lock_);
+ Program* info = GetProgramInfo(gl, program, kES3UniformBlocks);
+ if (info) {
+ const Program::UniformBlock* uniform_block = info->GetUniformBlock(index);
+ if (uniform_block) {
+ if (buf_size == 0) {
+ if (length) {
+ *length = 0;
+ }
+ } else if (length || name) {
+ GLsizei max_size = std::min(
+ buf_size - 1, static_cast<GLsizei>(uniform_block->name.size()));
+ if (length) {
+ *length = max_size;
+ }
+ if (name) {
+ memcpy(name, uniform_block->name.data(), max_size);
+ name[max_size] = '\0';
+ }
+ }
+ return true;
+ }
+ }
+ }
+ return gl->GetActiveUniformBlockNameHelper(
+ program, index, buf_size, length, name);
+}
+
+bool ProgramInfoManager::GetActiveUniformBlockiv(
+ GLES2Implementation* gl, GLuint program, GLuint index,
+ GLenum pname, GLint* params) {
+ {
+ base::AutoLock auto_lock(lock_);
+ Program* info = GetProgramInfo(gl, program, kES3UniformBlocks);
+ if (info) {
+ const Program::UniformBlock* uniform_block = info->GetUniformBlock(index);
+ bool valid_pname;
+ switch (pname) {
+ case GL_UNIFORM_BLOCK_BINDING:
+ case GL_UNIFORM_BLOCK_DATA_SIZE:
+ case GL_UNIFORM_BLOCK_NAME_LENGTH:
+ case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
+ case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
+ case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
+ case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
+ valid_pname = true;
+ break;
+ default:
+ valid_pname = false;
+ break;
+ }
+ if (uniform_block && valid_pname && params) {
+ switch (pname) {
+ case GL_UNIFORM_BLOCK_BINDING:
+ *params = static_cast<GLint>(uniform_block->binding);
+ break;
+ case GL_UNIFORM_BLOCK_DATA_SIZE:
+ *params = static_cast<GLint>(uniform_block->data_size);
+ break;
+ case GL_UNIFORM_BLOCK_NAME_LENGTH:
+ *params = static_cast<GLint>(uniform_block->name.size()) + 1;
+ break;
+ case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
+ *params = static_cast<GLint>(
+ uniform_block->active_uniform_indices.size());
+ break;
+ case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
+ for (size_t ii = 0;
+ ii < uniform_block->active_uniform_indices.size(); ++ii) {
+ params[ii] = static_cast<GLint>(
+ uniform_block->active_uniform_indices[ii]);
+ }
+ break;
+ case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
+ *params = static_cast<GLint>(
+ uniform_block->referenced_by_vertex_shader);
+ break;
+ case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
+ *params = static_cast<GLint>(
+ uniform_block->referenced_by_fragment_shader);
+ break;
+ default:
+ NOTREACHED();
+ }
+ return true;
+ }
+ }
+ }
+ return false;
+ // TODO(zmo): return gl->GetActiveUniformBlockivHelper(
+ // program, index, pname, params);
+}
+
} // namespace gles2
} // namespace gpu
« no previous file with comments | « gpu/command_buffer/client/program_info_manager.h ('k') | gpu/command_buffer/client/program_info_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698