| 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 51b0d6e0c551a365d64b2f38c7486c9a0f107cf7..aef7e44976e7f70709ec78c1ca5e62e28d7f3b87 100644
|
| --- a/gpu/command_buffer/service/program_manager.cc
|
| +++ b/gpu/command_buffer/service/program_manager.cc
|
| @@ -1529,6 +1529,80 @@ bool Program::GetTransformFeedbackVaryings(
|
| return true;
|
| }
|
|
|
| +bool Program::GetUniformsES3(CommonDecoder::Bucket* bucket) const {
|
| + // The data is packed into the bucket in the following order
|
| + // 1) header
|
| + // 2) N entries of UniformES3Info
|
| + //
|
| + // We query all the data directly through GL calls, assuming they are
|
| + // cheap through MANGLE.
|
| +
|
| + DCHECK(bucket);
|
| + GLuint program = service_id();
|
| +
|
| + uint32_t header_size = sizeof(UniformsES3Header);
|
| + bucket->SetSize(header_size); // In case we fail.
|
| +
|
| + GLsizei count = 0;
|
| + GLint param = GL_FALSE;
|
| + // We assume program is a valid program service id.
|
| + glGetProgramiv(program, GL_LINK_STATUS, ¶m);
|
| + if (param == GL_TRUE) {
|
| + param = 0;
|
| + glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &count);
|
| + }
|
| + if (count == 0) {
|
| + return true;
|
| + }
|
| +
|
| + base::CheckedNumeric<uint32_t> size = sizeof(UniformES3Info);
|
| + size *= count;
|
| + uint32_t entry_size = size.ValueOrDefault(0);
|
| + size += header_size;
|
| + if (!size.IsValid())
|
| + return false;
|
| + uint32_t total_size = size.ValueOrDefault(0);
|
| + bucket->SetSize(total_size);
|
| + UniformsES3Header* header =
|
| + bucket->GetDataAs<UniformsES3Header*>(0, header_size);
|
| + DCHECK(header);
|
| + header->num_uniforms = static_cast<uint32_t>(count);
|
| +
|
| + // Instead of GetDataAs<UniformES3Info*>, we do GetDataAs<int32_t>. This is
|
| + // because struct UniformES3Info is defined as five int32_t.
|
| + // By doing this, we can fill the structs through loops.
|
| + int32_t* entries =
|
| + bucket->GetDataAs<int32_t*>(header_size, entry_size);
|
| + DCHECK(entries);
|
| + const size_t kStride = sizeof(UniformES3Info) / sizeof(int32_t);
|
| +
|
| + const GLenum kPname[] = {
|
| + GL_UNIFORM_BLOCK_INDEX,
|
| + GL_UNIFORM_OFFSET,
|
| + GL_UNIFORM_ARRAY_STRIDE,
|
| + GL_UNIFORM_MATRIX_STRIDE,
|
| + GL_UNIFORM_IS_ROW_MAJOR,
|
| + };
|
| + const GLint kDefaultValue[] = { -1, -1, -1, -1, 0 };
|
| + const size_t kNumPnames = arraysize(kPname);
|
| + std::vector<GLuint> indices(count);
|
| + for (GLsizei ii = 0; ii < count; ++ii) {
|
| + indices[ii] = ii;
|
| + }
|
| + std::vector<GLint> params(count);
|
| + for (size_t pname_index = 0; pname_index < kNumPnames; ++pname_index) {
|
| + for (GLsizei ii = 0; ii < count; ++ii) {
|
| + params[ii] = kDefaultValue[pname_index];
|
| + }
|
| + glGetActiveUniformsiv(
|
| + program, count, &indices[0], kPname[pname_index], ¶ms[0]);
|
| + for (GLsizei ii = 0; ii < count; ++ii) {
|
| + entries[kStride * ii + pname_index] = params[ii];
|
| + }
|
| + }
|
| + return true;
|
| +}
|
| +
|
| Program::~Program() {
|
| if (manager_) {
|
| if (manager_->have_context_) {
|
|
|