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 <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
| 16 #include "base/metrics/histogram.h" |
16 #include "base/string_number_conversions.h" | 17 #include "base/string_number_conversions.h" |
| 18 #include "base/time.h" |
17 #include "gpu/command_buffer/common/gles2_cmd_format.h" | 19 #include "gpu/command_buffer/common/gles2_cmd_format.h" |
18 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 20 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
19 #include "gpu/command_buffer/service/feature_info.h" | 21 #include "gpu/command_buffer/service/feature_info.h" |
20 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 22 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
21 #include "gpu/command_buffer/service/gpu_switches.h" | 23 #include "gpu/command_buffer/service/gpu_switches.h" |
22 #include "gpu/command_buffer/service/program_cache.h" | 24 #include "gpu/command_buffer/service/program_cache.h" |
23 | 25 |
| 26 using base::TimeDelta; |
| 27 |
24 namespace gpu { | 28 namespace gpu { |
25 namespace gles2 { | 29 namespace gles2 { |
26 | 30 |
27 namespace { | 31 namespace { |
28 | 32 |
29 int ShaderTypeToIndex(GLenum shader_type) { | 33 int ShaderTypeToIndex(GLenum shader_type) { |
30 switch (shader_type) { | 34 switch (shader_type) { |
31 case GL_VERTEX_SHADER: | 35 case GL_VERTEX_SHADER: |
32 return 0; | 36 return 0; |
33 case GL_FRAGMENT_SHADER: | 37 case GL_FRAGMENT_SHADER: |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 it != bind_attrib_location_map_.end(); ++it) { | 378 it != bind_attrib_location_map_.end(); ++it) { |
375 const std::string* mapped_name = GetAttribMappedName(it->first); | 379 const std::string* mapped_name = GetAttribMappedName(it->first); |
376 if (mapped_name && *mapped_name != it->first) | 380 if (mapped_name && *mapped_name != it->first) |
377 glBindAttribLocation(service_id_, it->second, mapped_name->c_str()); | 381 glBindAttribLocation(service_id_, it->second, mapped_name->c_str()); |
378 } | 382 } |
379 } | 383 } |
380 | 384 |
381 void ProgramManager::DoCompileShader(ShaderManager::ShaderInfo* info, | 385 void ProgramManager::DoCompileShader(ShaderManager::ShaderInfo* info, |
382 ShaderTranslator* translator, | 386 ShaderTranslator* translator, |
383 FeatureInfo* feature_info) { | 387 FeatureInfo* feature_info) { |
| 388 base::Time before = base::Time::Now(); |
384 if (program_cache_ && | 389 if (program_cache_ && |
385 program_cache_->GetShaderCompilationStatus(info->source() ? | 390 program_cache_->GetShaderCompilationStatus(info->source() ? |
386 *info->source() : "") == | 391 *info->source() : "") == |
387 ProgramCache::COMPILATION_SUCCEEDED) { | 392 ProgramCache::COMPILATION_SUCCEEDED) { |
388 info->SetStatus(true, "", translator); | 393 info->SetStatus(true, "", translator); |
389 info->FlagSourceAsCompiled(false); | 394 info->FlagSourceAsCompiled(false); |
| 395 HISTOGRAM_CUSTOM_COUNTS("GPU.ProgramCache.CompilationCacheHitTime", |
| 396 (base::Time::Now() - before).InMicroseconds(), |
| 397 100, |
| 398 TimeDelta::FromSeconds(1).InMicroseconds(), |
| 399 50); |
390 return; | 400 return; |
391 } | 401 } |
392 ForceCompileShader(info->source(), info, translator, feature_info); | 402 ForceCompileShader(info->source(), info, translator, feature_info); |
| 403 HISTOGRAM_CUSTOM_COUNTS("GPU.ProgramCache.CompilationCacheMissTime", |
| 404 (base::Time::Now() - before).InMicroseconds(), |
| 405 100, |
| 406 TimeDelta::FromSeconds(1).InMicroseconds(), |
| 407 50); |
393 } | 408 } |
394 | 409 |
395 void ProgramManager::ForceCompileShader(const std::string* source, | 410 void ProgramManager::ForceCompileShader(const std::string* source, |
396 ShaderManager::ShaderInfo* info, | 411 ShaderManager::ShaderInfo* info, |
397 ShaderTranslator* translator, | 412 ShaderTranslator* translator, |
398 FeatureInfo* feature_info) { | 413 FeatureInfo* feature_info) { |
399 info->FlagSourceAsCompiled(true); | 414 info->FlagSourceAsCompiled(true); |
400 | 415 |
401 // Translate GL ES 2.0 shader to Desktop GL shader and pass that to | 416 // Translate GL ES 2.0 shader to Desktop GL shader and pass that to |
402 // glShaderSource and then glCompileShader. | 417 // glShaderSource and then glCompileShader. |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
460 if (!CanLink()) { | 475 if (!CanLink()) { |
461 set_log_info("missing shaders"); | 476 set_log_info("missing shaders"); |
462 return false; | 477 return false; |
463 } | 478 } |
464 if (DetectAttribLocationBindingConflicts()) { | 479 if (DetectAttribLocationBindingConflicts()) { |
465 set_log_info("glBindAttribLocation() conflicts"); | 480 set_log_info("glBindAttribLocation() conflicts"); |
466 return false; | 481 return false; |
467 } | 482 } |
468 ExecuteBindAttribLocationCalls(); | 483 ExecuteBindAttribLocationCalls(); |
469 | 484 |
| 485 base::Time before_time = base::Time::Now(); |
470 bool link = true; | 486 bool link = true; |
471 ProgramCache* cache = manager_->program_cache_; | 487 ProgramCache* cache = manager_->program_cache_; |
472 if (cache) { | 488 if (cache) { |
473 ProgramCache::LinkedProgramStatus status = cache->GetLinkedProgramStatus( | 489 ProgramCache::LinkedProgramStatus status = cache->GetLinkedProgramStatus( |
474 *attached_shaders_[0]->deferred_compilation_source(), | 490 *attached_shaders_[0]->deferred_compilation_source(), |
475 *attached_shaders_[1]->deferred_compilation_source(), | 491 *attached_shaders_[1]->deferred_compilation_source(), |
476 &bind_attrib_location_map_); | 492 &bind_attrib_location_map_); |
477 | 493 |
478 if (status == ProgramCache::LINK_SUCCEEDED) { | 494 if (status == ProgramCache::LINK_SUCCEEDED) { |
479 ProgramCache::ProgramLoadResult success = cache->LoadLinkedProgram( | 495 ProgramCache::ProgramLoadResult success = cache->LoadLinkedProgram( |
480 service_id(), | 496 service_id(), |
481 attached_shaders_[0], | 497 attached_shaders_[0], |
482 attached_shaders_[1], | 498 attached_shaders_[1], |
483 &bind_attrib_location_map_); | 499 &bind_attrib_location_map_); |
484 link = success != ProgramCache::PROGRAM_LOAD_SUCCESS; | 500 link = success != ProgramCache::PROGRAM_LOAD_SUCCESS; |
| 501 UMA_HISTOGRAM_BOOLEAN("GPU.ProgramCache.LoadBinarySuccess", !link); |
485 } | 502 } |
486 | 503 |
487 if (link) { | 504 if (link) { |
488 // compile our shaders if they're pending | 505 // compile our shaders if they're pending |
489 const int kShaders = ProgramManager::ProgramInfo::kMaxAttachedShaders; | 506 const int kShaders = ProgramManager::ProgramInfo::kMaxAttachedShaders; |
490 for (int i = 0; i < kShaders; ++i) { | 507 for (int i = 0; i < kShaders; ++i) { |
491 ShaderManager::ShaderInfo* info = attached_shaders_[i].get(); | 508 ShaderManager::ShaderInfo* info = attached_shaders_[i].get(); |
492 if (info->compilation_status() == | 509 if (info->compilation_status() == |
493 ShaderManager::ShaderInfo::PENDING_DEFERRED_COMPILE) { | 510 ShaderManager::ShaderInfo::PENDING_DEFERRED_COMPILE) { |
494 ShaderTranslator* translator = ShaderIndexToTranslator( | 511 ShaderTranslator* translator = ShaderIndexToTranslator( |
495 i, | 512 i, |
496 vertex_translator, | 513 vertex_translator, |
497 fragment_translator); | 514 fragment_translator); |
498 manager_->ForceCompileShader(info->deferred_compilation_source(), | 515 manager_->ForceCompileShader(info->deferred_compilation_source(), |
499 attached_shaders_[i], | 516 attached_shaders_[i], |
500 translator, | 517 translator, |
501 feature_info); | 518 feature_info); |
502 CHECK(info->IsValid()); | 519 CHECK(info->IsValid()); |
503 } | 520 } |
504 } | 521 } |
505 } | 522 } |
506 } | 523 } |
507 | 524 |
508 if (link) { | 525 if (link) { |
| 526 before_time = base::Time::Now(); |
509 if (cache && gfx::g_GL_ARB_get_program_binary) { | 527 if (cache && gfx::g_GL_ARB_get_program_binary) { |
510 glProgramParameteri(service_id(), | 528 glProgramParameteri(service_id(), |
511 PROGRAM_BINARY_RETRIEVABLE_HINT, | 529 PROGRAM_BINARY_RETRIEVABLE_HINT, |
512 GL_TRUE); | 530 GL_TRUE); |
513 } | 531 } |
514 glLinkProgram(service_id()); | 532 glLinkProgram(service_id()); |
515 } | 533 } |
516 | 534 |
517 GLint success = 0; | 535 GLint success = 0; |
518 glGetProgramiv(service_id(), GL_LINK_STATUS, &success); | 536 glGetProgramiv(service_id(), GL_LINK_STATUS, &success); |
519 if (success == GL_TRUE) { | 537 if (success == GL_TRUE) { |
520 Update(); | 538 Update(); |
521 if (cache && link) { | 539 if (cache && link) { |
522 cache->SaveLinkedProgram(service_id(), | 540 cache->SaveLinkedProgram(service_id(), |
523 attached_shaders_[0], | 541 attached_shaders_[0], |
524 attached_shaders_[1], | 542 attached_shaders_[1], |
525 &bind_attrib_location_map_); | 543 &bind_attrib_location_map_); |
| 544 HISTOGRAM_CUSTOM_COUNTS( |
| 545 "GPU.ProgramCache.BinaryCacheMissTime", |
| 546 (base::Time::Now() - before_time).InMicroseconds(), |
| 547 100, |
| 548 TimeDelta::FromSeconds(1).InMicroseconds(), |
| 549 50); |
| 550 } else if (cache) { |
| 551 HISTOGRAM_CUSTOM_COUNTS( |
| 552 "GPU.ProgramCache.BinaryCacheHitTime", |
| 553 (base::Time::Now() - before_time).InMicroseconds(), |
| 554 100, |
| 555 TimeDelta::FromSeconds(1).InMicroseconds(), |
| 556 50); |
526 } | 557 } |
527 } else { | 558 } else { |
528 UpdateLogInfo(); | 559 UpdateLogInfo(); |
529 } | 560 } |
530 return success == GL_TRUE; | 561 return success == GL_TRUE; |
531 } | 562 } |
532 | 563 |
533 void ProgramManager::ProgramInfo::Validate() { | 564 void ProgramManager::ProgramInfo::Validate() { |
534 if (!IsValid()) { | 565 if (!IsValid()) { |
535 set_log_info("program not linked"); | 566 set_log_info("program not linked"); |
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1114 info->ClearUniforms(&zero_); | 1145 info->ClearUniforms(&zero_); |
1115 } | 1146 } |
1116 } | 1147 } |
1117 | 1148 |
1118 int32 ProgramManager::MakeFakeLocation(int32 index, int32 element) { | 1149 int32 ProgramManager::MakeFakeLocation(int32 index, int32 element) { |
1119 return index + element * 0x10000; | 1150 return index + element * 0x10000; |
1120 } | 1151 } |
1121 | 1152 |
1122 } // namespace gles2 | 1153 } // namespace gles2 |
1123 } // namespace gpu | 1154 } // namespace gpu |
OLD | NEW |