| 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 "content/browser/gpu/gpu_blacklist.h" | 5 #include "content/browser/gpu/gpu_blacklist.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/json/json_reader.h" | 8 #include "base/json/json_reader.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
| 11 #include "base/string_split.h" | 11 #include "base/string_split.h" |
| 12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 13 #include "base/sys_info.h" | 13 #include "base/sys_info.h" |
| 14 #include "base/version.h" | 14 #include "base/version.h" |
| 15 #include "content/browser/gpu/gpu_util.h" | 15 #include "content/browser/gpu/gpu_util.h" |
| 16 #include "content/public/common/content_switches.h" | 16 #include "content/public/common/content_switches.h" |
| 17 #include "content/public/common/gpu_info.h" | 17 #include "content/public/common/gpu_info.h" |
| 18 | 18 |
| 19 using content::GpuFeatureType; | 19 using content::GpuFeatureType; |
| 20 using content::GpuSwitchingOption; |
| 20 | 21 |
| 21 namespace { | 22 namespace { |
| 22 | 23 |
| 23 // Encode a date as Version, where [0] is year, [1] is month, and [2] is day. | 24 // Encode a date as Version, where [0] is year, [1] is month, and [2] is day. |
| 24 void GetDateFromString(const std::string& date_string, Version* version) { | 25 void GetDateFromString(const std::string& date_string, Version* version) { |
| 25 // TODO(zmo): verify if in Windows registry, driver dates are always in the | 26 // TODO(zmo): verify if in Windows registry, driver dates are always in the |
| 26 // format of "mm-dd-yyyy". | 27 // format of "mm-dd-yyyy". |
| 27 std::vector<std::string> pieces; | 28 std::vector<std::string> pieces; |
| 28 base::SplitString(date_string, '-', &pieces); | 29 base::SplitString(date_string, '-', &pieces); |
| 29 if (pieces.size() != 3) { | 30 if (pieces.size() != 3) { |
| (...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 546 perf_overall_value->GetString("value2", &float_value2); | 547 perf_overall_value->GetString("value2", &float_value2); |
| 547 if (!entry->SetPerfOverallInfo(op, float_value, float_value2)) { | 548 if (!entry->SetPerfOverallInfo(op, float_value, float_value2)) { |
| 548 LOG(WARNING) << "Malformed perf_overall entry " << entry->id(); | 549 LOG(WARNING) << "Malformed perf_overall entry " << entry->id(); |
| 549 return NULL; | 550 return NULL; |
| 550 } | 551 } |
| 551 dictionary_entry_count++; | 552 dictionary_entry_count++; |
| 552 } | 553 } |
| 553 | 554 |
| 554 if (top_level) { | 555 if (top_level) { |
| 555 const ListValue* blacklist_value = NULL; | 556 const ListValue* blacklist_value = NULL; |
| 556 if (!value->GetList("blacklist", &blacklist_value)) { | 557 if (value->GetList("blacklist", &blacklist_value)) { |
| 557 LOG(WARNING) << "Malformed blacklist entry " << entry->id(); | 558 std::vector<std::string> blacklist; |
| 558 return NULL; | 559 for (size_t i = 0; i < blacklist_value->GetSize(); ++i) { |
| 559 } | 560 std::string feature; |
| 560 std::vector<std::string> blacklist; | 561 if (blacklist_value->GetString(i, &feature)) { |
| 561 for (size_t i = 0; i < blacklist_value->GetSize(); ++i) { | 562 blacklist.push_back(feature); |
| 562 std::string feature; | 563 } else { |
| 563 if (blacklist_value->GetString(i, &feature)) { | 564 LOG(WARNING) << "Malformed blacklist entry " << entry->id(); |
| 564 blacklist.push_back(feature); | 565 return NULL; |
| 565 } else { | 566 } |
| 567 } |
| 568 if (!entry->SetBlacklistedFeatures(blacklist)) { |
| 566 LOG(WARNING) << "Malformed blacklist entry " << entry->id(); | 569 LOG(WARNING) << "Malformed blacklist entry " << entry->id(); |
| 567 return NULL; | 570 return NULL; |
| 568 } | 571 } |
| 572 dictionary_entry_count++; |
| 569 } | 573 } |
| 570 if (!entry->SetBlacklistedFeatures(blacklist)) { | 574 |
| 571 LOG(WARNING) << "Malformed blacklist entry " << entry->id(); | 575 std::string switching_value; |
| 572 return NULL; | 576 if (value->GetString("gpu_switching", &switching_value)) { |
| 577 if (!entry->SetGpuSwitchingOption(switching_value)) { |
| 578 LOG(WARNING) << "Malformed gpu_switching entry " << entry->id(); |
| 579 return NULL; |
| 580 } |
| 581 dictionary_entry_count++; |
| 573 } | 582 } |
| 574 dictionary_entry_count++; | |
| 575 } | 583 } |
| 576 | 584 |
| 577 if (top_level) { | 585 if (top_level) { |
| 578 const ListValue* exception_list_value = NULL; | 586 const ListValue* exception_list_value = NULL; |
| 579 if (value->GetList("exceptions", &exception_list_value)) { | 587 if (value->GetList("exceptions", &exception_list_value)) { |
| 580 for (size_t i = 0; i < exception_list_value->GetSize(); ++i) { | 588 for (size_t i = 0; i < exception_list_value->GetSize(); ++i) { |
| 581 const DictionaryValue* exception_value = NULL; | 589 const DictionaryValue* exception_value = NULL; |
| 582 if (!exception_list_value->GetDictionary(i, &exception_value)) { | 590 if (!exception_list_value->GetDictionary(i, &exception_value)) { |
| 583 LOG(WARNING) << "Malformed exceptions entry " << entry->id(); | 591 LOG(WARNING) << "Malformed exceptions entry " << entry->id(); |
| 584 return NULL; | 592 return NULL; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 611 } | 619 } |
| 612 return entry; | 620 return entry; |
| 613 } | 621 } |
| 614 | 622 |
| 615 GpuBlacklist::GpuBlacklistEntry::GpuBlacklistEntry() | 623 GpuBlacklist::GpuBlacklistEntry::GpuBlacklistEntry() |
| 616 : id_(0), | 624 : id_(0), |
| 617 disabled_(false), | 625 disabled_(false), |
| 618 vendor_id_(0), | 626 vendor_id_(0), |
| 619 multi_gpu_style_(kMultiGpuStyleNone), | 627 multi_gpu_style_(kMultiGpuStyleNone), |
| 620 multi_gpu_category_(kMultiGpuCategoryPrimary), | 628 multi_gpu_category_(kMultiGpuCategoryPrimary), |
| 621 feature_type_(content::GPU_FEATURE_TYPE_UNKNOWN), | |
| 622 contains_unknown_fields_(false), | 629 contains_unknown_fields_(false), |
| 623 contains_unknown_features_(false) { | 630 contains_unknown_features_(false) { |
| 624 } | 631 } |
| 625 | 632 |
| 626 GpuBlacklist::GpuBlacklistEntry::~GpuBlacklistEntry() { } | 633 GpuBlacklist::GpuBlacklistEntry::~GpuBlacklistEntry() { } |
| 627 | 634 |
| 628 bool GpuBlacklist::GpuBlacklistEntry::SetId(uint32 id) { | 635 bool GpuBlacklist::GpuBlacklistEntry::SetId(uint32 id) { |
| 629 if (id != 0) { | 636 if (id != 0) { |
| 630 id_ = id; | 637 id_ = id; |
| 631 return true; | 638 return true; |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 772 case content::GPU_FEATURE_TYPE_TEXTURE_SHARING: | 779 case content::GPU_FEATURE_TYPE_TEXTURE_SHARING: |
| 773 case content::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE: | 780 case content::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE: |
| 774 case content::GPU_FEATURE_TYPE_ALL: | 781 case content::GPU_FEATURE_TYPE_ALL: |
| 775 feature_type |= type; | 782 feature_type |= type; |
| 776 break; | 783 break; |
| 777 case content::GPU_FEATURE_TYPE_UNKNOWN: | 784 case content::GPU_FEATURE_TYPE_UNKNOWN: |
| 778 contains_unknown_features_ = true; | 785 contains_unknown_features_ = true; |
| 779 break; | 786 break; |
| 780 } | 787 } |
| 781 } | 788 } |
| 782 feature_type_ = static_cast<GpuFeatureType>(feature_type); | 789 decision_.blacklisted_features = static_cast<GpuFeatureType>(feature_type); |
| 790 return true; |
| 791 } |
| 792 |
| 793 bool GpuBlacklist::GpuBlacklistEntry::SetGpuSwitchingOption( |
| 794 const std::string& switching_string) { |
| 795 GpuSwitchingOption switching = gpu_util::StringToGpuSwitchingOption( |
| 796 switching_string); |
| 797 if (switching == content::GPU_SWITCHING_UNKNOWN) |
| 798 return false; |
| 799 decision_.gpu_switching = switching; |
| 783 return true; | 800 return true; |
| 784 } | 801 } |
| 785 | 802 |
| 786 void GpuBlacklist::GpuBlacklistEntry::AddException( | 803 void GpuBlacklist::GpuBlacklistEntry::AddException( |
| 787 ScopedGpuBlacklistEntry exception) { | 804 ScopedGpuBlacklistEntry exception) { |
| 788 exceptions_.push_back(exception); | 805 exceptions_.push_back(exception); |
| 789 } | 806 } |
| 790 | 807 |
| 791 // static | 808 // static |
| 792 GpuBlacklist::GpuBlacklistEntry::MultiGpuStyle | 809 GpuBlacklist::GpuBlacklistEntry::MultiGpuStyle |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 906 | 923 |
| 907 uint32 GpuBlacklist::GpuBlacklistEntry::id() const { | 924 uint32 GpuBlacklist::GpuBlacklistEntry::id() const { |
| 908 return id_; | 925 return id_; |
| 909 } | 926 } |
| 910 | 927 |
| 911 bool GpuBlacklist::GpuBlacklistEntry::disabled() const { | 928 bool GpuBlacklist::GpuBlacklistEntry::disabled() const { |
| 912 return disabled_; | 929 return disabled_; |
| 913 } | 930 } |
| 914 | 931 |
| 915 GpuFeatureType GpuBlacklist::GpuBlacklistEntry::GetGpuFeatureType() const { | 932 GpuFeatureType GpuBlacklist::GpuBlacklistEntry::GetGpuFeatureType() const { |
| 916 return feature_type_; | 933 return decision_.blacklisted_features; |
| 934 } |
| 935 |
| 936 GpuSwitchingOption |
| 937 GpuBlacklist::GpuBlacklistEntry::GetGpuSwitchingOption() const { |
| 938 return decision_.gpu_switching; |
| 917 } | 939 } |
| 918 | 940 |
| 919 GpuBlacklist::GpuBlacklist() | 941 GpuBlacklist::GpuBlacklist() |
| 920 : max_entry_id_(0), | 942 : max_entry_id_(0), |
| 921 contains_unknown_fields_(false) { | 943 contains_unknown_fields_(false) { |
| 922 } | 944 } |
| 923 | 945 |
| 924 GpuBlacklist::~GpuBlacklist() { | 946 GpuBlacklist::~GpuBlacklist() { |
| 925 Clear(); | 947 Clear(); |
| 926 } | 948 } |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1001 OsType entry_os = entries[i]->GetOsType(); | 1023 OsType entry_os = entries[i]->GetOsType(); |
| 1002 if (os_filter == GpuBlacklist::kAllOs || | 1024 if (os_filter == GpuBlacklist::kAllOs || |
| 1003 entry_os == kOsAny || entry_os == my_os) | 1025 entry_os == kOsAny || entry_os == my_os) |
| 1004 blacklist_.push_back(entries[i]); | 1026 blacklist_.push_back(entries[i]); |
| 1005 } | 1027 } |
| 1006 max_entry_id_ = max_entry_id; | 1028 max_entry_id_ = max_entry_id; |
| 1007 contains_unknown_fields_ = contains_unknown_fields; | 1029 contains_unknown_fields_ = contains_unknown_fields; |
| 1008 return true; | 1030 return true; |
| 1009 } | 1031 } |
| 1010 | 1032 |
| 1011 GpuFeatureType GpuBlacklist::DetermineGpuFeatureType( | 1033 GpuBlacklist::Decision GpuBlacklist::MakeBlacklistDecision( |
| 1012 GpuBlacklist::OsType os, | 1034 GpuBlacklist::OsType os, |
| 1013 Version* os_version, | 1035 Version* os_version, |
| 1014 const content::GPUInfo& gpu_info) { | 1036 const content::GPUInfo& gpu_info) { |
| 1015 active_entries_.clear(); | 1037 active_entries_.clear(); |
| 1016 int type = 0; | 1038 int type = 0; |
| 1039 GpuSwitchingOption switching = content::GPU_SWITCHING_AUTOMATIC; |
| 1017 | 1040 |
| 1018 if (os == kOsAny) | 1041 if (os == kOsAny) |
| 1019 os = GetOsType(); | 1042 os = GetOsType(); |
| 1020 scoped_ptr<Version> my_os_version; | 1043 scoped_ptr<Version> my_os_version; |
| 1021 if (os_version == NULL) { | 1044 if (os_version == NULL) { |
| 1022 std::string version_string = base::SysInfo::OperatingSystemVersion(); | 1045 std::string version_string = base::SysInfo::OperatingSystemVersion(); |
| 1023 size_t pos = version_string.find_first_not_of("0123456789."); | 1046 size_t pos = version_string.find_first_not_of("0123456789."); |
| 1024 if (pos != std::string::npos) | 1047 if (pos != std::string::npos) |
| 1025 version_string = version_string.substr(0, pos); | 1048 version_string = version_string.substr(0, pos); |
| 1026 my_os_version.reset(new Version(version_string)); | 1049 my_os_version.reset(new Version(version_string)); |
| 1027 os_version = my_os_version.get(); | 1050 os_version = my_os_version.get(); |
| 1028 } | 1051 } |
| 1029 DCHECK(os_version != NULL); | 1052 DCHECK(os_version != NULL); |
| 1030 | 1053 |
| 1031 for (size_t i = 0; i < blacklist_.size(); ++i) { | 1054 for (size_t i = 0; i < blacklist_.size(); ++i) { |
| 1032 if (blacklist_[i]->Contains(os, *os_version, gpu_info)) { | 1055 if (blacklist_[i]->Contains(os, *os_version, gpu_info)) { |
| 1033 if (!blacklist_[i]->disabled()) | 1056 if (!blacklist_[i]->disabled()) { |
| 1034 type |= blacklist_[i]->GetGpuFeatureType(); | 1057 type |= blacklist_[i]->GetGpuFeatureType(); |
| 1058 if (blacklist_[i]->GetGpuSwitchingOption() != |
| 1059 content::GPU_SWITCHING_AUTOMATIC) |
| 1060 switching = blacklist_[i]->GetGpuSwitchingOption(); |
| 1061 } |
| 1035 active_entries_.push_back(blacklist_[i]); | 1062 active_entries_.push_back(blacklist_[i]); |
| 1036 } | 1063 } |
| 1037 } | 1064 } |
| 1038 return static_cast<GpuFeatureType>(type); | 1065 Decision decision; |
| 1066 decision.blacklisted_features = static_cast<GpuFeatureType>(type); |
| 1067 decision.gpu_switching = switching; |
| 1068 return decision; |
| 1039 } | 1069 } |
| 1040 | 1070 |
| 1041 void GpuBlacklist::GetGpuFeatureTypeEntries( | 1071 void GpuBlacklist::GetDecisionEntries( |
| 1042 content::GpuFeatureType feature, | 1072 std::vector<uint32>& entry_ids, bool disabled) const { |
| 1043 std::vector<uint32>& entry_ids, | |
| 1044 bool disabled) const { | |
| 1045 entry_ids.clear(); | 1073 entry_ids.clear(); |
| 1046 for (size_t i = 0; i < active_entries_.size(); ++i) { | 1074 for (size_t i = 0; i < active_entries_.size(); ++i) { |
| 1047 if (((feature & active_entries_[i]->GetGpuFeatureType()) != 0) && | 1075 if (disabled == active_entries_[i]->disabled()) |
| 1048 disabled == active_entries_[i]->disabled()) | |
| 1049 entry_ids.push_back(active_entries_[i]->id()); | 1076 entry_ids.push_back(active_entries_[i]->id()); |
| 1050 } | 1077 } |
| 1051 } | 1078 } |
| 1052 | 1079 |
| 1053 void GpuBlacklist::GetBlacklistReasons(ListValue* problem_list) const { | 1080 void GpuBlacklist::GetBlacklistReasons(ListValue* problem_list) const { |
| 1054 DCHECK(problem_list); | 1081 DCHECK(problem_list); |
| 1055 for (size_t i = 0; i < active_entries_.size(); ++i) { | 1082 for (size_t i = 0; i < active_entries_.size(); ++i) { |
| 1056 GpuBlacklistEntry* entry = active_entries_[i]; | 1083 GpuBlacklistEntry* entry = active_entries_[i]; |
| 1057 if (entry->disabled()) | 1084 if (entry->disabled()) |
| 1058 continue; | 1085 continue; |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1155 if (op == ">") | 1182 if (op == ">") |
| 1156 return kGT; | 1183 return kGT; |
| 1157 if (op == ">=") | 1184 if (op == ">=") |
| 1158 return kGE; | 1185 return kGE; |
| 1159 if (op == "any") | 1186 if (op == "any") |
| 1160 return kAny; | 1187 return kAny; |
| 1161 if (op == "between") | 1188 if (op == "between") |
| 1162 return kBetween; | 1189 return kBetween; |
| 1163 return kUnknown; | 1190 return kUnknown; |
| 1164 } | 1191 } |
| OLD | NEW |