| 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" |
| 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" |
| 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) |
| 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); |
| 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, |
| 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], |
| 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 |
| 403 if(link) { |
| 404 glLinkProgram(service_id()); |
| 405 } |
| 406 |
| 298 GLint success = 0; | 407 GLint success = 0; |
| 299 glGetProgramiv(service_id(), GL_LINK_STATUS, &success); | 408 glGetProgramiv(service_id(), GL_LINK_STATUS, &success); |
| 300 if (success == GL_TRUE) { | 409 if (success == GL_TRUE) { |
| 301 Update(); | 410 Update(); |
| 411 if(cache && link) { |
| 412 cache->SaveLinkedProgram(service_id(), |
| 413 attached_shaders_[0], |
| 414 attached_shaders_[1], |
| 415 &bind_attrib_location_map_); |
| 416 |
| 417 } |
| 302 } else { | 418 } else { |
| 303 UpdateLogInfo(); | 419 UpdateLogInfo(); |
| 304 } | 420 } |
| 305 return success == GL_TRUE; | 421 return success == GL_TRUE; |
| 306 } | 422 } |
| 307 | 423 |
| 308 void ProgramManager::ProgramInfo::Validate() { | 424 void ProgramManager::ProgramInfo::Validate() { |
| 309 if (!IsValid()) { | 425 if (!IsValid()) { |
| 310 set_log_info("program not linked"); | 426 set_log_info("program not linked"); |
| 311 return; | 427 return; |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 ProgramManager::ProgramInfo::~ProgramInfo() { | 818 ProgramManager::ProgramInfo::~ProgramInfo() { |
| 703 if (manager_) { | 819 if (manager_) { |
| 704 if (manager_->have_context_) { | 820 if (manager_->have_context_) { |
| 705 glDeleteProgram(service_id()); | 821 glDeleteProgram(service_id()); |
| 706 } | 822 } |
| 707 manager_->StopTracking(this); | 823 manager_->StopTracking(this); |
| 708 manager_ = NULL; | 824 manager_ = NULL; |
| 709 } | 825 } |
| 710 } | 826 } |
| 711 | 827 |
| 712 ProgramManager::ProgramManager() | 828 |
| 829 ProgramManager::ProgramManager(ProgramCache* program_cache) |
| 713 : program_info_count_(0), | 830 : program_info_count_(0), |
| 714 have_context_(true), | 831 have_context_(true), |
| 715 disable_workarounds_( | 832 disable_workarounds_( |
| 716 CommandLine::ForCurrentProcess()->HasSwitch( | 833 CommandLine::ForCurrentProcess()->HasSwitch( |
| 717 switches::kDisableGpuDriverBugWorkarounds)) { | 834 switches::kDisableGpuDriverBugWorkarounds)), |
| 718 } | 835 program_cache_(program_cache){ } |
| 719 | 836 |
| 720 ProgramManager::~ProgramManager() { | 837 ProgramManager::~ProgramManager() { |
| 721 DCHECK(program_infos_.empty()); | 838 DCHECK(program_infos_.empty()); |
| 722 } | 839 } |
| 723 | 840 |
| 724 void ProgramManager::Destroy(bool have_context) { | 841 void ProgramManager::Destroy(bool have_context) { |
| 725 have_context_ = have_context; | 842 have_context_ = have_context; |
| 726 program_infos_.clear(); | 843 program_infos_.clear(); |
| 727 } | 844 } |
| 728 | 845 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 754 for (ProgramInfoMap::const_iterator it = program_infos_.begin(); | 871 for (ProgramInfoMap::const_iterator it = program_infos_.begin(); |
| 755 it != program_infos_.end(); ++it) { | 872 it != program_infos_.end(); ++it) { |
| 756 if (it->second->service_id() == service_id) { | 873 if (it->second->service_id() == service_id) { |
| 757 *client_id = it->first; | 874 *client_id = it->first; |
| 758 return true; | 875 return true; |
| 759 } | 876 } |
| 760 } | 877 } |
| 761 return false; | 878 return false; |
| 762 } | 879 } |
| 763 | 880 |
| 881 ProgramCache* ProgramManager::program_cache() const { |
| 882 return program_cache_; |
| 883 } |
| 884 |
| 764 bool ProgramManager::IsOwned(ProgramManager::ProgramInfo* info) { | 885 bool ProgramManager::IsOwned(ProgramManager::ProgramInfo* info) { |
| 765 for (ProgramInfoMap::iterator it = program_infos_.begin(); | 886 for (ProgramInfoMap::iterator it = program_infos_.begin(); |
| 766 it != program_infos_.end(); ++it) { | 887 it != program_infos_.end(); ++it) { |
| 767 if (it->second.get() == info) { | 888 if (it->second.get() == info) { |
| 768 return true; | 889 return true; |
| 769 } | 890 } |
| 770 } | 891 } |
| 771 return false; | 892 return false; |
| 772 } | 893 } |
| 773 | 894 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 820 DCHECK(info); | 941 DCHECK(info); |
| 821 if (!disable_workarounds_) { | 942 if (!disable_workarounds_) { |
| 822 info->ClearUniforms(&zero_); | 943 info->ClearUniforms(&zero_); |
| 823 } | 944 } |
| 824 } | 945 } |
| 825 | 946 |
| 826 } // namespace gles2 | 947 } // namespace gles2 |
| 827 } // namespace gpu | 948 } // namespace gpu |
| 828 | 949 |
| 829 | 950 |
| OLD | NEW |