| 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 |