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::UniformBlock::UniformBlock() |
| 48 : binding(0), |
| 49 data_size(0), |
| 50 referenced_by_vertex_shader(false), |
| 51 referenced_by_fragment_shader(false) { |
| 52 } |
| 53 |
| 54 ProgramInfoManager::Program::UniformBlock::~UniformBlock() { |
| 55 } |
| 56 |
47 ProgramInfoManager::Program::Program() | 57 ProgramInfoManager::Program::Program() |
48 : cached_(false), | 58 : cached_es2_(false), |
49 max_attrib_name_length_(0), | 59 max_attrib_name_length_(0), |
50 max_uniform_name_length_(0), | 60 max_uniform_name_length_(0), |
51 link_status_(false) { | 61 link_status_(false), |
| 62 cached_es3_uniform_blocks_(false), |
| 63 active_uniform_block_max_name_length_(0) { |
52 } | 64 } |
53 | 65 |
54 ProgramInfoManager::Program::~Program() { | 66 ProgramInfoManager::Program::~Program() { |
55 } | 67 } |
56 | 68 |
57 // TODO(gman): Add a faster lookup. | 69 // TODO(gman): Add a faster lookup. |
58 GLint ProgramInfoManager::Program::GetAttribLocation( | 70 GLint ProgramInfoManager::Program::GetAttribLocation( |
59 const std::string& name) const { | 71 const std::string& name) const { |
60 for (GLuint ii = 0; ii < attrib_infos_.size(); ++ii) { | 72 for (GLuint ii = 0; ii < attrib_infos_.size(); ++ii) { |
61 const VertexAttrib& info = attrib_infos_[ii]; | 73 const VertexAttrib& info = attrib_infos_[ii]; |
62 if (info.name == name) { | 74 if (info.name == name) { |
63 return info.location; | 75 return info.location; |
64 } | 76 } |
65 } | 77 } |
66 return -1; | 78 return -1; |
67 } | 79 } |
68 | 80 |
69 const ProgramInfoManager::Program::VertexAttrib* | 81 const ProgramInfoManager::Program::VertexAttrib* |
70 ProgramInfoManager::Program::GetAttribInfo(GLint index) const { | 82 ProgramInfoManager::Program::GetAttribInfo(GLint index) const { |
71 return (static_cast<size_t>(index) < attrib_infos_.size()) ? | 83 return (static_cast<size_t>(index) < attrib_infos_.size()) ? |
72 &attrib_infos_[index] : NULL; | 84 &attrib_infos_[index] : NULL; |
73 } | 85 } |
74 | 86 |
75 const ProgramInfoManager::Program::UniformInfo* | 87 const ProgramInfoManager::Program::UniformInfo* |
76 ProgramInfoManager::Program::GetUniformInfo(GLint index) const { | 88 ProgramInfoManager::Program::GetUniformInfo(GLint index) const { |
77 return (static_cast<size_t>(index) < uniform_infos_.size()) ? | 89 return (static_cast<size_t>(index) < uniform_infos_.size()) ? |
78 &uniform_infos_[index] : NULL; | 90 &uniform_infos_[index] : NULL; |
79 } | 91 } |
80 | 92 |
| 93 const ProgramInfoManager::Program::UniformBlock* |
| 94 ProgramInfoManager::Program::GetUniformBlock(GLuint index) const { |
| 95 return (index < uniform_blocks_.size()) ? &uniform_blocks_[index] : NULL; |
| 96 } |
| 97 |
81 GLint ProgramInfoManager::Program::GetUniformLocation( | 98 GLint ProgramInfoManager::Program::GetUniformLocation( |
82 const std::string& name) const { | 99 const std::string& name) const { |
83 bool getting_array_location = false; | 100 bool getting_array_location = false; |
84 size_t open_pos = std::string::npos; | 101 size_t open_pos = std::string::npos; |
85 int index = 0; | 102 int index = 0; |
86 if (!GLES2Util::ParseUniformName( | 103 if (!GLES2Util::ParseUniformName( |
87 name, &open_pos, &index, &getting_array_location)) { | 104 name, &open_pos, &index, &getting_array_location)) { |
88 return -1; | 105 return -1; |
89 } | 106 } |
90 for (GLuint ii = 0; ii < uniform_infos_.size(); ++ii) { | 107 for (GLuint ii = 0; ii < uniform_infos_.size(); ++ii) { |
(...skipping 27 matching lines...) Expand all Loading... |
118 | 135 |
119 void ProgramInfoManager::Program::CacheFragDataLocation( | 136 void ProgramInfoManager::Program::CacheFragDataLocation( |
120 const std::string& name, GLint loc) { | 137 const std::string& name, GLint loc) { |
121 frag_data_locations_[name] = loc; | 138 frag_data_locations_[name] = loc; |
122 } | 139 } |
123 | 140 |
124 bool ProgramInfoManager::Program::GetProgramiv( | 141 bool ProgramInfoManager::Program::GetProgramiv( |
125 GLenum pname, GLint* params) { | 142 GLenum pname, GLint* params) { |
126 switch (pname) { | 143 switch (pname) { |
127 case GL_LINK_STATUS: | 144 case GL_LINK_STATUS: |
128 *params = link_status_; | 145 *params = static_cast<GLint>(link_status_); |
129 return true; | 146 return true; |
130 case GL_ACTIVE_ATTRIBUTES: | 147 case GL_ACTIVE_ATTRIBUTES: |
131 *params = attrib_infos_.size(); | 148 *params = static_cast<GLint>(attrib_infos_.size()); |
132 return true; | 149 return true; |
133 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: | 150 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: |
134 *params = max_attrib_name_length_; | 151 *params = static_cast<GLint>(max_attrib_name_length_); |
135 return true; | 152 return true; |
136 case GL_ACTIVE_UNIFORMS: | 153 case GL_ACTIVE_UNIFORMS: |
137 *params = uniform_infos_.size(); | 154 *params = static_cast<GLint>(uniform_infos_.size()); |
138 return true; | 155 return true; |
139 case GL_ACTIVE_UNIFORM_MAX_LENGTH: | 156 case GL_ACTIVE_UNIFORM_MAX_LENGTH: |
140 *params = max_uniform_name_length_; | 157 *params = static_cast<GLint>(max_uniform_name_length_); |
| 158 return true; |
| 159 case GL_ACTIVE_UNIFORM_BLOCKS: |
| 160 *params = static_cast<GLint>(uniform_blocks_.size()); |
| 161 return true; |
| 162 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: |
| 163 *params = static_cast<GLint>(active_uniform_block_max_name_length_); |
141 return true; | 164 return true; |
142 default: | 165 default: |
| 166 NOTREACHED(); |
143 break; | 167 break; |
144 } | 168 } |
145 return false; | 169 return false; |
146 } | 170 } |
147 | 171 |
148 void ProgramInfoManager::Program::Update( | 172 GLuint ProgramInfoManager::Program::GetUniformBlockIndex( |
149 GLES2Implementation* gl, | 173 const std::string& name) const { |
150 GLuint program, | 174 for (size_t ii = 0; ii < uniform_blocks_.size(); ++ii) { |
151 const std::vector<int8>& result) { | 175 if (uniform_blocks_[ii].name == name) { |
152 if (cached_) { | 176 return static_cast<GLuint>(ii); |
| 177 } |
| 178 } |
| 179 return GL_INVALID_INDEX; |
| 180 } |
| 181 |
| 182 void ProgramInfoManager::Program::UpdateES2(const std::vector<int8>& result) { |
| 183 if (cached_es2_) { |
153 return; | 184 return; |
154 } | 185 } |
155 if (result.empty()) { | 186 if (result.empty()) { |
156 // This should only happen on a lost context. | 187 // This should only happen on a lost context. |
157 return; | 188 return; |
158 } | 189 } |
159 DCHECK_GE(result.size(), sizeof(ProgramInfoHeader)); | 190 DCHECK_GE(result.size(), sizeof(ProgramInfoHeader)); |
160 const ProgramInfoHeader* header = LocalGetAs<const ProgramInfoHeader*>( | 191 const ProgramInfoHeader* header = LocalGetAs<const ProgramInfoHeader*>( |
161 result, 0, sizeof(header)); | 192 result, 0, sizeof(header)); |
162 link_status_ = header->link_status != 0; | 193 link_status_ = header->link_status != 0; |
(...skipping 30 matching lines...) Expand all Loading... |
193 UniformInfo info(input->size, input->type, name); | 224 UniformInfo info(input->size, input->type, name); |
194 max_uniform_name_length_ = std::max( | 225 max_uniform_name_length_ = std::max( |
195 static_cast<GLsizei>(name.size() + 1), max_uniform_name_length_); | 226 static_cast<GLsizei>(name.size() + 1), max_uniform_name_length_); |
196 for (int32 jj = 0; jj < input->size; ++jj) { | 227 for (int32 jj = 0; jj < input->size; ++jj) { |
197 info.element_locations.push_back(locations[jj]); | 228 info.element_locations.push_back(locations[jj]); |
198 } | 229 } |
199 uniform_infos_.push_back(info); | 230 uniform_infos_.push_back(info); |
200 ++input; | 231 ++input; |
201 } | 232 } |
202 DCHECK_EQ(header->num_attribs + header->num_uniforms, | 233 DCHECK_EQ(header->num_attribs + header->num_uniforms, |
203 static_cast<uint32>(input - inputs)); | 234 static_cast<uint32>(input - inputs)); |
204 cached_ = true; | 235 cached_es2_ = true; |
205 } | 236 } |
206 | 237 |
207 bool ProgramInfoManager::Program::cached() const { | 238 void ProgramInfoManager::Program::UpdateES3UniformBlocks( |
208 return cached_; | 239 const std::vector<int8>& result) { |
| 240 if (cached_es3_uniform_blocks_) { |
| 241 return; |
| 242 } |
| 243 if (result.empty()) { |
| 244 // This should only happen on a lost context. |
| 245 return; |
| 246 } |
| 247 uniform_blocks_.clear(); |
| 248 active_uniform_block_max_name_length_ = 0; |
| 249 |
| 250 // |result| comes from GPU process. We consider it trusted data. Therefore, |
| 251 // no need to check for overflows as the GPU side did the checks already. |
| 252 uint32_t header_size = sizeof(UniformBlocksHeader); |
| 253 DCHECK_GE(result.size(), header_size); |
| 254 const UniformBlocksHeader* header = LocalGetAs<const UniformBlocksHeader*>( |
| 255 result, 0, header_size); |
| 256 DCHECK(header); |
| 257 if (header->num_uniform_blocks == 0) { |
| 258 DCHECK_EQ(result.size(), header_size); |
| 259 // TODO(zmo): Here we can't tell if no uniform blocks are defined, or |
| 260 // the previous link failed. |
| 261 return; |
| 262 } |
| 263 uniform_blocks_.resize(header->num_uniform_blocks); |
| 264 |
| 265 uint32_t entry_size = sizeof(UniformBlockInfo) * header->num_uniform_blocks; |
| 266 DCHECK_GE(result.size(), header_size + entry_size); |
| 267 uint32_t data_size = result.size() - header_size - entry_size; |
| 268 DCHECK_LT(0u, data_size); |
| 269 const UniformBlockInfo* entries = LocalGetAs<const UniformBlockInfo*>( |
| 270 result, header_size, entry_size); |
| 271 DCHECK(entries); |
| 272 const char* data = LocalGetAs<const char*>( |
| 273 result, header_size + entry_size, data_size); |
| 274 DCHECK(data); |
| 275 |
| 276 uint32_t size = 0; |
| 277 for (uint32_t ii = 0; ii < header->num_uniform_blocks; ++ii) { |
| 278 uniform_blocks_[ii].binding = static_cast<GLuint>(entries[ii].binding); |
| 279 uniform_blocks_[ii].data_size = static_cast<GLuint>(entries[ii].data_size); |
| 280 uniform_blocks_[ii].active_uniform_indices.resize( |
| 281 entries[ii].active_uniforms); |
| 282 uniform_blocks_[ii].referenced_by_vertex_shader = static_cast<GLboolean>( |
| 283 entries[ii].referenced_by_vertex_shader); |
| 284 uniform_blocks_[ii].referenced_by_fragment_shader = static_cast<GLboolean>( |
| 285 entries[ii].referenced_by_fragment_shader); |
| 286 // Uniform block names can't be empty strings. |
| 287 DCHECK_LT(1u, entries[ii].name_length); |
| 288 if (entries[ii].name_length > active_uniform_block_max_name_length_) { |
| 289 active_uniform_block_max_name_length_ = entries[ii].name_length; |
| 290 } |
| 291 size += entries[ii].name_length; |
| 292 DCHECK_GE(data_size, size); |
| 293 uniform_blocks_[ii].name = std::string(data, entries[ii].name_length - 1); |
| 294 data += entries[ii].name_length; |
| 295 size += entries[ii].active_uniforms * sizeof(uint32_t); |
| 296 DCHECK_GE(data_size, size); |
| 297 const uint32_t* indices = reinterpret_cast<const uint32_t*>(data); |
| 298 for (uint32_t uu = 0; uu < entries[ii].active_uniforms; ++uu) { |
| 299 uniform_blocks_[ii].active_uniform_indices[uu] = |
| 300 static_cast<GLuint>(indices[uu]); |
| 301 } |
| 302 indices += entries[ii].active_uniforms; |
| 303 data = reinterpret_cast<const char*>(indices); |
| 304 } |
| 305 DCHECK_EQ(data_size, size); |
| 306 cached_es3_uniform_blocks_ = true; |
| 307 } |
| 308 |
| 309 bool ProgramInfoManager::Program::IsCached(ProgramInfoType type) const { |
| 310 switch (type) { |
| 311 case kES2: |
| 312 return cached_es2_; |
| 313 case kES3UniformBlocks: |
| 314 return cached_es3_uniform_blocks_; |
| 315 case kNone: |
| 316 return true; |
| 317 default: |
| 318 NOTREACHED(); |
| 319 return true; |
| 320 } |
209 } | 321 } |
210 | 322 |
211 | 323 |
212 ProgramInfoManager::ProgramInfoManager() { | 324 ProgramInfoManager::ProgramInfoManager() { |
213 } | 325 } |
214 | 326 |
215 ProgramInfoManager::~ProgramInfoManager() { | 327 ProgramInfoManager::~ProgramInfoManager() { |
216 } | 328 } |
217 | 329 |
218 ProgramInfoManager::Program* ProgramInfoManager::GetProgramInfo( | 330 ProgramInfoManager::Program* ProgramInfoManager::GetProgramInfo( |
219 GLES2Implementation* gl, GLuint program) { | 331 GLES2Implementation* gl, GLuint program, ProgramInfoType type) { |
220 lock_.AssertAcquired(); | 332 lock_.AssertAcquired(); |
221 ProgramInfoMap::iterator it = program_infos_.find(program); | 333 ProgramInfoMap::iterator it = program_infos_.find(program); |
222 if (it == program_infos_.end()) { | 334 if (it == program_infos_.end()) { |
223 return NULL; | 335 return NULL; |
224 } | 336 } |
225 Program* info = &it->second; | 337 Program* info = &it->second; |
226 if (info->cached()) | 338 if (info->IsCached(type)) |
227 return info; | 339 return info; |
| 340 |
228 std::vector<int8> result; | 341 std::vector<int8> result; |
229 { | 342 switch (type) { |
230 base::AutoUnlock unlock(lock_); | 343 case kES2: |
231 // lock_ can't be held across IPC call or else it may deadlock in pepper. | 344 { |
232 // http://crbug.com/418651 | 345 base::AutoUnlock unlock(lock_); |
233 gl->GetProgramInfoCHROMIUMHelper(program, &result); | 346 // lock_ can't be held across IPC call or else it may deadlock in |
| 347 // pepper. http://crbug.com/418651 |
| 348 gl->GetProgramInfoCHROMIUMHelper(program, &result); |
| 349 } |
| 350 info->UpdateES2(result); |
| 351 break; |
| 352 case kES3UniformBlocks: |
| 353 { |
| 354 base::AutoUnlock unlock(lock_); |
| 355 // lock_ can't be held across IPC call or else it may deadlock in |
| 356 // pepper. http://crbug.com/418651 |
| 357 |
| 358 // TODO(zmo): Uncomment the below line once GetUniformBlocksCHROMIUM |
| 359 // command is implemented. |
| 360 // gl->GetUniformBlocksCHROMIUMHeler(program, &result); |
| 361 } |
| 362 info->UpdateES3UniformBlocks(result); |
| 363 default: |
| 364 NOTREACHED(); |
| 365 return NULL; |
234 } | 366 } |
235 | |
236 it = program_infos_.find(program); | |
237 if (it == program_infos_.end()) { | |
238 return NULL; | |
239 } | |
240 info = &it->second; | |
241 info->Update(gl, program, result); | |
242 return info; | 367 return info; |
243 } | 368 } |
244 | 369 |
245 void ProgramInfoManager::CreateInfo(GLuint program) { | 370 void ProgramInfoManager::CreateInfo(GLuint program) { |
246 base::AutoLock auto_lock(lock_); | 371 base::AutoLock auto_lock(lock_); |
247 program_infos_.erase(program); | 372 program_infos_.erase(program); |
248 std::pair<ProgramInfoMap::iterator, bool> result = | 373 std::pair<ProgramInfoMap::iterator, bool> result = |
249 program_infos_.insert(std::make_pair(program, Program())); | 374 program_infos_.insert(std::make_pair(program, Program())); |
250 | 375 |
251 DCHECK(result.second); | 376 DCHECK(result.second); |
252 } | 377 } |
253 | 378 |
254 void ProgramInfoManager::DeleteInfo(GLuint program) { | 379 void ProgramInfoManager::DeleteInfo(GLuint program) { |
255 base::AutoLock auto_lock(lock_); | 380 base::AutoLock auto_lock(lock_); |
256 program_infos_.erase(program); | 381 program_infos_.erase(program); |
257 } | 382 } |
258 | 383 |
259 bool ProgramInfoManager::GetProgramiv( | 384 bool ProgramInfoManager::GetProgramiv( |
260 GLES2Implementation* gl, GLuint program, GLenum pname, GLint* params) { | 385 GLES2Implementation* gl, GLuint program, GLenum pname, GLint* params) { |
261 base::AutoLock auto_lock(lock_); | 386 base::AutoLock auto_lock(lock_); |
262 Program* info = GetProgramInfo(gl, program); | 387 ProgramInfoType type = kNone; |
| 388 switch (pname) { |
| 389 case GL_ACTIVE_ATTRIBUTES: |
| 390 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: |
| 391 case GL_ACTIVE_UNIFORMS: |
| 392 case GL_ACTIVE_UNIFORM_MAX_LENGTH: |
| 393 case GL_LINK_STATUS: |
| 394 type = kES2; |
| 395 break; |
| 396 case GL_ACTIVE_UNIFORM_BLOCKS: |
| 397 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: |
| 398 type = kES3UniformBlocks; |
| 399 break; |
| 400 default: |
| 401 return false; |
| 402 } |
| 403 Program* info = GetProgramInfo(gl, program, type); |
263 if (!info) { | 404 if (!info) { |
264 return false; | 405 return false; |
265 } | 406 } |
266 return info->GetProgramiv(pname, params); | 407 return info->GetProgramiv(pname, params); |
267 } | 408 } |
268 | 409 |
269 GLint ProgramInfoManager::GetAttribLocation( | 410 GLint ProgramInfoManager::GetAttribLocation( |
270 GLES2Implementation* gl, GLuint program, const char* name) { | 411 GLES2Implementation* gl, GLuint program, const char* name) { |
271 { | 412 { |
272 base::AutoLock auto_lock(lock_); | 413 base::AutoLock auto_lock(lock_); |
273 Program* info = GetProgramInfo(gl, program); | 414 Program* info = GetProgramInfo(gl, program, kES2); |
274 if (info) { | 415 if (info) { |
275 return info->GetAttribLocation(name); | 416 return info->GetAttribLocation(name); |
276 } | 417 } |
277 } | 418 } |
278 return gl->GetAttribLocationHelper(program, name); | 419 return gl->GetAttribLocationHelper(program, name); |
279 } | 420 } |
280 | 421 |
281 GLint ProgramInfoManager::GetUniformLocation( | 422 GLint ProgramInfoManager::GetUniformLocation( |
282 GLES2Implementation* gl, GLuint program, const char* name) { | 423 GLES2Implementation* gl, GLuint program, const char* name) { |
283 { | 424 { |
284 base::AutoLock auto_lock(lock_); | 425 base::AutoLock auto_lock(lock_); |
285 Program* info = GetProgramInfo(gl, program); | 426 Program* info = GetProgramInfo(gl, program, kES2); |
286 if (info) { | 427 if (info) { |
287 return info->GetUniformLocation(name); | 428 return info->GetUniformLocation(name); |
288 } | 429 } |
289 } | 430 } |
290 return gl->GetUniformLocationHelper(program, name); | 431 return gl->GetUniformLocationHelper(program, name); |
291 } | 432 } |
292 | 433 |
293 GLint ProgramInfoManager::GetFragDataLocation( | 434 GLint ProgramInfoManager::GetFragDataLocation( |
294 GLES2Implementation* gl, GLuint program, const char* name) { | 435 GLES2Implementation* gl, GLuint program, const char* name) { |
295 // TODO(zmo): make FragData locations part of the ProgramInfo that are | 436 // TODO(zmo): make FragData locations part of the ProgramInfo that are |
296 // fetched altogether from the service side. See crbug.com/452104. | 437 // fetched altogether from the service side. See crbug.com/452104. |
297 { | 438 { |
298 base::AutoLock auto_lock(lock_); | 439 base::AutoLock auto_lock(lock_); |
299 Program* info = GetProgramInfo(gl, program); | 440 Program* info = GetProgramInfo(gl, program, kNone); |
300 if (info) { | 441 if (info) { |
301 GLint possible_loc = info->GetFragDataLocation(name); | 442 GLint possible_loc = info->GetFragDataLocation(name); |
302 if (possible_loc != -1) | 443 if (possible_loc != -1) |
303 return possible_loc; | 444 return possible_loc; |
304 } | 445 } |
305 } | 446 } |
306 GLint loc = gl->GetFragDataLocationHelper(program, name); | 447 GLint loc = gl->GetFragDataLocationHelper(program, name); |
307 if (loc != -1) { | 448 if (loc != -1) { |
308 base::AutoLock auto_lock(lock_); | 449 base::AutoLock auto_lock(lock_); |
309 Program* info = GetProgramInfo(gl, program); | 450 Program* info = GetProgramInfo(gl, program, kNone); |
310 if (info) { | 451 if (info) { |
311 info->CacheFragDataLocation(name, loc); | 452 info->CacheFragDataLocation(name, loc); |
312 } | 453 } |
313 } | 454 } |
314 return loc; | 455 return loc; |
315 } | 456 } |
316 | 457 |
317 bool ProgramInfoManager::GetActiveAttrib( | 458 bool ProgramInfoManager::GetActiveAttrib( |
318 GLES2Implementation* gl, | 459 GLES2Implementation* gl, |
319 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, | 460 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, |
320 GLint* size, GLenum* type, char* name) { | 461 GLint* size, GLenum* type, char* name) { |
321 { | 462 { |
322 base::AutoLock auto_lock(lock_); | 463 base::AutoLock auto_lock(lock_); |
323 Program* info = GetProgramInfo(gl, program); | 464 Program* info = GetProgramInfo(gl, program, kES2); |
324 if (info) { | 465 if (info) { |
325 const Program::VertexAttrib* attrib_info = info->GetAttribInfo(index); | 466 const Program::VertexAttrib* attrib_info = info->GetAttribInfo(index); |
326 if (attrib_info) { | 467 if (attrib_info) { |
327 if (size) { | 468 if (size) { |
328 *size = attrib_info->size; | 469 *size = attrib_info->size; |
329 } | 470 } |
330 if (type) { | 471 if (type) { |
331 *type = attrib_info->type; | 472 *type = attrib_info->type; |
332 } | 473 } |
333 if (length || name) { | 474 if (length || name) { |
(...skipping 15 matching lines...) Expand all Loading... |
349 return gl->GetActiveAttribHelper( | 490 return gl->GetActiveAttribHelper( |
350 program, index, bufsize, length, size, type, name); | 491 program, index, bufsize, length, size, type, name); |
351 } | 492 } |
352 | 493 |
353 bool ProgramInfoManager::GetActiveUniform( | 494 bool ProgramInfoManager::GetActiveUniform( |
354 GLES2Implementation* gl, | 495 GLES2Implementation* gl, |
355 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, | 496 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, |
356 GLint* size, GLenum* type, char* name) { | 497 GLint* size, GLenum* type, char* name) { |
357 { | 498 { |
358 base::AutoLock auto_lock(lock_); | 499 base::AutoLock auto_lock(lock_); |
359 Program* info = GetProgramInfo(gl, program); | 500 Program* info = GetProgramInfo(gl, program, kES2); |
360 if (info) { | 501 if (info) { |
361 const Program::UniformInfo* uniform_info = info->GetUniformInfo(index); | 502 const Program::UniformInfo* uniform_info = info->GetUniformInfo(index); |
362 if (uniform_info) { | 503 if (uniform_info) { |
363 if (size) { | 504 if (size) { |
364 *size = uniform_info->size; | 505 *size = uniform_info->size; |
365 } | 506 } |
366 if (type) { | 507 if (type) { |
367 *type = uniform_info->type; | 508 *type = uniform_info->type; |
368 } | 509 } |
369 if (length || name) { | 510 if (length || name) { |
370 GLsizei max_size = std::min( | 511 GLsizei max_size = std::min( |
371 static_cast<size_t>(bufsize) - 1, | 512 static_cast<size_t>(bufsize) - 1, |
372 std::max(static_cast<size_t>(0), uniform_info->name.size())); | 513 std::max(static_cast<size_t>(0), uniform_info->name.size())); |
373 if (length) { | 514 if (length) { |
374 *length = max_size; | 515 *length = max_size; |
375 } | 516 } |
376 if (name && bufsize > 0) { | 517 if (name && bufsize > 0) { |
377 memcpy(name, uniform_info->name.c_str(), max_size); | 518 memcpy(name, uniform_info->name.c_str(), max_size); |
378 name[max_size] = '\0'; | 519 name[max_size] = '\0'; |
379 } | 520 } |
380 } | 521 } |
381 return true; | 522 return true; |
382 } | 523 } |
383 } | 524 } |
384 } | 525 } |
385 return gl->GetActiveUniformHelper( | 526 return gl->GetActiveUniformHelper( |
386 program, index, bufsize, length, size, type, name); | 527 program, index, bufsize, length, size, type, name); |
387 } | 528 } |
388 | 529 |
| 530 GLuint ProgramInfoManager::GetUniformBlockIndex( |
| 531 GLES2Implementation* gl, GLuint program, const char* name) { |
| 532 { |
| 533 base::AutoLock auto_lock(lock_); |
| 534 Program* info = GetProgramInfo(gl, program, kES3UniformBlocks); |
| 535 if (info) { |
| 536 return info->GetUniformBlockIndex(name); |
| 537 } |
| 538 } |
| 539 return gl->GetUniformBlockIndexHelper(program, name); |
| 540 } |
| 541 |
| 542 bool ProgramInfoManager::GetActiveUniformBlockName( |
| 543 GLES2Implementation* gl, GLuint program, GLuint index, |
| 544 GLsizei buf_size, GLsizei* length, char* name) { |
| 545 DCHECK_LE(0, buf_size); |
| 546 if (!name) { |
| 547 buf_size = 0; |
| 548 } |
| 549 { |
| 550 base::AutoLock auto_lock(lock_); |
| 551 Program* info = GetProgramInfo(gl, program, kES3UniformBlocks); |
| 552 if (info) { |
| 553 const Program::UniformBlock* uniform_block = info->GetUniformBlock(index); |
| 554 if (uniform_block) { |
| 555 if (buf_size == 0) { |
| 556 if (length) { |
| 557 *length = 0; |
| 558 } |
| 559 } else if (length || name) { |
| 560 GLsizei max_size = std::min( |
| 561 buf_size - 1, static_cast<GLsizei>(uniform_block->name.size())); |
| 562 if (length) { |
| 563 *length = max_size; |
| 564 } |
| 565 if (name) { |
| 566 memcpy(name, uniform_block->name.data(), max_size); |
| 567 name[max_size] = '\0'; |
| 568 } |
| 569 } |
| 570 return true; |
| 571 } |
| 572 } |
| 573 } |
| 574 return gl->GetActiveUniformBlockNameHelper( |
| 575 program, index, buf_size, length, name); |
| 576 } |
| 577 |
| 578 bool ProgramInfoManager::GetActiveUniformBlockiv( |
| 579 GLES2Implementation* gl, GLuint program, GLuint index, |
| 580 GLenum pname, GLint* params) { |
| 581 { |
| 582 base::AutoLock auto_lock(lock_); |
| 583 Program* info = GetProgramInfo(gl, program, kES3UniformBlocks); |
| 584 if (info) { |
| 585 const Program::UniformBlock* uniform_block = info->GetUniformBlock(index); |
| 586 bool valid_pname; |
| 587 switch (pname) { |
| 588 case GL_UNIFORM_BLOCK_BINDING: |
| 589 case GL_UNIFORM_BLOCK_DATA_SIZE: |
| 590 case GL_UNIFORM_BLOCK_NAME_LENGTH: |
| 591 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: |
| 592 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: |
| 593 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: |
| 594 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: |
| 595 valid_pname = true; |
| 596 break; |
| 597 default: |
| 598 valid_pname = false; |
| 599 break; |
| 600 } |
| 601 if (uniform_block && valid_pname && params) { |
| 602 switch (pname) { |
| 603 case GL_UNIFORM_BLOCK_BINDING: |
| 604 *params = static_cast<GLint>(uniform_block->binding); |
| 605 break; |
| 606 case GL_UNIFORM_BLOCK_DATA_SIZE: |
| 607 *params = static_cast<GLint>(uniform_block->data_size); |
| 608 break; |
| 609 case GL_UNIFORM_BLOCK_NAME_LENGTH: |
| 610 *params = static_cast<GLint>(uniform_block->name.size()) + 1; |
| 611 break; |
| 612 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: |
| 613 *params = static_cast<GLint>( |
| 614 uniform_block->active_uniform_indices.size()); |
| 615 break; |
| 616 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: |
| 617 for (size_t ii = 0; |
| 618 ii < uniform_block->active_uniform_indices.size(); ++ii) { |
| 619 params[ii] = static_cast<GLint>( |
| 620 uniform_block->active_uniform_indices[ii]); |
| 621 } |
| 622 break; |
| 623 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: |
| 624 *params = static_cast<GLint>( |
| 625 uniform_block->referenced_by_vertex_shader); |
| 626 break; |
| 627 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: |
| 628 *params = static_cast<GLint>( |
| 629 uniform_block->referenced_by_fragment_shader); |
| 630 break; |
| 631 default: |
| 632 NOTREACHED(); |
| 633 } |
| 634 return true; |
| 635 } |
| 636 } |
| 637 } |
| 638 return false; |
| 639 // TODO(zmo): return gl->GetActiveUniformBlockivHelper( |
| 640 // program, index, pname, params); |
| 641 } |
| 642 |
389 } // namespace gles2 | 643 } // namespace gles2 |
390 } // namespace gpu | 644 } // namespace gpu |
391 | 645 |
OLD | NEW |