Commit 790cc105 authored by zmo@google.com's avatar zmo@google.com

Enhance GPU blacklist so we can also blacklist GPUs other than the primary one.

For example, on Macbook, we can blacklist Intel HD 4000 whether it is the only GPU on the machine, or it is the integrated one of a dual GPU setting.

BUG=134015
TEST=unit_tests
Review URL: https://chromiumcodereview.appspot.com/10832044

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148999 0039d316-1c4b-4281-b951-d872f2087c98
parent 8157347c
......@@ -67,9 +67,30 @@ std::string NumericalToLexical(const std::string& numerical) {
return numerical;
}
bool GpuUnmatched(uint32 vendor_id, const std::vector<uint32>& device_id_list,
const content::GPUInfo::GPUDevice& gpu) {
if (vendor_id == 0)
return false;
if (vendor_id != gpu.vendor_id)
return true;
bool device_specified = false;
for (size_t i = 0; i < device_id_list.size(); ++i) {
if (device_id_list[i] == 0)
continue;
if (device_id_list[i] == gpu.device_id)
return false;
device_specified = true;
}
return device_specified;
}
const char kMultiGpuStyleStringAMDSwitchable[] = "amd_switchable";
const char kMultiGpuStyleStringOptimus[] = "optimus";
const char kMultiGpuCategoryStringPrimary[] = "primary";
const char kMultiGpuCategoryStringSecondary[] = "secondary";
const char kMultiGpuCategoryStringAny[] = "any";
const char kVersionStyleStringNumerical[] = "numerical";
const char kVersionStyleStringLexical[] = "lexical";
......@@ -404,6 +425,15 @@ GpuBlacklist::GpuBlacklistEntry::GetGpuBlacklistEntryFromValue(
dictionary_entry_count++;
}
std::string multi_gpu_category;
if (value->GetString("multi_gpu_category", &multi_gpu_category)) {
if (!entry->SetMultiGpuCategory(multi_gpu_category)) {
LOG(WARNING) << "Malformed multi_gpu_category entry " << entry->id();
return NULL;
}
dictionary_entry_count++;
}
DictionaryValue* driver_vendor_value = NULL;
if (value->GetDictionary("driver_vendor", &driver_vendor_value)) {
std::string vendor_op;
......@@ -590,6 +620,7 @@ GpuBlacklist::GpuBlacklistEntry::GpuBlacklistEntry()
disabled_(false),
vendor_id_(0),
multi_gpu_style_(kMultiGpuStyleNone),
multi_gpu_category_(kMultiGpuCategoryPrimary),
feature_type_(content::GPU_FEATURE_TYPE_UNKNOWN),
contains_unknown_fields_(false),
contains_unknown_features_(false) {
......@@ -643,6 +674,16 @@ bool GpuBlacklist::GpuBlacklistEntry::SetMultiGpuStyle(
return true;
}
bool GpuBlacklist::GpuBlacklistEntry::SetMultiGpuCategory(
const std::string& multi_gpu_category_string) {
MultiGpuCategory category =
StringToMultiGpuCategory(multi_gpu_category_string);
if (category == kMultiGpuCategoryNone)
return false;
multi_gpu_category_ = category;
return true;
}
bool GpuBlacklist::GpuBlacklistEntry::SetDriverVendorInfo(
const std::string& vendor_op,
const std::string& vendor_value) {
......@@ -758,24 +799,47 @@ GpuBlacklist::GpuBlacklistEntry::StringToMultiGpuStyle(
return kMultiGpuStyleNone;
}
// static
GpuBlacklist::GpuBlacklistEntry::MultiGpuCategory
GpuBlacklist::GpuBlacklistEntry::StringToMultiGpuCategory(
const std::string& category) {
if (category == kMultiGpuCategoryStringPrimary)
return kMultiGpuCategoryPrimary;
if (category == kMultiGpuCategoryStringSecondary)
return kMultiGpuCategorySecondary;
if (category == kMultiGpuCategoryStringAny)
return kMultiGpuCategoryAny;
return kMultiGpuCategoryNone;
}
bool GpuBlacklist::GpuBlacklistEntry::Contains(
OsType os_type, const Version& os_version,
const content::GPUInfo& gpu_info) const {
DCHECK(os_type != kOsAny);
if (os_info_.get() != NULL && !os_info_->Contains(os_type, os_version))
return false;
if (vendor_id_ != 0 && vendor_id_ != gpu_info.gpu.vendor_id)
return false;
if (device_id_list_.size() > 0) {
bool found = false;
for (size_t i = 0; i < device_id_list_.size(); ++i) {
if (device_id_list_[i] == gpu_info.gpu.device_id) {
found = true;
break;
}
}
if (!found)
return false;
bool is_not_primary_gpu =
GpuUnmatched(vendor_id_, device_id_list_, gpu_info.gpu);
bool is_not_secondary_gpu = true;
for (size_t i = 0; i < gpu_info.secondary_gpus.size(); ++i) {
is_not_secondary_gpu = is_not_secondary_gpu &&
GpuUnmatched(vendor_id_, device_id_list_, gpu_info.secondary_gpus[i]);
}
switch (multi_gpu_category_) {
case kMultiGpuCategoryPrimary:
if (is_not_primary_gpu)
return false;
break;
case kMultiGpuCategorySecondary:
if (is_not_secondary_gpu)
return false;
break;
case kMultiGpuCategoryAny:
if (is_not_primary_gpu && is_not_secondary_gpu)
return false;
break;
default:
break;
}
switch (multi_gpu_style_) {
case kMultiGpuStyleOptimus:
......
......@@ -272,6 +272,13 @@ class GpuBlacklist : public content::GpuDataManagerObserver {
kMultiGpuStyleNone
};
enum MultiGpuCategory {
kMultiGpuCategoryPrimary,
kMultiGpuCategorySecondary,
kMultiGpuCategoryAny,
kMultiGpuCategoryNone
};
GpuBlacklistEntry();
~GpuBlacklistEntry() { }
......@@ -290,6 +297,8 @@ class GpuBlacklist : public content::GpuDataManagerObserver {
bool SetMultiGpuStyle(const std::string& multi_gpu_style_string);
bool SetMultiGpuCategory(const std::string& multi_gpu_category_string);
bool SetDriverVendorInfo(const std::string& vendor_op,
const std::string& vendor_value);
......@@ -327,6 +336,9 @@ class GpuBlacklist : public content::GpuDataManagerObserver {
static MultiGpuStyle StringToMultiGpuStyle(const std::string& style);
static MultiGpuCategory StringToMultiGpuCategory(
const std::string& category);
uint32 id_;
bool disabled_;
std::string description_;
......@@ -336,6 +348,7 @@ class GpuBlacklist : public content::GpuDataManagerObserver {
uint32 vendor_id_;
std::vector<uint32> device_id_list_;
MultiGpuStyle multi_gpu_style_;
MultiGpuCategory multi_gpu_category_;
scoped_ptr<StringInfo> driver_vendor_info_;
scoped_ptr<VersionInfo> driver_version_info_;
scoped_ptr<VersionInfo> driver_date_info_;
......
......@@ -869,3 +869,88 @@ TEST_F(GpuBlacklistTest, LexicalDriverVersion) {
GpuBlacklist::kOsLinux, &os_version, gpu_info);
EXPECT_EQ(type, 0);
}
TEST_F(GpuBlacklistTest, MultipleGPUsAny) {
const std::string multi_gpu_json =
"{\n"
" \"name\": \"gpu blacklist\",\n"
" \"version\": \"0.1\",\n"
" \"entries\": [\n"
" {\n"
" \"id\": 1,\n"
" \"os\": {\n"
" \"type\": \"macosx\"\n"
" },\n"
" \"vendor_id\": \"0x8086\",\n"
" \"device_id\": [\"0x0166\"],\n"
" \"multi_gpu_category\": \"any\",\n"
" \"blacklist\": [\n"
" \"webgl\"\n"
" ]\n"
" }\n"
" ]\n"
"}";
Version os_version("10.6.4");
content::GPUInfo gpu_info;
gpu_info.gpu.vendor_id = 0x10de;
gpu_info.gpu.device_id = 0x0fd5;
scoped_ptr<GpuBlacklist> blacklist(Create());
EXPECT_TRUE(blacklist->LoadGpuBlacklist(
multi_gpu_json, GpuBlacklist::kAllOs));
GpuFeatureType type = blacklist->DetermineGpuFeatureType(
GpuBlacklist::kOsMacosx, &os_version, gpu_info);
EXPECT_EQ(type, 0);
content::GPUInfo::GPUDevice gpu_device;
gpu_device.vendor_id = 0x8086;
gpu_device.device_id = 0x0166;
gpu_info.secondary_gpus.push_back(gpu_device);
type = blacklist->DetermineGpuFeatureType(
GpuBlacklist::kOsMacosx, &os_version, gpu_info);
EXPECT_EQ(type, content::GPU_FEATURE_TYPE_WEBGL);
}
TEST_F(GpuBlacklistTest, MultipleGPUsSecondary) {
const std::string multi_gpu_json =
"{\n"
" \"name\": \"gpu blacklist\",\n"
" \"version\": \"0.1\",\n"
" \"entries\": [\n"
" {\n"
" \"id\": 1,\n"
" \"os\": {\n"
" \"type\": \"macosx\"\n"
" },\n"
" \"vendor_id\": \"0x8086\",\n"
" \"device_id\": [\"0x0166\"],\n"
" \"multi_gpu_category\": \"secondary\",\n"
" \"blacklist\": [\n"
" \"webgl\"\n"
" ]\n"
" }\n"
" ]\n"
"}";
Version os_version("10.6.4");
content::GPUInfo gpu_info;
gpu_info.gpu.vendor_id = 0x10de;
gpu_info.gpu.device_id = 0x0fd5;
scoped_ptr<GpuBlacklist> blacklist(Create());
EXPECT_TRUE(blacklist->LoadGpuBlacklist(
multi_gpu_json, GpuBlacklist::kAllOs));
GpuFeatureType type = blacklist->DetermineGpuFeatureType(
GpuBlacklist::kOsMacosx, &os_version, gpu_info);
EXPECT_EQ(type, 0);
content::GPUInfo::GPUDevice gpu_device;
gpu_device.vendor_id = 0x8086;
gpu_device.device_id = 0x0166;
gpu_info.secondary_gpus.push_back(gpu_device);
type = blacklist->DetermineGpuFeatureType(
GpuBlacklist::kOsMacosx, &os_version, gpu_info);
EXPECT_EQ(type, content::GPU_FEATURE_TYPE_WEBGL);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment