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 #include <map> | 7 #include <map> |
8 | 8 |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 #include "base/synchronization/lock.h" | 10 #include "base/synchronization/lock.h" |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 return (static_cast<size_t>(index) < uniform_infos_.size()) ? | 187 return (static_cast<size_t>(index) < uniform_infos_.size()) ? |
188 &uniform_infos_[index] : NULL; | 188 &uniform_infos_[index] : NULL; |
189 } | 189 } |
190 | 190 |
191 // Gets the location of a uniform by name. | 191 // Gets the location of a uniform by name. |
192 GLint GetUniformLocation(const std::string& name) const; | 192 GLint GetUniformLocation(const std::string& name) const; |
193 | 193 |
194 bool GetProgramiv(GLenum pname, GLint* params); | 194 bool GetProgramiv(GLenum pname, GLint* params); |
195 | 195 |
196 // Updates the program info after a successful link. | 196 // Updates the program info after a successful link. |
197 void Update(GLES2Implementation* gl, GLuint program); | 197 void Update(GLES2Implementation* gl, |
| 198 GLuint program, |
| 199 const std::vector<int8>& result); |
| 200 |
| 201 bool cached() const { return cached_; } |
198 | 202 |
199 private: | 203 private: |
200 bool cached_; | 204 bool cached_; |
201 | 205 |
202 GLsizei max_attrib_name_length_; | 206 GLsizei max_attrib_name_length_; |
203 | 207 |
204 // Attrib by index. | 208 // Attrib by index. |
205 AttribInfoVector attrib_infos_; | 209 AttribInfoVector attrib_infos_; |
206 | 210 |
207 GLsizei max_uniform_name_length_; | 211 GLsizei max_uniform_name_length_; |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 const std::vector<int8>& data, uint32 offset, size_t size) { | 312 const std::vector<int8>& data, uint32 offset, size_t size) { |
309 const int8* p = &data[0] + offset; | 313 const int8* p = &data[0] + offset; |
310 if (offset + size > data.size()) { | 314 if (offset + size > data.size()) { |
311 NOTREACHED(); | 315 NOTREACHED(); |
312 return NULL; | 316 return NULL; |
313 } | 317 } |
314 return static_cast<T>(static_cast<const void*>(p)); | 318 return static_cast<T>(static_cast<const void*>(p)); |
315 } | 319 } |
316 | 320 |
317 void CachedProgramInfoManager::Program::Update( | 321 void CachedProgramInfoManager::Program::Update( |
318 GLES2Implementation* gl, GLuint program) { | 322 GLES2Implementation* gl, |
| 323 GLuint program, |
| 324 const std::vector<int8>& result) { |
319 if (cached_) { | 325 if (cached_) { |
320 return; | 326 return; |
321 } | 327 } |
322 std::vector<int8> result; | |
323 gl->GetProgramInfoCHROMIUMHelper(program, &result); | |
324 if (result.empty()) { | 328 if (result.empty()) { |
325 // This should only happen on a lost context. | 329 // This should only happen on a lost context. |
326 return; | 330 return; |
327 } | 331 } |
328 DCHECK_GE(result.size(), sizeof(ProgramInfoHeader)); | 332 DCHECK_GE(result.size(), sizeof(ProgramInfoHeader)); |
329 const ProgramInfoHeader* header = LocalGetAs<const ProgramInfoHeader*>( | 333 const ProgramInfoHeader* header = LocalGetAs<const ProgramInfoHeader*>( |
330 result, 0, sizeof(header)); | 334 result, 0, sizeof(header)); |
331 link_status_ = header->link_status != 0; | 335 link_status_ = header->link_status != 0; |
332 if (!link_status_) { | 336 if (!link_status_) { |
333 return; | 337 return; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 | 385 |
382 CachedProgramInfoManager::Program* | 386 CachedProgramInfoManager::Program* |
383 CachedProgramInfoManager::GetProgramInfo( | 387 CachedProgramInfoManager::GetProgramInfo( |
384 GLES2Implementation* gl, GLuint program) { | 388 GLES2Implementation* gl, GLuint program) { |
385 lock_.AssertAcquired(); | 389 lock_.AssertAcquired(); |
386 ProgramInfoMap::iterator it = program_infos_.find(program); | 390 ProgramInfoMap::iterator it = program_infos_.find(program); |
387 if (it == program_infos_.end()) { | 391 if (it == program_infos_.end()) { |
388 return NULL; | 392 return NULL; |
389 } | 393 } |
390 Program* info = &it->second; | 394 Program* info = &it->second; |
391 info->Update(gl, program); | 395 if (info->cached()) |
| 396 return info; |
| 397 std::vector<int8> result; |
| 398 { |
| 399 base::AutoUnlock unlock(lock_); |
| 400 // lock_ can't be held across IPC call or else it may deadlock in pepper. |
| 401 // http://crbug.com/418651 |
| 402 gl->GetProgramInfoCHROMIUMHelper(program, &result); |
| 403 } |
| 404 |
| 405 it = program_infos_.find(program); |
| 406 if (it == program_infos_.end()) { |
| 407 return NULL; |
| 408 } |
| 409 info = &it->second; |
| 410 info->Update(gl, program, result); |
392 return info; | 411 return info; |
393 } | 412 } |
394 | 413 |
395 void CachedProgramInfoManager::CreateInfo(GLuint program) { | 414 void CachedProgramInfoManager::CreateInfo(GLuint program) { |
396 base::AutoLock auto_lock(lock_); | 415 base::AutoLock auto_lock(lock_); |
397 program_infos_.erase(program); | 416 program_infos_.erase(program); |
398 std::pair<ProgramInfoMap::iterator, bool> result = | 417 std::pair<ProgramInfoMap::iterator, bool> result = |
399 program_infos_.insert(std::make_pair(program, Program())); | 418 program_infos_.insert(std::make_pair(program, Program())); |
400 | 419 |
401 DCHECK(result.second); | 420 DCHECK(result.second); |
402 } | 421 } |
403 | 422 |
404 void CachedProgramInfoManager::DeleteInfo(GLuint program) { | 423 void CachedProgramInfoManager::DeleteInfo(GLuint program) { |
405 base::AutoLock auto_lock(lock_); | 424 base::AutoLock auto_lock(lock_); |
406 program_infos_.erase(program); | 425 program_infos_.erase(program); |
407 } | 426 } |
408 | 427 |
409 bool CachedProgramInfoManager::GetProgramiv( | 428 bool CachedProgramInfoManager::GetProgramiv( |
410 GLES2Implementation* gl, GLuint program, GLenum pname, GLint* params) { | 429 GLES2Implementation* gl, GLuint program, GLenum pname, GLint* params) { |
411 base::AutoLock auto_lock(lock_); | 430 base::AutoLock auto_lock(lock_); |
412 Program* info = GetProgramInfo(gl, program); | 431 Program* info = GetProgramInfo(gl, program); |
413 if (!info) { | 432 if (!info) { |
414 return false; | 433 return false; |
415 } | 434 } |
416 return info->GetProgramiv(pname, params); | 435 return info->GetProgramiv(pname, params); |
417 } | 436 } |
418 | 437 |
419 GLint CachedProgramInfoManager::GetAttribLocation( | 438 GLint CachedProgramInfoManager::GetAttribLocation( |
420 GLES2Implementation* gl, GLuint program, const char* name) { | 439 GLES2Implementation* gl, GLuint program, const char* name) { |
421 base::AutoLock auto_lock(lock_); | 440 { |
422 Program* info = GetProgramInfo(gl, program); | 441 base::AutoLock auto_lock(lock_); |
423 if (info) { | 442 Program* info = GetProgramInfo(gl, program); |
424 return info->GetAttribLocation(name); | 443 if (info) { |
| 444 return info->GetAttribLocation(name); |
| 445 } |
425 } | 446 } |
426 return gl->GetAttribLocationHelper(program, name); | 447 return gl->GetAttribLocationHelper(program, name); |
427 } | 448 } |
428 | 449 |
429 GLint CachedProgramInfoManager::GetUniformLocation( | 450 GLint CachedProgramInfoManager::GetUniformLocation( |
430 GLES2Implementation* gl, GLuint program, const char* name) { | 451 GLES2Implementation* gl, GLuint program, const char* name) { |
431 base::AutoLock auto_lock(lock_); | 452 { |
432 Program* info = GetProgramInfo(gl, program); | 453 base::AutoLock auto_lock(lock_); |
433 if (info) { | 454 Program* info = GetProgramInfo(gl, program); |
434 return info->GetUniformLocation(name); | 455 if (info) { |
| 456 return info->GetUniformLocation(name); |
| 457 } |
435 } | 458 } |
436 return gl->GetUniformLocationHelper(program, name); | 459 return gl->GetUniformLocationHelper(program, name); |
437 } | 460 } |
438 | 461 |
439 bool CachedProgramInfoManager::GetActiveAttrib( | 462 bool CachedProgramInfoManager::GetActiveAttrib( |
440 GLES2Implementation* gl, | 463 GLES2Implementation* gl, |
441 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, | 464 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, |
442 GLint* size, GLenum* type, char* name) { | 465 GLint* size, GLenum* type, char* name) { |
443 base::AutoLock auto_lock(lock_); | 466 { |
444 Program* info = GetProgramInfo(gl, program); | 467 base::AutoLock auto_lock(lock_); |
445 if (info) { | 468 Program* info = GetProgramInfo(gl, program); |
446 const Program::VertexAttrib* attrib_info = | 469 if (info) { |
447 info->GetAttribInfo(index); | 470 const Program::VertexAttrib* attrib_info = info->GetAttribInfo(index); |
448 if (attrib_info) { | 471 if (attrib_info) { |
449 if (size) { | 472 if (size) { |
450 *size = attrib_info->size; | 473 *size = attrib_info->size; |
| 474 } |
| 475 if (type) { |
| 476 *type = attrib_info->type; |
| 477 } |
| 478 if (length || name) { |
| 479 GLsizei max_size = std::min( |
| 480 static_cast<size_t>(bufsize) - 1, |
| 481 std::max(static_cast<size_t>(0), attrib_info->name.size())); |
| 482 if (length) { |
| 483 *length = max_size; |
| 484 } |
| 485 if (name && bufsize > 0) { |
| 486 memcpy(name, attrib_info->name.c_str(), max_size); |
| 487 name[max_size] = '\0'; |
| 488 } |
| 489 } |
| 490 return true; |
451 } | 491 } |
452 if (type) { | |
453 *type = attrib_info->type; | |
454 } | |
455 if (length || name) { | |
456 GLsizei max_size = std::min(static_cast<size_t>(bufsize) - 1, | |
457 std::max(static_cast<size_t>(0), | |
458 attrib_info->name.size())); | |
459 if (length) { | |
460 *length = max_size; | |
461 } | |
462 if (name && bufsize > 0) { | |
463 memcpy(name, attrib_info->name.c_str(), max_size); | |
464 name[max_size] = '\0'; | |
465 } | |
466 } | |
467 return true; | |
468 } | 492 } |
469 } | 493 } |
470 return gl->GetActiveAttribHelper( | 494 return gl->GetActiveAttribHelper( |
471 program, index, bufsize, length, size, type, name); | 495 program, index, bufsize, length, size, type, name); |
472 } | 496 } |
473 | 497 |
474 bool CachedProgramInfoManager::GetActiveUniform( | 498 bool CachedProgramInfoManager::GetActiveUniform( |
475 GLES2Implementation* gl, | 499 GLES2Implementation* gl, |
476 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, | 500 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, |
477 GLint* size, GLenum* type, char* name) { | 501 GLint* size, GLenum* type, char* name) { |
478 base::AutoLock auto_lock(lock_); | 502 { |
479 Program* info = GetProgramInfo(gl, program); | 503 base::AutoLock auto_lock(lock_); |
480 if (info) { | 504 Program* info = GetProgramInfo(gl, program); |
481 const Program::UniformInfo* uniform_info = info->GetUniformInfo(index); | 505 if (info) { |
482 if (uniform_info) { | 506 const Program::UniformInfo* uniform_info = info->GetUniformInfo(index); |
483 if (size) { | 507 if (uniform_info) { |
484 *size = uniform_info->size; | 508 if (size) { |
| 509 *size = uniform_info->size; |
| 510 } |
| 511 if (type) { |
| 512 *type = uniform_info->type; |
| 513 } |
| 514 if (length || name) { |
| 515 GLsizei max_size = std::min( |
| 516 static_cast<size_t>(bufsize) - 1, |
| 517 std::max(static_cast<size_t>(0), uniform_info->name.size())); |
| 518 if (length) { |
| 519 *length = max_size; |
| 520 } |
| 521 if (name && bufsize > 0) { |
| 522 memcpy(name, uniform_info->name.c_str(), max_size); |
| 523 name[max_size] = '\0'; |
| 524 } |
| 525 } |
| 526 return true; |
485 } | 527 } |
486 if (type) { | |
487 *type = uniform_info->type; | |
488 } | |
489 if (length || name) { | |
490 GLsizei max_size = std::min(static_cast<size_t>(bufsize) - 1, | |
491 std::max(static_cast<size_t>(0), | |
492 uniform_info->name.size())); | |
493 if (length) { | |
494 *length = max_size; | |
495 } | |
496 if (name && bufsize > 0) { | |
497 memcpy(name, uniform_info->name.c_str(), max_size); | |
498 name[max_size] = '\0'; | |
499 } | |
500 } | |
501 return true; | |
502 } | 528 } |
503 } | 529 } |
504 return gl->GetActiveUniformHelper( | 530 return gl->GetActiveUniformHelper( |
505 program, index, bufsize, length, size, type, name); | 531 program, index, bufsize, length, size, type, name); |
506 } | 532 } |
507 | 533 |
508 ProgramInfoManager::ProgramInfoManager() { | 534 ProgramInfoManager::ProgramInfoManager() { |
509 } | 535 } |
510 | 536 |
511 ProgramInfoManager::~ProgramInfoManager() { | 537 ProgramInfoManager::~ProgramInfoManager() { |
512 } | 538 } |
513 | 539 |
514 ProgramInfoManager* ProgramInfoManager::Create( | 540 ProgramInfoManager* ProgramInfoManager::Create( |
515 bool shared_resources_across_processes) { | 541 bool shared_resources_across_processes) { |
516 if (shared_resources_across_processes) { | 542 if (shared_resources_across_processes) { |
517 return new NonCachedProgramInfoManager(); | 543 return new NonCachedProgramInfoManager(); |
518 } else { | 544 } else { |
519 return new CachedProgramInfoManager(); | 545 return new CachedProgramInfoManager(); |
520 } | 546 } |
521 } | 547 } |
522 | 548 |
523 } // namespace gles2 | 549 } // namespace gles2 |
524 } // namespace gpu | 550 } // namespace gpu |
525 | 551 |
OLD | NEW |