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

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

Issue 935333002: Update from https://crrev.com/316786 (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 04121aa7346ba275391dc30102909c31d47cf304..779d914ac4c441a6fc40d0a00a958281a7df7c83 100644
--- a/gpu/command_buffer/client/program_info_manager.cc
+++ b/gpu/command_buffer/client/program_info_manager.cc
@@ -44,6 +44,17 @@ ProgramInfoManager::Program::UniformInfo::UniformInfo(
ProgramInfoManager::Program::UniformInfo::~UniformInfo() {
}
+ProgramInfoManager::Program::UniformES3::UniformES3()
+ : block_index(-1),
+ offset(-1),
+ array_stride(-1),
+ matrix_stride(-1),
+ is_row_major(0) {
+}
+
+ProgramInfoManager::Program::UniformES3::~UniformES3() {
+}
+
ProgramInfoManager::Program::UniformBlock::UniformBlock()
: binding(0),
data_size(0),
@@ -54,13 +65,26 @@ ProgramInfoManager::Program::UniformBlock::UniformBlock()
ProgramInfoManager::Program::UniformBlock::~UniformBlock() {
}
+ProgramInfoManager::Program::TransformFeedbackVarying::
+TransformFeedbackVarying()
+ : size(0),
+ type(0) {
+}
+
+ProgramInfoManager::Program::TransformFeedbackVarying::
+~TransformFeedbackVarying() {
+}
+
ProgramInfoManager::Program::Program()
: cached_es2_(false),
max_attrib_name_length_(0),
max_uniform_name_length_(0),
link_status_(false),
cached_es3_uniform_blocks_(false),
- active_uniform_block_max_name_length_(0) {
+ active_uniform_block_max_name_length_(0),
+ cached_es3_transform_feedback_varyings_(false),
+ transform_feedback_varying_max_length_(0),
+ cached_es3_uniformsiv_(false) {
}
ProgramInfoManager::Program::~Program() {
@@ -124,6 +148,22 @@ GLint ProgramInfoManager::Program::GetUniformLocation(
return -1;
}
+GLuint ProgramInfoManager::Program::GetUniformIndex(
+ const std::string& name) const {
+ // TODO(zmo): Maybe build a hashed_map for faster lookup.
+ for (GLuint ii = 0; ii < uniform_infos_.size(); ++ii) {
+ const UniformInfo& info = uniform_infos_[ii];
+ // For an array, either "var" or "var[0]" is considered as a match.
+ // See "OpenGL ES 3.0.0, Section 2.11.3 Program Objects."
+ if (info.name == name ||
+ (info.is_array &&
+ info.name.compare(0, info.name.size() - 3, name) == 0)) {
+ return ii;
+ }
+ }
+ return GL_INVALID_INDEX;
+}
+
GLint ProgramInfoManager::Program::GetFragDataLocation(
const std::string& name) const {
base::hash_map<std::string, GLint>::const_iterator iter =
@@ -162,6 +202,12 @@ bool ProgramInfoManager::Program::GetProgramiv(
case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
*params = static_cast<GLint>(active_uniform_block_max_name_length_);
return true;
+ case GL_TRANSFORM_FEEDBACK_VARYINGS:
+ *params = static_cast<GLint>(transform_feedback_varyings_.size());
+ return true;
+ case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
+ *params = static_cast<GLint>(transform_feedback_varying_max_length_);
+ return true;
default:
NOTREACHED();
break;
@@ -179,6 +225,98 @@ GLuint ProgramInfoManager::Program::GetUniformBlockIndex(
return GL_INVALID_INDEX;
}
+void ProgramInfoManager::Program::UniformBlockBinding(
+ GLuint index , GLuint binding) {
+ if (index < uniform_blocks_.size()) {
+ uniform_blocks_[index].binding = binding;
+ }
+}
+
+const ProgramInfoManager::Program::TransformFeedbackVarying*
+ProgramInfoManager::Program::GetTransformFeedbackVarying(GLuint index) const {
+ return (index < transform_feedback_varyings_.size()) ?
+ &transform_feedback_varyings_[index] : NULL;
+}
+
+bool ProgramInfoManager::Program::GetUniformsiv(
+ GLsizei count, const GLuint* indices, GLenum pname, GLint* params) {
+ if (count == 0) {
+ // At this point, pname has already been validated.
+ return true;
+ }
+ DCHECK(count > 0 && indices);
+ size_t num_uniforms = uniform_infos_.size();
+ if (num_uniforms == 0) {
+ num_uniforms = uniforms_es3_.size();
+ }
+ if (static_cast<size_t>(count) > num_uniforms) {
+ return false;
+ }
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ if (indices[ii] >= num_uniforms) {
+ return false;
+ }
+ }
+ if (!params) {
+ return true;
+ }
+ switch (pname) {
+ case GL_UNIFORM_SIZE:
+ DCHECK_EQ(num_uniforms, uniform_infos_.size());
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ params[ii] = static_cast<GLint>(uniform_infos_[indices[ii]].size);
+ }
+ return true;
+ case GL_UNIFORM_TYPE:
+ DCHECK_EQ(num_uniforms, uniform_infos_.size());
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ params[ii] = static_cast<GLint>(uniform_infos_[indices[ii]].type);
+ }
+ return true;
+ case GL_UNIFORM_NAME_LENGTH:
+ DCHECK_EQ(num_uniforms, uniform_infos_.size());
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ params[ii] = static_cast<GLint>(
+ uniform_infos_[indices[ii]].name.length() + 1);
+ }
+ return true;
+ case GL_UNIFORM_BLOCK_INDEX:
+ DCHECK_EQ(num_uniforms, uniforms_es3_.size());
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ params[ii] = uniforms_es3_[indices[ii]].block_index;
+ }
+ return true;
+ case GL_UNIFORM_OFFSET:
+ DCHECK_EQ(num_uniforms, uniforms_es3_.size());
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ params[ii] = uniforms_es3_[indices[ii]].offset;
+ }
+ return true;
+ case GL_UNIFORM_ARRAY_STRIDE:
+ DCHECK_EQ(num_uniforms, uniforms_es3_.size());
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ params[ii] = uniforms_es3_[indices[ii]].array_stride;
+ }
+ return true;
+ case GL_UNIFORM_MATRIX_STRIDE:
+ DCHECK_EQ(num_uniforms, uniforms_es3_.size());
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ params[ii] = uniforms_es3_[indices[ii]].matrix_stride;
+ }
+ return true;
+ case GL_UNIFORM_IS_ROW_MAJOR:
+ DCHECK_EQ(num_uniforms, uniforms_es3_.size());
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ params[ii] = uniforms_es3_[indices[ii]].is_row_major;
+ }
+ return true;
+ default:
+ NOTREACHED();
+ break;
+ }
+ return false;
+}
+
void ProgramInfoManager::Program::UpdateES2(const std::vector<int8>& result) {
if (cached_es2_) {
return;
@@ -306,12 +444,119 @@ void ProgramInfoManager::Program::UpdateES3UniformBlocks(
cached_es3_uniform_blocks_ = true;
}
+void ProgramInfoManager::Program::UpdateES3Uniformsiv(
+ const std::vector<int8>& result) {
+ if (cached_es3_uniformsiv_) {
+ return;
+ }
+ if (result.empty()) {
+ // This should only happen on a lost context.
+ return;
+ }
+ uniforms_es3_.clear();
+
+ // |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(UniformsES3Header);
+ DCHECK_GE(result.size(), header_size);
+ const UniformsES3Header* header = LocalGetAs<const UniformsES3Header*>(
+ result, 0, header_size);
+ DCHECK(header);
+ if (header->num_uniforms == 0) {
+ DCHECK_EQ(result.size(), header_size);
+ // TODO(zmo): Here we can't tell if no uniforms are defined, or
+ // the previous link failed.
+ return;
+ }
+ uniforms_es3_.resize(header->num_uniforms);
+
+ uint32_t entry_size = sizeof(UniformES3Info) * header->num_uniforms;
+ DCHECK_EQ(result.size(), header_size + entry_size);
+ const UniformES3Info* entries = LocalGetAs<const UniformES3Info*>(
+ result, header_size, entry_size);
+ DCHECK(entries);
+
+ for (uint32_t ii = 0; ii < header->num_uniforms; ++ii) {
+ uniforms_es3_[ii].block_index = entries[ii].block_index;
+ uniforms_es3_[ii].offset = entries[ii].offset;
+ uniforms_es3_[ii].array_stride = entries[ii].array_stride;
+ uniforms_es3_[ii].matrix_stride = entries[ii].matrix_stride;
+ uniforms_es3_[ii].is_row_major = entries[ii].is_row_major;
+ }
+ cached_es3_uniformsiv_ = true;
+}
+
+void ProgramInfoManager::Program::UpdateES3TransformFeedbackVaryings(
+ const std::vector<int8>& result) {
+ if (cached_es3_transform_feedback_varyings_) {
+ return;
+ }
+ if (result.empty()) {
+ // This should only happen on a lost context.
+ return;
+ }
+ transform_feedback_varyings_.clear();
+ transform_feedback_varying_max_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(TransformFeedbackVaryingsHeader);
+ DCHECK_GE(result.size(), header_size);
+ const TransformFeedbackVaryingsHeader* header =
+ LocalGetAs<const TransformFeedbackVaryingsHeader*>(
+ result, 0, header_size);
+ DCHECK(header);
+ if (header->num_transform_feedback_varyings == 0) {
+ DCHECK_EQ(result.size(), header_size);
+ // TODO(zmo): Here we can't tell if no TransformFeedback varyings are
+ // defined, or the previous link failed.
+ return;
+ }
+ transform_feedback_varyings_.resize(header->num_transform_feedback_varyings);
+
+ uint32_t entry_size = sizeof(TransformFeedbackVaryingInfo) *
+ header->num_transform_feedback_varyings;
+ DCHECK_GE(result.size(), header_size + entry_size);
+ uint32_t data_size = result.size() - header_size - entry_size;
+ DCHECK_LT(0u, data_size);
+ const TransformFeedbackVaryingInfo* entries =
+ LocalGetAs<const TransformFeedbackVaryingInfo*>(
+ 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_transform_feedback_varyings; ++ii) {
+ transform_feedback_varyings_[ii].size =
+ static_cast<GLsizei>(entries[ii].size);
+ transform_feedback_varyings_[ii].type =
+ static_cast<GLenum>(entries[ii].type);
+ DCHECK_LE(1u, entries[ii].name_length);
+ if (entries[ii].name_length > transform_feedback_varying_max_length_) {
+ transform_feedback_varying_max_length_ = entries[ii].name_length;
+ }
+ size += entries[ii].name_length;
+ DCHECK_GE(data_size, size);
+ transform_feedback_varyings_[ii].name =
+ std::string(data, entries[ii].name_length - 1);
+ data += entries[ii].name_length;
+ }
+ DCHECK_EQ(data_size, size);
+ cached_es3_transform_feedback_varyings_ = true;
+}
+
bool ProgramInfoManager::Program::IsCached(ProgramInfoType type) const {
switch (type) {
case kES2:
return cached_es2_;
case kES3UniformBlocks:
return cached_es3_uniform_blocks_;
+ case kES3TransformFeedbackVaryings:
+ return cached_es3_transform_feedback_varyings_;
+ case kES3Uniformsiv:
+ return cached_es3_uniformsiv_;
case kNone:
return true;
default:
@@ -354,12 +599,26 @@ ProgramInfoManager::Program* ProgramInfoManager::GetProgramInfo(
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);
+ gl->GetUniformBlocksCHROMIUMHelper(program, &result);
}
info->UpdateES3UniformBlocks(result);
+ break;
+ case kES3TransformFeedbackVaryings:
+ {
+ base::AutoUnlock unlock(lock_);
+ // lock_ can't be held across IPC call or else it may deadlock in
+ // pepper. http://crbug.com/418651
+ gl->GetTransformFeedbackVaryingsCHROMIUMHelper(program, &result);
+ }
+ info->UpdateES3TransformFeedbackVaryings(result);
+ case kES3Uniformsiv:
+ {
+ base::AutoUnlock unlock(lock_);
+ // lock_ can't be held across IPC call or else it may deadlock in
+ // pepper. http://crbug.com/418651
+ gl->GetUniformsES3CHROMIUMHelper(program, &result);
+ }
+ info->UpdateES3Uniformsiv(result);
default:
NOTREACHED();
return NULL;
@@ -397,6 +656,10 @@ bool ProgramInfoManager::GetProgramiv(
case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
type = kES3UniformBlocks;
break;
+ case GL_TRANSFORM_FEEDBACK_VARYINGS:
+ case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
+ type = kES3TransformFeedbackVaryings;
+ break;
default:
return false;
}
@@ -407,6 +670,34 @@ bool ProgramInfoManager::GetProgramiv(
return info->GetProgramiv(pname, params);
}
+bool ProgramInfoManager::GetActiveUniformsiv(
+ GLES2Implementation* gl, GLuint program, GLsizei count,
+ const GLuint* indices, GLenum pname, GLint* params) {
+ base::AutoLock auto_lock(lock_);
+ ProgramInfoType type = kNone;
+ switch (pname) {
+ case GL_UNIFORM_SIZE:
+ case GL_UNIFORM_TYPE:
+ case GL_UNIFORM_NAME_LENGTH:
+ type = kES2;
+ break;
+ case GL_UNIFORM_BLOCK_INDEX:
+ case GL_UNIFORM_OFFSET:
+ case GL_UNIFORM_ARRAY_STRIDE:
+ case GL_UNIFORM_MATRIX_STRIDE:
+ case GL_UNIFORM_IS_ROW_MAJOR:
+ type = kES3Uniformsiv;
+ break;
+ default:
+ return false;
+ }
+ Program* info = GetProgramInfo(gl, program, type);
+ if (info) {
+ return info->GetUniformsiv(count, indices, pname, params);
+ }
+ return gl->GetActiveUniformsivHelper(program, count, indices, pname, params);
+}
+
GLint ProgramInfoManager::GetAttribLocation(
GLES2Implementation* gl, GLuint program, const char* name) {
{
@@ -635,9 +926,73 @@ bool ProgramInfoManager::GetActiveUniformBlockiv(
}
}
}
- return false;
- // TODO(zmo): return gl->GetActiveUniformBlockivHelper(
- // program, index, pname, params);
+ return gl->GetActiveUniformBlockivHelper(program, index, pname, params);
+}
+
+void ProgramInfoManager::UniformBlockBinding(
+ GLES2Implementation* gl, GLuint program, GLuint index, GLuint binding) {
+ GLuint max_bindings =
+ static_cast<GLuint>(gl->capabilities().max_uniform_buffer_bindings);
+ if (binding < max_bindings) {
+ base::AutoLock auto_lock(lock_);
+ // If UniformBlock info haven't been cached yet, skip updating the binding.
+ Program* info = GetProgramInfo(gl, program, kNone);
+ if (info) {
+ info->UniformBlockBinding(index, binding);
+ }
+ }
+}
+
+bool ProgramInfoManager::GetTransformFeedbackVarying(
+ GLES2Implementation* gl, GLuint program, GLuint index, GLsizei bufsize,
+ GLsizei* length, GLsizei* size, GLenum* type, char* name) {
+ {
+ base::AutoLock auto_lock(lock_);
+ Program* info = GetProgramInfo(gl, program, kES3TransformFeedbackVaryings);
+ if (info) {
+ const Program::TransformFeedbackVarying* varying =
+ info->GetTransformFeedbackVarying(index);
+ if (varying) {
+ if (size) {
+ *size = varying->size;
+ }
+ if (type) {
+ *type = varying->type;
+ }
+ if (length || name) {
+ GLsizei max_size = std::min(
+ bufsize - 1, static_cast<GLsizei>(varying->name.size()));
+ if (length) {
+ *length = static_cast<GLsizei>(max_size);
+ }
+ if (name && bufsize > 0) {
+ memcpy(name, varying->name.c_str(), max_size);
+ name[max_size] = '\0';
+ }
+ }
+ return true;
+ }
+ }
+ }
+ return gl->GetTransformFeedbackVaryingHelper(
+ program, index, bufsize, length, size, type, name);
+}
+
+bool ProgramInfoManager::GetUniformIndices(GLES2Implementation* gl,
+ GLuint program, GLsizei count, const char* const* names, GLuint* indices) {
+ {
+ base::AutoLock auto_lock(lock_);
+ Program* info = GetProgramInfo(gl, program, kES2);
+ if (info) {
+ DCHECK_LT(0, count);
+ DCHECK(names && indices);
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ indices[ii] = info->GetUniformIndex(names[ii]);
+ }
+ return true;
+ }
+ }
+ return gl->GetUniformIndicesHelper(program, count, names, indices);
}
} // namespace gles2
« 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