Chromium Code Reviews| 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/service/program_manager.h" | 5 #include "gpu/command_buffer/service/program_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
| 12 #include "base/bind.h" | |
|
greggman
2012/06/26 23:00:27
is this include needed?
| |
| 12 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 13 #include "base/logging.h" | 14 #include "base/logging.h" |
| 14 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
| 15 #include "base/string_number_conversions.h" | 16 #include "base/string_number_conversions.h" |
| 17 #include "net/base/net_log.h" | |
|
greggman
2012/06/26 23:00:27
is this include needed?
| |
| 16 #include "gpu/command_buffer/common/gles2_cmd_format.h" | 18 #include "gpu/command_buffer/common/gles2_cmd_format.h" |
| 17 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 19 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
| 18 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 20 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| 19 #include "gpu/command_buffer/service/gpu_switches.h" | 21 #include "gpu/command_buffer/service/gpu_switches.h" |
| 20 | 22 |
| 21 namespace gpu { | 23 namespace gpu { |
| 22 namespace gles2 { | 24 namespace gles2 { |
| 23 | 25 |
| 24 static int ShaderTypeToIndex(GLenum shader_type) { | 26 static int ShaderTypeToIndex(GLenum shader_type) { |
| 25 switch (shader_type) { | 27 switch (shader_type) { |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 276 void ProgramManager::ProgramInfo::ExecuteBindAttribLocationCalls() { | 278 void ProgramManager::ProgramInfo::ExecuteBindAttribLocationCalls() { |
| 277 for (std::map<std::string, GLint>::const_iterator it = | 279 for (std::map<std::string, GLint>::const_iterator it = |
| 278 bind_attrib_location_map_.begin(); | 280 bind_attrib_location_map_.begin(); |
| 279 it != bind_attrib_location_map_.end(); ++it) { | 281 it != bind_attrib_location_map_.end(); ++it) { |
| 280 const std::string* mapped_name = GetAttribMappedName(it->first); | 282 const std::string* mapped_name = GetAttribMappedName(it->first); |
| 281 if (mapped_name && *mapped_name != it->first) | 283 if (mapped_name && *mapped_name != it->first) |
| 282 glBindAttribLocation(service_id_, it->second, mapped_name->c_str()); | 284 glBindAttribLocation(service_id_, it->second, mapped_name->c_str()); |
| 283 } | 285 } |
| 284 } | 286 } |
| 285 | 287 |
| 286 bool ProgramManager::ProgramInfo::Link() { | 288 void ProgramManager::DoCompileShader(ShaderManager::ShaderInfo* info, |
| 289 ShaderTranslator* translator, | |
| 290 FeatureInfo* feature_info) { | |
| 291 // Translate GL ES 2.0 shader to Desktop GL shader and pass that to | |
| 292 // glShaderSource and then glCompileShader. | |
| 293 const char* shader_src = info->source() ? info->source()->c_str() : ""; | |
| 294 if (translator) { | |
| 295 if (!translator->Translate(shader_src)) { | |
| 296 info->SetStatus(false, translator->info_log(), NULL); | |
| 297 return; | |
| 298 } | |
| 299 shader_src = translator->translated_shader(); | |
| 300 if (!feature_info->feature_flags().angle_translated_shader_source) | |
|
greggman
2012/06/26 23:00:27
ugh: please add a new issue. We need to either cac
dmurph
2012/07/04 00:01:29
Hm, okay then I'll leave this alone? Should the i
| |
| 301 info->UpdateTranslatedSource(shader_src); | |
| 302 } | |
| 303 | |
| 304 glShaderSource(info->service_id(), 1, &shader_src, NULL); | |
| 305 glCompileShader(info->service_id()); | |
| 306 if (feature_info->feature_flags().angle_translated_shader_source) { | |
| 307 GLint max_len = 0; | |
| 308 glGetShaderiv(info->service_id(), | |
| 309 GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE, | |
| 310 &max_len); | |
| 311 scoped_array<char> temp(new char[max_len]); | |
| 312 GLint len = 0; | |
| 313 glGetTranslatedShaderSourceANGLE( | |
| 314 info->service_id(), max_len, &len, temp.get()); | |
| 315 DCHECK(max_len == 0 || len < max_len); | |
| 316 DCHECK(len == 0 || temp[len] == '\0'); | |
| 317 info->UpdateTranslatedSource(temp.get()); | |
| 318 } | |
| 319 | |
| 320 GLint status = GL_FALSE; | |
| 321 glGetShaderiv(info->service_id(), GL_COMPILE_STATUS, &status); | |
|
greggman
2012/06/26 23:00:27
style: I'm sure this was just copied and passed bu
dmurph
2012/07/04 00:01:29
Done.
| |
| 322 if (status) { | |
| 323 info->SetStatus(true, "", translator); | |
| 324 if (program_cache_) { | |
| 325 program_cache_->ShaderCompilationSucceeded(*info->source()); | |
| 326 } | |
| 327 } else { | |
| 328 // We cannot reach here if we are using the shader translator. | |
| 329 // All invalid shaders must be rejected by the translator. | |
| 330 // All translated shaders must compile. | |
| 331 LOG_IF(ERROR, translator) | |
| 332 << "Shader translator allowed/produced an invalid shader."; | |
| 333 GLint max_len = 0; | |
| 334 glGetShaderiv(info->service_id(), GL_INFO_LOG_LENGTH, &max_len); | |
| 335 scoped_array<char> temp(new char[max_len]); | |
| 336 GLint len = 0; | |
| 337 glGetShaderInfoLog(info->service_id(), max_len, &len, temp.get()); | |
| 338 DCHECK(max_len == 0 || len < max_len); | |
| 339 DCHECK(len == 0 || temp[len] == '\0'); | |
| 340 info->SetStatus(false, std::string(temp.get(), len).c_str(), NULL); | |
| 341 } | |
| 342 } | |
| 343 | |
| 344 bool ProgramManager::ProgramInfo::Link(ShaderManager* manager, | |
| 345 ShaderTranslator* vertex_translator, | |
| 346 ShaderTranslator* fragment_shader, | |
| 347 FeatureInfo* feature_info) { | |
| 287 ClearLinkStatus(); | 348 ClearLinkStatus(); |
| 288 if (!CanLink()) { | 349 if (!CanLink()) { |
| 289 set_log_info("missing shaders"); | 350 set_log_info("missing shaders"); |
| 290 return false; | 351 return false; |
| 291 } | 352 } |
| 292 if (DetectAttribLocationBindingConflicts()) { | 353 if (DetectAttribLocationBindingConflicts()) { |
| 293 set_log_info("glBindAttribLocation() conflicts"); | 354 set_log_info("glBindAttribLocation() conflicts"); |
| 294 return false; | 355 return false; |
| 295 } | 356 } |
| 296 ExecuteBindAttribLocationCalls(); | 357 ExecuteBindAttribLocationCalls(); |
| 297 glLinkProgram(service_id()); | 358 |
| 359 bool link = true; | |
| 360 ProgramCache* cache = manager_->program_cache_; | |
| 361 const std::string* shader_a = attached_shaders_[0]->source(); | |
| 362 const std::string* shader_b = attached_shaders_[1]->source(); | |
| 363 if (cache) { | |
| 364 ProgramCache::LinkedProgramStatus status = cache->GetLinkedProgramStatus( | |
| 365 *shader_a, | |
|
greggman
2012/06/26 23:00:27
style: indenting
dmurph
2012/07/04 00:01:29
Done.
| |
| 366 *shader_b, | |
| 367 &bind_attrib_location_map_); | |
| 368 switch (status) { | |
| 369 case ProgramCache::LINK_SUCCEEDED: { | |
| 370 bool success = cache->LoadLinkedProgram(service_id(), | |
| 371 attached_shaders_[0], | |
| 372 attached_shaders_[1], | |
| 373 &bind_attrib_location_map_); | |
| 374 if (success) { | |
| 375 link = false; | |
| 376 break; | |
| 377 } | |
| 378 } // fall through | |
| 379 case ProgramCache::LINK_UNKNOWN: | |
| 380 // compile our shaders + attach | |
| 381 if (attached_shaders_[0]->IsPendingCacheMissCompilation()) { | |
| 382 manager_->DoCompileShader(attached_shaders_[0], | |
|
greggman
2012/06/26 23:00:27
this code is repeated pretty much repeated twice.
dmurph
2012/07/04 00:01:29
Done.
| |
| 383 vertex_translator, | |
| 384 feature_info); | |
| 385 AttachShader(manager, attached_shaders_[0]); | |
| 386 glAttachShader(service_id(), attached_shaders_[0]->service_id()); | |
| 387 attached_shaders_[0]->SetPendingCompilation(false); | |
| 388 } | |
| 389 if (attached_shaders_[1]->IsPendingCacheMissCompilation()) { | |
| 390 manager_->DoCompileShader(attached_shaders_[1], | |
| 391 fragment_shader, | |
| 392 feature_info); | |
| 393 AttachShader(manager, attached_shaders_[1]); | |
| 394 glAttachShader(service_id(), attached_shaders_[1]->service_id()); | |
| 395 attached_shaders_[1]->SetPendingCompilation(false); | |
| 396 } | |
| 397 link = true; | |
| 398 break; | |
| 399 } | |
| 400 } | |
| 401 | |
| 402 if (link) { | |
| 403 glLinkProgram(service_id()); | |
| 404 } | |
| 405 | |
| 298 GLint success = 0; | 406 GLint success = 0; |
| 299 glGetProgramiv(service_id(), GL_LINK_STATUS, &success); | 407 glGetProgramiv(service_id(), GL_LINK_STATUS, &success); |
| 300 if (success == GL_TRUE) { | 408 if (success == GL_TRUE) { |
| 301 Update(); | 409 Update(); |
| 410 if (cache && link) { | |
| 411 cache->SaveLinkedProgram(service_id(), | |
| 412 attached_shaders_[0], | |
| 413 attached_shaders_[1], | |
| 414 &bind_attrib_location_map_); | |
| 415 } | |
| 302 } else { | 416 } else { |
| 303 UpdateLogInfo(); | 417 UpdateLogInfo(); |
| 304 } | 418 } |
| 305 return success == GL_TRUE; | 419 return success == GL_TRUE; |
| 306 } | 420 } |
| 307 | 421 |
| 308 void ProgramManager::ProgramInfo::Validate() { | 422 void ProgramManager::ProgramInfo::Validate() { |
| 309 if (!IsValid()) { | 423 if (!IsValid()) { |
| 310 set_log_info("program not linked"); | 424 set_log_info("program not linked"); |
| 311 return; | 425 return; |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 702 ProgramManager::ProgramInfo::~ProgramInfo() { | 816 ProgramManager::ProgramInfo::~ProgramInfo() { |
| 703 if (manager_) { | 817 if (manager_) { |
| 704 if (manager_->have_context_) { | 818 if (manager_->have_context_) { |
| 705 glDeleteProgram(service_id()); | 819 glDeleteProgram(service_id()); |
| 706 } | 820 } |
| 707 manager_->StopTracking(this); | 821 manager_->StopTracking(this); |
| 708 manager_ = NULL; | 822 manager_ = NULL; |
| 709 } | 823 } |
| 710 } | 824 } |
| 711 | 825 |
| 712 ProgramManager::ProgramManager() | 826 |
| 827 ProgramManager::ProgramManager(ProgramCache* program_cache) | |
| 713 : program_info_count_(0), | 828 : program_info_count_(0), |
| 714 have_context_(true), | 829 have_context_(true), |
| 715 disable_workarounds_( | 830 disable_workarounds_( |
| 716 CommandLine::ForCurrentProcess()->HasSwitch( | 831 CommandLine::ForCurrentProcess()->HasSwitch( |
| 717 switches::kDisableGpuDriverBugWorkarounds)) { | 832 switches::kDisableGpuDriverBugWorkarounds)), |
| 718 } | 833 program_cache_(program_cache) { } |
| 719 | 834 |
| 720 ProgramManager::~ProgramManager() { | 835 ProgramManager::~ProgramManager() { |
| 721 DCHECK(program_infos_.empty()); | 836 DCHECK(program_infos_.empty()); |
| 722 } | 837 } |
| 723 | 838 |
| 724 void ProgramManager::Destroy(bool have_context) { | 839 void ProgramManager::Destroy(bool have_context) { |
| 725 have_context_ = have_context; | 840 have_context_ = have_context; |
| 726 program_infos_.clear(); | 841 program_infos_.clear(); |
| 727 } | 842 } |
| 728 | 843 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 754 for (ProgramInfoMap::const_iterator it = program_infos_.begin(); | 869 for (ProgramInfoMap::const_iterator it = program_infos_.begin(); |
| 755 it != program_infos_.end(); ++it) { | 870 it != program_infos_.end(); ++it) { |
| 756 if (it->second->service_id() == service_id) { | 871 if (it->second->service_id() == service_id) { |
| 757 *client_id = it->first; | 872 *client_id = it->first; |
| 758 return true; | 873 return true; |
| 759 } | 874 } |
| 760 } | 875 } |
| 761 return false; | 876 return false; |
| 762 } | 877 } |
| 763 | 878 |
| 879 ProgramCache* ProgramManager::program_cache() const { | |
| 880 return program_cache_; | |
| 881 } | |
| 882 | |
| 764 bool ProgramManager::IsOwned(ProgramManager::ProgramInfo* info) { | 883 bool ProgramManager::IsOwned(ProgramManager::ProgramInfo* info) { |
| 765 for (ProgramInfoMap::iterator it = program_infos_.begin(); | 884 for (ProgramInfoMap::iterator it = program_infos_.begin(); |
| 766 it != program_infos_.end(); ++it) { | 885 it != program_infos_.end(); ++it) { |
| 767 if (it->second.get() == info) { | 886 if (it->second.get() == info) { |
| 768 return true; | 887 return true; |
| 769 } | 888 } |
| 770 } | 889 } |
| 771 return false; | 890 return false; |
| 772 } | 891 } |
| 773 | 892 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 820 DCHECK(info); | 939 DCHECK(info); |
| 821 if (!disable_workarounds_) { | 940 if (!disable_workarounds_) { |
| 822 info->ClearUniforms(&zero_); | 941 info->ClearUniforms(&zero_); |
| 823 } | 942 } |
| 824 } | 943 } |
| 825 | 944 |
| 826 } // namespace gles2 | 945 } // namespace gles2 |
| 827 } // namespace gpu | 946 } // namespace gpu |
| 828 | 947 |
| 829 | 948 |
| OLD | NEW |