OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/client/program_info_manager.h" | 5 #include "gpu/command_buffer/client/program_info_manager.h" |
6 | 6 |
7 namespace { | 7 namespace { |
8 | 8 |
9 template<typename T> static T LocalGetAs( | 9 template<typename T> static T LocalGetAs( |
10 const std::vector<int8>& data, uint32 offset, size_t size) { | 10 const std::vector<int8>& data, uint32 offset, size_t size) { |
(...skipping 26 matching lines...) Expand all Loading... |
37 : size(_size), | 37 : size(_size), |
38 type(_type), | 38 type(_type), |
39 name(_name) { | 39 name(_name) { |
40 is_array = (!name.empty() && name[name.size() - 1] == ']'); | 40 is_array = (!name.empty() && name[name.size() - 1] == ']'); |
41 DCHECK(!(size > 1 && !is_array)); | 41 DCHECK(!(size > 1 && !is_array)); |
42 } | 42 } |
43 | 43 |
44 ProgramInfoManager::Program::UniformInfo::~UniformInfo() { | 44 ProgramInfoManager::Program::UniformInfo::~UniformInfo() { |
45 } | 45 } |
46 | 46 |
| 47 ProgramInfoManager::Program::UniformES3::UniformES3() |
| 48 : block_index(-1), |
| 49 offset(-1), |
| 50 array_stride(-1), |
| 51 matrix_stride(-1), |
| 52 is_row_major(0) { |
| 53 } |
| 54 |
| 55 ProgramInfoManager::Program::UniformES3::~UniformES3() { |
| 56 } |
| 57 |
47 ProgramInfoManager::Program::UniformBlock::UniformBlock() | 58 ProgramInfoManager::Program::UniformBlock::UniformBlock() |
48 : binding(0), | 59 : binding(0), |
49 data_size(0), | 60 data_size(0), |
50 referenced_by_vertex_shader(false), | 61 referenced_by_vertex_shader(false), |
51 referenced_by_fragment_shader(false) { | 62 referenced_by_fragment_shader(false) { |
52 } | 63 } |
53 | 64 |
54 ProgramInfoManager::Program::UniformBlock::~UniformBlock() { | 65 ProgramInfoManager::Program::UniformBlock::~UniformBlock() { |
55 } | 66 } |
56 | 67 |
| 68 ProgramInfoManager::Program::TransformFeedbackVarying:: |
| 69 TransformFeedbackVarying() |
| 70 : size(0), |
| 71 type(0) { |
| 72 } |
| 73 |
| 74 ProgramInfoManager::Program::TransformFeedbackVarying:: |
| 75 ~TransformFeedbackVarying() { |
| 76 } |
| 77 |
57 ProgramInfoManager::Program::Program() | 78 ProgramInfoManager::Program::Program() |
58 : cached_es2_(false), | 79 : cached_es2_(false), |
59 max_attrib_name_length_(0), | 80 max_attrib_name_length_(0), |
60 max_uniform_name_length_(0), | 81 max_uniform_name_length_(0), |
61 link_status_(false), | 82 link_status_(false), |
62 cached_es3_uniform_blocks_(false), | 83 cached_es3_uniform_blocks_(false), |
63 active_uniform_block_max_name_length_(0) { | 84 active_uniform_block_max_name_length_(0), |
| 85 cached_es3_transform_feedback_varyings_(false), |
| 86 transform_feedback_varying_max_length_(0), |
| 87 cached_es3_uniformsiv_(false) { |
64 } | 88 } |
65 | 89 |
66 ProgramInfoManager::Program::~Program() { | 90 ProgramInfoManager::Program::~Program() { |
67 } | 91 } |
68 | 92 |
69 // TODO(gman): Add a faster lookup. | 93 // TODO(gman): Add a faster lookup. |
70 GLint ProgramInfoManager::Program::GetAttribLocation( | 94 GLint ProgramInfoManager::Program::GetAttribLocation( |
71 const std::string& name) const { | 95 const std::string& name) const { |
72 for (GLuint ii = 0; ii < attrib_infos_.size(); ++ii) { | 96 for (GLuint ii = 0; ii < attrib_infos_.size(); ++ii) { |
73 const VertexAttrib& info = attrib_infos_[ii]; | 97 const VertexAttrib& info = attrib_infos_[ii]; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 name.compare(0, open_pos, info.name, 0, open_pos) == 0) { | 141 name.compare(0, open_pos, info.name, 0, open_pos) == 0) { |
118 if (index >= 0 && index < info.size) { | 142 if (index >= 0 && index < info.size) { |
119 return info.element_locations[index]; | 143 return info.element_locations[index]; |
120 } | 144 } |
121 } | 145 } |
122 } | 146 } |
123 } | 147 } |
124 return -1; | 148 return -1; |
125 } | 149 } |
126 | 150 |
| 151 GLuint ProgramInfoManager::Program::GetUniformIndex( |
| 152 const std::string& name) const { |
| 153 // TODO(zmo): Maybe build a hashed_map for faster lookup. |
| 154 for (GLuint ii = 0; ii < uniform_infos_.size(); ++ii) { |
| 155 const UniformInfo& info = uniform_infos_[ii]; |
| 156 // For an array, either "var" or "var[0]" is considered as a match. |
| 157 // See "OpenGL ES 3.0.0, Section 2.11.3 Program Objects." |
| 158 if (info.name == name || |
| 159 (info.is_array && |
| 160 info.name.compare(0, info.name.size() - 3, name) == 0)) { |
| 161 return ii; |
| 162 } |
| 163 } |
| 164 return GL_INVALID_INDEX; |
| 165 } |
| 166 |
127 GLint ProgramInfoManager::Program::GetFragDataLocation( | 167 GLint ProgramInfoManager::Program::GetFragDataLocation( |
128 const std::string& name) const { | 168 const std::string& name) const { |
129 base::hash_map<std::string, GLint>::const_iterator iter = | 169 base::hash_map<std::string, GLint>::const_iterator iter = |
130 frag_data_locations_.find(name); | 170 frag_data_locations_.find(name); |
131 if (iter == frag_data_locations_.end()) | 171 if (iter == frag_data_locations_.end()) |
132 return -1; | 172 return -1; |
133 return iter->second; | 173 return iter->second; |
134 } | 174 } |
135 | 175 |
136 void ProgramInfoManager::Program::CacheFragDataLocation( | 176 void ProgramInfoManager::Program::CacheFragDataLocation( |
(...skipping 18 matching lines...) Expand all Loading... |
155 return true; | 195 return true; |
156 case GL_ACTIVE_UNIFORM_MAX_LENGTH: | 196 case GL_ACTIVE_UNIFORM_MAX_LENGTH: |
157 *params = static_cast<GLint>(max_uniform_name_length_); | 197 *params = static_cast<GLint>(max_uniform_name_length_); |
158 return true; | 198 return true; |
159 case GL_ACTIVE_UNIFORM_BLOCKS: | 199 case GL_ACTIVE_UNIFORM_BLOCKS: |
160 *params = static_cast<GLint>(uniform_blocks_.size()); | 200 *params = static_cast<GLint>(uniform_blocks_.size()); |
161 return true; | 201 return true; |
162 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: | 202 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: |
163 *params = static_cast<GLint>(active_uniform_block_max_name_length_); | 203 *params = static_cast<GLint>(active_uniform_block_max_name_length_); |
164 return true; | 204 return true; |
| 205 case GL_TRANSFORM_FEEDBACK_VARYINGS: |
| 206 *params = static_cast<GLint>(transform_feedback_varyings_.size()); |
| 207 return true; |
| 208 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: |
| 209 *params = static_cast<GLint>(transform_feedback_varying_max_length_); |
| 210 return true; |
165 default: | 211 default: |
166 NOTREACHED(); | 212 NOTREACHED(); |
167 break; | 213 break; |
168 } | 214 } |
169 return false; | 215 return false; |
170 } | 216 } |
171 | 217 |
172 GLuint ProgramInfoManager::Program::GetUniformBlockIndex( | 218 GLuint ProgramInfoManager::Program::GetUniformBlockIndex( |
173 const std::string& name) const { | 219 const std::string& name) const { |
174 for (size_t ii = 0; ii < uniform_blocks_.size(); ++ii) { | 220 for (size_t ii = 0; ii < uniform_blocks_.size(); ++ii) { |
175 if (uniform_blocks_[ii].name == name) { | 221 if (uniform_blocks_[ii].name == name) { |
176 return static_cast<GLuint>(ii); | 222 return static_cast<GLuint>(ii); |
177 } | 223 } |
178 } | 224 } |
179 return GL_INVALID_INDEX; | 225 return GL_INVALID_INDEX; |
180 } | 226 } |
181 | 227 |
| 228 void ProgramInfoManager::Program::UniformBlockBinding( |
| 229 GLuint index , GLuint binding) { |
| 230 if (index < uniform_blocks_.size()) { |
| 231 uniform_blocks_[index].binding = binding; |
| 232 } |
| 233 } |
| 234 |
| 235 const ProgramInfoManager::Program::TransformFeedbackVarying* |
| 236 ProgramInfoManager::Program::GetTransformFeedbackVarying(GLuint index) const { |
| 237 return (index < transform_feedback_varyings_.size()) ? |
| 238 &transform_feedback_varyings_[index] : NULL; |
| 239 } |
| 240 |
| 241 bool ProgramInfoManager::Program::GetUniformsiv( |
| 242 GLsizei count, const GLuint* indices, GLenum pname, GLint* params) { |
| 243 if (count == 0) { |
| 244 // At this point, pname has already been validated. |
| 245 return true; |
| 246 } |
| 247 DCHECK(count > 0 && indices); |
| 248 size_t num_uniforms = uniform_infos_.size(); |
| 249 if (num_uniforms == 0) { |
| 250 num_uniforms = uniforms_es3_.size(); |
| 251 } |
| 252 if (static_cast<size_t>(count) > num_uniforms) { |
| 253 return false; |
| 254 } |
| 255 for (GLsizei ii = 0; ii < count; ++ii) { |
| 256 if (indices[ii] >= num_uniforms) { |
| 257 return false; |
| 258 } |
| 259 } |
| 260 if (!params) { |
| 261 return true; |
| 262 } |
| 263 switch (pname) { |
| 264 case GL_UNIFORM_SIZE: |
| 265 DCHECK_EQ(num_uniforms, uniform_infos_.size()); |
| 266 for (GLsizei ii = 0; ii < count; ++ii) { |
| 267 params[ii] = static_cast<GLint>(uniform_infos_[indices[ii]].size); |
| 268 } |
| 269 return true; |
| 270 case GL_UNIFORM_TYPE: |
| 271 DCHECK_EQ(num_uniforms, uniform_infos_.size()); |
| 272 for (GLsizei ii = 0; ii < count; ++ii) { |
| 273 params[ii] = static_cast<GLint>(uniform_infos_[indices[ii]].type); |
| 274 } |
| 275 return true; |
| 276 case GL_UNIFORM_NAME_LENGTH: |
| 277 DCHECK_EQ(num_uniforms, uniform_infos_.size()); |
| 278 for (GLsizei ii = 0; ii < count; ++ii) { |
| 279 params[ii] = static_cast<GLint>( |
| 280 uniform_infos_[indices[ii]].name.length() + 1); |
| 281 } |
| 282 return true; |
| 283 case GL_UNIFORM_BLOCK_INDEX: |
| 284 DCHECK_EQ(num_uniforms, uniforms_es3_.size()); |
| 285 for (GLsizei ii = 0; ii < count; ++ii) { |
| 286 params[ii] = uniforms_es3_[indices[ii]].block_index; |
| 287 } |
| 288 return true; |
| 289 case GL_UNIFORM_OFFSET: |
| 290 DCHECK_EQ(num_uniforms, uniforms_es3_.size()); |
| 291 for (GLsizei ii = 0; ii < count; ++ii) { |
| 292 params[ii] = uniforms_es3_[indices[ii]].offset; |
| 293 } |
| 294 return true; |
| 295 case GL_UNIFORM_ARRAY_STRIDE: |
| 296 DCHECK_EQ(num_uniforms, uniforms_es3_.size()); |
| 297 for (GLsizei ii = 0; ii < count; ++ii) { |
| 298 params[ii] = uniforms_es3_[indices[ii]].array_stride; |
| 299 } |
| 300 return true; |
| 301 case GL_UNIFORM_MATRIX_STRIDE: |
| 302 DCHECK_EQ(num_uniforms, uniforms_es3_.size()); |
| 303 for (GLsizei ii = 0; ii < count; ++ii) { |
| 304 params[ii] = uniforms_es3_[indices[ii]].matrix_stride; |
| 305 } |
| 306 return true; |
| 307 case GL_UNIFORM_IS_ROW_MAJOR: |
| 308 DCHECK_EQ(num_uniforms, uniforms_es3_.size()); |
| 309 for (GLsizei ii = 0; ii < count; ++ii) { |
| 310 params[ii] = uniforms_es3_[indices[ii]].is_row_major; |
| 311 } |
| 312 return true; |
| 313 default: |
| 314 NOTREACHED(); |
| 315 break; |
| 316 } |
| 317 return false; |
| 318 } |
| 319 |
182 void ProgramInfoManager::Program::UpdateES2(const std::vector<int8>& result) { | 320 void ProgramInfoManager::Program::UpdateES2(const std::vector<int8>& result) { |
183 if (cached_es2_) { | 321 if (cached_es2_) { |
184 return; | 322 return; |
185 } | 323 } |
186 if (result.empty()) { | 324 if (result.empty()) { |
187 // This should only happen on a lost context. | 325 // This should only happen on a lost context. |
188 return; | 326 return; |
189 } | 327 } |
190 DCHECK_GE(result.size(), sizeof(ProgramInfoHeader)); | 328 DCHECK_GE(result.size(), sizeof(ProgramInfoHeader)); |
191 const ProgramInfoHeader* header = LocalGetAs<const ProgramInfoHeader*>( | 329 const ProgramInfoHeader* header = LocalGetAs<const ProgramInfoHeader*>( |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 uniform_blocks_[ii].active_uniform_indices[uu] = | 437 uniform_blocks_[ii].active_uniform_indices[uu] = |
300 static_cast<GLuint>(indices[uu]); | 438 static_cast<GLuint>(indices[uu]); |
301 } | 439 } |
302 indices += entries[ii].active_uniforms; | 440 indices += entries[ii].active_uniforms; |
303 data = reinterpret_cast<const char*>(indices); | 441 data = reinterpret_cast<const char*>(indices); |
304 } | 442 } |
305 DCHECK_EQ(data_size, size); | 443 DCHECK_EQ(data_size, size); |
306 cached_es3_uniform_blocks_ = true; | 444 cached_es3_uniform_blocks_ = true; |
307 } | 445 } |
308 | 446 |
| 447 void ProgramInfoManager::Program::UpdateES3Uniformsiv( |
| 448 const std::vector<int8>& result) { |
| 449 if (cached_es3_uniformsiv_) { |
| 450 return; |
| 451 } |
| 452 if (result.empty()) { |
| 453 // This should only happen on a lost context. |
| 454 return; |
| 455 } |
| 456 uniforms_es3_.clear(); |
| 457 |
| 458 // |result| comes from GPU process. We consider it trusted data. Therefore, |
| 459 // no need to check for overflows as the GPU side did the checks already. |
| 460 uint32_t header_size = sizeof(UniformsES3Header); |
| 461 DCHECK_GE(result.size(), header_size); |
| 462 const UniformsES3Header* header = LocalGetAs<const UniformsES3Header*>( |
| 463 result, 0, header_size); |
| 464 DCHECK(header); |
| 465 if (header->num_uniforms == 0) { |
| 466 DCHECK_EQ(result.size(), header_size); |
| 467 // TODO(zmo): Here we can't tell if no uniforms are defined, or |
| 468 // the previous link failed. |
| 469 return; |
| 470 } |
| 471 uniforms_es3_.resize(header->num_uniforms); |
| 472 |
| 473 uint32_t entry_size = sizeof(UniformES3Info) * header->num_uniforms; |
| 474 DCHECK_EQ(result.size(), header_size + entry_size); |
| 475 const UniformES3Info* entries = LocalGetAs<const UniformES3Info*>( |
| 476 result, header_size, entry_size); |
| 477 DCHECK(entries); |
| 478 |
| 479 for (uint32_t ii = 0; ii < header->num_uniforms; ++ii) { |
| 480 uniforms_es3_[ii].block_index = entries[ii].block_index; |
| 481 uniforms_es3_[ii].offset = entries[ii].offset; |
| 482 uniforms_es3_[ii].array_stride = entries[ii].array_stride; |
| 483 uniforms_es3_[ii].matrix_stride = entries[ii].matrix_stride; |
| 484 uniforms_es3_[ii].is_row_major = entries[ii].is_row_major; |
| 485 } |
| 486 cached_es3_uniformsiv_ = true; |
| 487 } |
| 488 |
| 489 void ProgramInfoManager::Program::UpdateES3TransformFeedbackVaryings( |
| 490 const std::vector<int8>& result) { |
| 491 if (cached_es3_transform_feedback_varyings_) { |
| 492 return; |
| 493 } |
| 494 if (result.empty()) { |
| 495 // This should only happen on a lost context. |
| 496 return; |
| 497 } |
| 498 transform_feedback_varyings_.clear(); |
| 499 transform_feedback_varying_max_length_ = 0; |
| 500 |
| 501 // |result| comes from GPU process. We consider it trusted data. Therefore, |
| 502 // no need to check for overflows as the GPU side did the checks already. |
| 503 uint32_t header_size = sizeof(TransformFeedbackVaryingsHeader); |
| 504 DCHECK_GE(result.size(), header_size); |
| 505 const TransformFeedbackVaryingsHeader* header = |
| 506 LocalGetAs<const TransformFeedbackVaryingsHeader*>( |
| 507 result, 0, header_size); |
| 508 DCHECK(header); |
| 509 if (header->num_transform_feedback_varyings == 0) { |
| 510 DCHECK_EQ(result.size(), header_size); |
| 511 // TODO(zmo): Here we can't tell if no TransformFeedback varyings are |
| 512 // defined, or the previous link failed. |
| 513 return; |
| 514 } |
| 515 transform_feedback_varyings_.resize(header->num_transform_feedback_varyings); |
| 516 |
| 517 uint32_t entry_size = sizeof(TransformFeedbackVaryingInfo) * |
| 518 header->num_transform_feedback_varyings; |
| 519 DCHECK_GE(result.size(), header_size + entry_size); |
| 520 uint32_t data_size = result.size() - header_size - entry_size; |
| 521 DCHECK_LT(0u, data_size); |
| 522 const TransformFeedbackVaryingInfo* entries = |
| 523 LocalGetAs<const TransformFeedbackVaryingInfo*>( |
| 524 result, header_size, entry_size); |
| 525 DCHECK(entries); |
| 526 const char* data = LocalGetAs<const char*>( |
| 527 result, header_size + entry_size, data_size); |
| 528 DCHECK(data); |
| 529 |
| 530 uint32_t size = 0; |
| 531 for (uint32_t ii = 0; ii < header->num_transform_feedback_varyings; ++ii) { |
| 532 transform_feedback_varyings_[ii].size = |
| 533 static_cast<GLsizei>(entries[ii].size); |
| 534 transform_feedback_varyings_[ii].type = |
| 535 static_cast<GLenum>(entries[ii].type); |
| 536 DCHECK_LE(1u, entries[ii].name_length); |
| 537 if (entries[ii].name_length > transform_feedback_varying_max_length_) { |
| 538 transform_feedback_varying_max_length_ = entries[ii].name_length; |
| 539 } |
| 540 size += entries[ii].name_length; |
| 541 DCHECK_GE(data_size, size); |
| 542 transform_feedback_varyings_[ii].name = |
| 543 std::string(data, entries[ii].name_length - 1); |
| 544 data += entries[ii].name_length; |
| 545 } |
| 546 DCHECK_EQ(data_size, size); |
| 547 cached_es3_transform_feedback_varyings_ = true; |
| 548 } |
| 549 |
309 bool ProgramInfoManager::Program::IsCached(ProgramInfoType type) const { | 550 bool ProgramInfoManager::Program::IsCached(ProgramInfoType type) const { |
310 switch (type) { | 551 switch (type) { |
311 case kES2: | 552 case kES2: |
312 return cached_es2_; | 553 return cached_es2_; |
313 case kES3UniformBlocks: | 554 case kES3UniformBlocks: |
314 return cached_es3_uniform_blocks_; | 555 return cached_es3_uniform_blocks_; |
| 556 case kES3TransformFeedbackVaryings: |
| 557 return cached_es3_transform_feedback_varyings_; |
| 558 case kES3Uniformsiv: |
| 559 return cached_es3_uniformsiv_; |
315 case kNone: | 560 case kNone: |
316 return true; | 561 return true; |
317 default: | 562 default: |
318 NOTREACHED(); | 563 NOTREACHED(); |
319 return true; | 564 return true; |
320 } | 565 } |
321 } | 566 } |
322 | 567 |
323 | 568 |
324 ProgramInfoManager::ProgramInfoManager() { | 569 ProgramInfoManager::ProgramInfoManager() { |
(...skipping 22 matching lines...) Expand all Loading... |
347 // pepper. http://crbug.com/418651 | 592 // pepper. http://crbug.com/418651 |
348 gl->GetProgramInfoCHROMIUMHelper(program, &result); | 593 gl->GetProgramInfoCHROMIUMHelper(program, &result); |
349 } | 594 } |
350 info->UpdateES2(result); | 595 info->UpdateES2(result); |
351 break; | 596 break; |
352 case kES3UniformBlocks: | 597 case kES3UniformBlocks: |
353 { | 598 { |
354 base::AutoUnlock unlock(lock_); | 599 base::AutoUnlock unlock(lock_); |
355 // lock_ can't be held across IPC call or else it may deadlock in | 600 // lock_ can't be held across IPC call or else it may deadlock in |
356 // pepper. http://crbug.com/418651 | 601 // pepper. http://crbug.com/418651 |
357 | 602 gl->GetUniformBlocksCHROMIUMHelper(program, &result); |
358 // TODO(zmo): Uncomment the below line once GetUniformBlocksCHROMIUM | |
359 // command is implemented. | |
360 // gl->GetUniformBlocksCHROMIUMHeler(program, &result); | |
361 } | 603 } |
362 info->UpdateES3UniformBlocks(result); | 604 info->UpdateES3UniformBlocks(result); |
| 605 break; |
| 606 case kES3TransformFeedbackVaryings: |
| 607 { |
| 608 base::AutoUnlock unlock(lock_); |
| 609 // lock_ can't be held across IPC call or else it may deadlock in |
| 610 // pepper. http://crbug.com/418651 |
| 611 gl->GetTransformFeedbackVaryingsCHROMIUMHelper(program, &result); |
| 612 } |
| 613 info->UpdateES3TransformFeedbackVaryings(result); |
| 614 case kES3Uniformsiv: |
| 615 { |
| 616 base::AutoUnlock unlock(lock_); |
| 617 // lock_ can't be held across IPC call or else it may deadlock in |
| 618 // pepper. http://crbug.com/418651 |
| 619 gl->GetUniformsES3CHROMIUMHelper(program, &result); |
| 620 } |
| 621 info->UpdateES3Uniformsiv(result); |
363 default: | 622 default: |
364 NOTREACHED(); | 623 NOTREACHED(); |
365 return NULL; | 624 return NULL; |
366 } | 625 } |
367 return info; | 626 return info; |
368 } | 627 } |
369 | 628 |
370 void ProgramInfoManager::CreateInfo(GLuint program) { | 629 void ProgramInfoManager::CreateInfo(GLuint program) { |
371 base::AutoLock auto_lock(lock_); | 630 base::AutoLock auto_lock(lock_); |
372 program_infos_.erase(program); | 631 program_infos_.erase(program); |
(...skipping 17 matching lines...) Expand all Loading... |
390 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: | 649 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: |
391 case GL_ACTIVE_UNIFORMS: | 650 case GL_ACTIVE_UNIFORMS: |
392 case GL_ACTIVE_UNIFORM_MAX_LENGTH: | 651 case GL_ACTIVE_UNIFORM_MAX_LENGTH: |
393 case GL_LINK_STATUS: | 652 case GL_LINK_STATUS: |
394 type = kES2; | 653 type = kES2; |
395 break; | 654 break; |
396 case GL_ACTIVE_UNIFORM_BLOCKS: | 655 case GL_ACTIVE_UNIFORM_BLOCKS: |
397 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: | 656 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: |
398 type = kES3UniformBlocks; | 657 type = kES3UniformBlocks; |
399 break; | 658 break; |
| 659 case GL_TRANSFORM_FEEDBACK_VARYINGS: |
| 660 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: |
| 661 type = kES3TransformFeedbackVaryings; |
| 662 break; |
400 default: | 663 default: |
401 return false; | 664 return false; |
402 } | 665 } |
403 Program* info = GetProgramInfo(gl, program, type); | 666 Program* info = GetProgramInfo(gl, program, type); |
404 if (!info) { | 667 if (!info) { |
405 return false; | 668 return false; |
406 } | 669 } |
407 return info->GetProgramiv(pname, params); | 670 return info->GetProgramiv(pname, params); |
408 } | 671 } |
409 | 672 |
| 673 bool ProgramInfoManager::GetActiveUniformsiv( |
| 674 GLES2Implementation* gl, GLuint program, GLsizei count, |
| 675 const GLuint* indices, GLenum pname, GLint* params) { |
| 676 base::AutoLock auto_lock(lock_); |
| 677 ProgramInfoType type = kNone; |
| 678 switch (pname) { |
| 679 case GL_UNIFORM_SIZE: |
| 680 case GL_UNIFORM_TYPE: |
| 681 case GL_UNIFORM_NAME_LENGTH: |
| 682 type = kES2; |
| 683 break; |
| 684 case GL_UNIFORM_BLOCK_INDEX: |
| 685 case GL_UNIFORM_OFFSET: |
| 686 case GL_UNIFORM_ARRAY_STRIDE: |
| 687 case GL_UNIFORM_MATRIX_STRIDE: |
| 688 case GL_UNIFORM_IS_ROW_MAJOR: |
| 689 type = kES3Uniformsiv; |
| 690 break; |
| 691 default: |
| 692 return false; |
| 693 } |
| 694 Program* info = GetProgramInfo(gl, program, type); |
| 695 if (info) { |
| 696 return info->GetUniformsiv(count, indices, pname, params); |
| 697 } |
| 698 return gl->GetActiveUniformsivHelper(program, count, indices, pname, params); |
| 699 } |
| 700 |
410 GLint ProgramInfoManager::GetAttribLocation( | 701 GLint ProgramInfoManager::GetAttribLocation( |
411 GLES2Implementation* gl, GLuint program, const char* name) { | 702 GLES2Implementation* gl, GLuint program, const char* name) { |
412 { | 703 { |
413 base::AutoLock auto_lock(lock_); | 704 base::AutoLock auto_lock(lock_); |
414 Program* info = GetProgramInfo(gl, program, kES2); | 705 Program* info = GetProgramInfo(gl, program, kES2); |
415 if (info) { | 706 if (info) { |
416 return info->GetAttribLocation(name); | 707 return info->GetAttribLocation(name); |
417 } | 708 } |
418 } | 709 } |
419 return gl->GetAttribLocationHelper(program, name); | 710 return gl->GetAttribLocationHelper(program, name); |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
628 *params = static_cast<GLint>( | 919 *params = static_cast<GLint>( |
629 uniform_block->referenced_by_fragment_shader); | 920 uniform_block->referenced_by_fragment_shader); |
630 break; | 921 break; |
631 default: | 922 default: |
632 NOTREACHED(); | 923 NOTREACHED(); |
633 } | 924 } |
634 return true; | 925 return true; |
635 } | 926 } |
636 } | 927 } |
637 } | 928 } |
638 return false; | 929 return gl->GetActiveUniformBlockivHelper(program, index, pname, params); |
639 // TODO(zmo): return gl->GetActiveUniformBlockivHelper( | 930 } |
640 // program, index, pname, params); | 931 |
| 932 void ProgramInfoManager::UniformBlockBinding( |
| 933 GLES2Implementation* gl, GLuint program, GLuint index, GLuint binding) { |
| 934 GLuint max_bindings = |
| 935 static_cast<GLuint>(gl->capabilities().max_uniform_buffer_bindings); |
| 936 if (binding < max_bindings) { |
| 937 base::AutoLock auto_lock(lock_); |
| 938 // If UniformBlock info haven't been cached yet, skip updating the binding. |
| 939 Program* info = GetProgramInfo(gl, program, kNone); |
| 940 if (info) { |
| 941 info->UniformBlockBinding(index, binding); |
| 942 } |
| 943 } |
| 944 } |
| 945 |
| 946 bool ProgramInfoManager::GetTransformFeedbackVarying( |
| 947 GLES2Implementation* gl, GLuint program, GLuint index, GLsizei bufsize, |
| 948 GLsizei* length, GLsizei* size, GLenum* type, char* name) { |
| 949 { |
| 950 base::AutoLock auto_lock(lock_); |
| 951 Program* info = GetProgramInfo(gl, program, kES3TransformFeedbackVaryings); |
| 952 if (info) { |
| 953 const Program::TransformFeedbackVarying* varying = |
| 954 info->GetTransformFeedbackVarying(index); |
| 955 if (varying) { |
| 956 if (size) { |
| 957 *size = varying->size; |
| 958 } |
| 959 if (type) { |
| 960 *type = varying->type; |
| 961 } |
| 962 if (length || name) { |
| 963 GLsizei max_size = std::min( |
| 964 bufsize - 1, static_cast<GLsizei>(varying->name.size())); |
| 965 if (length) { |
| 966 *length = static_cast<GLsizei>(max_size); |
| 967 } |
| 968 if (name && bufsize > 0) { |
| 969 memcpy(name, varying->name.c_str(), max_size); |
| 970 name[max_size] = '\0'; |
| 971 } |
| 972 } |
| 973 return true; |
| 974 } |
| 975 } |
| 976 } |
| 977 return gl->GetTransformFeedbackVaryingHelper( |
| 978 program, index, bufsize, length, size, type, name); |
| 979 } |
| 980 |
| 981 bool ProgramInfoManager::GetUniformIndices(GLES2Implementation* gl, |
| 982 GLuint program, GLsizei count, const char* const* names, GLuint* indices) { |
| 983 { |
| 984 base::AutoLock auto_lock(lock_); |
| 985 Program* info = GetProgramInfo(gl, program, kES2); |
| 986 if (info) { |
| 987 DCHECK_LT(0, count); |
| 988 DCHECK(names && indices); |
| 989 for (GLsizei ii = 0; ii < count; ++ii) { |
| 990 indices[ii] = info->GetUniformIndex(names[ii]); |
| 991 } |
| 992 return true; |
| 993 } |
| 994 } |
| 995 return gl->GetUniformIndicesHelper(program, count, names, indices); |
641 } | 996 } |
642 | 997 |
643 } // namespace gles2 | 998 } // namespace gles2 |
644 } // namespace gpu | 999 } // namespace gpu |
645 | 1000 |
OLD | NEW |