summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/resources/software_rendering_list.json3
-rw-r--r--content/browser/gpu_blacklist.cc73
-rw-r--r--content/browser/gpu_blacklist.h6
-rw-r--r--content/browser/gpu_blacklist_unittest.cc69
4 files changed, 127 insertions, 24 deletions
diff --git a/chrome/browser/resources/software_rendering_list.json b/chrome/browser/resources/software_rendering_list.json
index e9f4140..dfad0c6 100644
--- a/chrome/browser/resources/software_rendering_list.json
+++ b/chrome/browser/resources/software_rendering_list.json
@@ -22,7 +22,8 @@
// 4. "driver_vendor" is a STRING structure (defined below).
// 5. "driver_version" is a VERSION structure (defined below).
// 6. "gl_renderer" is a STRING structure (defined below).
-// 7. "blacklist" is a list of gpu feature strings, valid values include
+// 7: "Exceptions" is a list of entries.
+// 8. "blacklist" is a list of gpu feature strings, valid values include
// "accelerated_2d_canvas", "accelerated_compositing", "webgl", and "all".
// Currently whatever feature is selected, the effect is the same as "all",
// i.e., it's not supported to turn off one GPU feature and not the others.
diff --git a/content/browser/gpu_blacklist.cc b/content/browser/gpu_blacklist.cc
index 771de1d..d9b934f 100644
--- a/content/browser/gpu_blacklist.cc
+++ b/content/browser/gpu_blacklist.cc
@@ -176,16 +176,18 @@ GpuBlacklist::StringInfo::Op GpuBlacklist::StringInfo::StringToOp(
GpuBlacklist::GpuBlacklistEntry*
GpuBlacklist::GpuBlacklistEntry::GetGpuBlacklistEntryFromValue(
- DictionaryValue* value) {
+ DictionaryValue* value, bool top_level) {
if (value == NULL)
return NULL;
GpuBlacklistEntry* entry = new GpuBlacklistEntry();
- std::string id;
- if (!value->GetString("id", &id) || !entry->SetId(id)) {
- delete entry;
- return NULL;
+ if (top_level) {
+ std::string id;
+ if (!value->GetString("id", &id) || !entry->SetId(id)) {
+ delete entry;
+ return NULL;
+ }
}
DictionaryValue* os_value = NULL;
@@ -263,30 +265,50 @@ GpuBlacklist::GpuBlacklistEntry::GetGpuBlacklistEntryFromValue(
}
}
- ListValue* blacklist_value = NULL;
- if (!value->GetList("blacklist", &blacklist_value)) {
- delete entry;
- return NULL;
- }
- std::vector<std::string> blacklist;
- for (size_t i = 0; i < blacklist_value->GetSize(); ++i) {
- std::string feature;
- if (blacklist_value->GetString(i, &feature)) {
- blacklist.push_back(feature);
- } else {
+ if (top_level) {
+ ListValue* blacklist_value = NULL;
+ if (!value->GetList("blacklist", &blacklist_value)) {
+ delete entry;
+ return NULL;
+ }
+ std::vector<std::string> blacklist;
+ for (size_t i = 0; i < blacklist_value->GetSize(); ++i) {
+ std::string feature;
+ if (blacklist_value->GetString(i, &feature)) {
+ blacklist.push_back(feature);
+ } else {
+ delete entry;
+ return NULL;
+ }
+ }
+ if (!entry->SetBlacklistedFeatures(blacklist)) {
delete entry;
return NULL;
}
}
- if (!entry->SetBlacklistedFeatures(blacklist)) {
- delete entry;
- return NULL;
+
+ if (top_level) {
+ ListValue* exception_list_value = NULL;
+ if (value->GetList("exceptions", &exception_list_value)) {
+ for (size_t i = 0; i < exception_list_value->GetSize(); ++i) {
+ DictionaryValue* exception_value = NULL;
+ if (!exception_list_value->GetDictionary(i, &exception_value))
+ continue;
+ GpuBlacklistEntry* exception = GetGpuBlacklistEntryFromValue(
+ exception_value, false);
+ if (exception)
+ entry->AddException(exception);
+ }
+ }
}
return entry;
}
-GpuBlacklist::GpuBlacklistEntry::~GpuBlacklistEntry() {}
+GpuBlacklist::GpuBlacklistEntry::~GpuBlacklistEntry() {
+ for (size_t i = 0; i < exceptions_.size(); ++i)
+ delete exceptions_[i];
+}
GpuBlacklist::GpuBlacklistEntry::GpuBlacklistEntry()
: id_(0),
@@ -377,6 +399,11 @@ bool GpuBlacklist::GpuBlacklistEntry::SetBlacklistedFeatures(
return true;
}
+void GpuBlacklist::GpuBlacklistEntry::AddException(
+ GpuBlacklistEntry* exception) {
+ exceptions_.push_back(exception);
+}
+
bool GpuBlacklist::GpuBlacklistEntry::Contains(
OsType os_type, const Version& os_version, const GPUInfo& gpu_info) const {
DCHECK(os_type != kOsAny);
@@ -399,6 +426,10 @@ bool GpuBlacklist::GpuBlacklistEntry::Contains(
if (gl_renderer_info_.get() != NULL &&
!gl_renderer_info_->Contains(gpu_info.gl_renderer()))
return false;
+ for (size_t i = 0; i < exceptions_.size(); ++i) {
+ if (exceptions_[i]->Contains(os_type, os_version, gpu_info))
+ return false;
+ }
return true;
}
@@ -458,7 +489,7 @@ bool GpuBlacklist::LoadGpuBlacklist(const DictionaryValue& parsed_json,
if (!valid)
break;
GpuBlacklistEntry* entry =
- GpuBlacklistEntry::GetGpuBlacklistEntryFromValue(list_item);
+ GpuBlacklistEntry::GetGpuBlacklistEntryFromValue(list_item, true);
if (entry == NULL)
break;
if (entry->id() > max_entry_id)
diff --git a/content/browser/gpu_blacklist.h b/content/browser/gpu_blacklist.h
index 7758b65..f2fdfe5 100644
--- a/content/browser/gpu_blacklist.h
+++ b/content/browser/gpu_blacklist.h
@@ -157,8 +157,9 @@ class GpuBlacklist {
class GpuBlacklistEntry {
public:
// Constructs GpuBlacklistEntry from DictionaryValue loaded from json.
+ // Top-level entry must have an id number. Others are exceptions.
static GpuBlacklistEntry* GetGpuBlacklistEntryFromValue(
- DictionaryValue* value);
+ DictionaryValue* value, bool top_level);
// Determines if a given os/gc/driver is included in the Entry set.
bool Contains(OsType os_type,
@@ -203,6 +204,8 @@ class GpuBlacklist {
bool SetBlacklistedFeatures(
const std::vector<std::string>& blacklisted_features);
+ void AddException(GpuBlacklistEntry* exception);
+
uint32 id_;
scoped_ptr<OsInfo> os_info_;
uint32 vendor_id_;
@@ -211,6 +214,7 @@ class GpuBlacklist {
scoped_ptr<VersionInfo> driver_version_info_;
scoped_ptr<StringInfo> gl_renderer_info_;
scoped_ptr<GpuFeatureFlags> feature_flags_;
+ std::vector<GpuBlacklistEntry*> exceptions_;
};
// Gets the current OS type.
diff --git a/content/browser/gpu_blacklist_unittest.cc b/content/browser/gpu_blacklist_unittest.cc
index b5ed07a..1b20e1b 100644
--- a/content/browser/gpu_blacklist_unittest.cc
+++ b/content/browser/gpu_blacklist_unittest.cc
@@ -142,7 +142,6 @@ TEST(GpuBlacklistTest, BlacklistLogic) {
static_cast<uint32>(GpuFeatureFlags::kGpuFeatureWebgl));
#endif
-
// Blacklist a vendor on Linux only.
const std::string vendor_linux_json =
"{\n"
@@ -173,5 +172,73 @@ TEST(GpuBlacklistTest, BlacklistLogic) {
EXPECT_EQ(
flags.flags(),
static_cast<uint32>(GpuFeatureFlags::kGpuFeatureAccelerated2dCanvas));
+
+ // Blacklist all cards in Linux except NVIDIA.
+ const std::string linux_except_nvidia_json =
+ "{\n"
+ " \"name\": \"gpu blacklist\",\n"
+ " \"version\": \"0.1\",\n"
+ " \"entries\": [\n"
+ " {\n"
+ " \"id\": \"1\",\n"
+ " \"os\": {\n"
+ " \"type\": \"linux\"\n"
+ " },\n"
+ " \"exceptions\": [\n"
+ " {\n"
+ " \"vendor_id\": \"0x10de\"\n"
+ " }\n"
+ " ],\n"
+ " \"blacklist\": [\n"
+ " \"accelerated_2d_canvas\"\n"
+ " ]\n"
+ " }\n"
+ " ]\n"
+ "}";
+ EXPECT_TRUE(blacklist.LoadGpuBlacklist(linux_except_nvidia_json, false));
+ flags = blacklist.DetermineGpuFeatureFlags(
+ GpuBlacklist::kOsMacosx, os_version.get(), gpu_info);
+ EXPECT_EQ(flags.flags(), 0u);
+ flags = blacklist.DetermineGpuFeatureFlags(
+ GpuBlacklist::kOsWin, os_version.get(), gpu_info);
+ EXPECT_EQ(flags.flags(), 0u);
+ flags = blacklist.DetermineGpuFeatureFlags(
+ GpuBlacklist::kOsLinux, os_version.get(), gpu_info);
+ EXPECT_EQ(flags.flags(), 0u);
+
+ // Blacklist all cards in Linux except Intel.
+ const std::string linux_except_intel_json =
+ "{\n"
+ " \"name\": \"gpu blacklist\",\n"
+ " \"version\": \"0.1\",\n"
+ " \"entries\": [\n"
+ " {\n"
+ " \"id\": \"1\",\n"
+ " \"os\": {\n"
+ " \"type\": \"linux\"\n"
+ " },\n"
+ " \"exceptions\": [\n"
+ " {\n"
+ " \"vendor_id\": \"0x8086\"\n"
+ " }\n"
+ " ],\n"
+ " \"blacklist\": [\n"
+ " \"accelerated_2d_canvas\"\n"
+ " ]\n"
+ " }\n"
+ " ]\n"
+ "}";
+ EXPECT_TRUE(blacklist.LoadGpuBlacklist(linux_except_intel_json, false));
+ flags = blacklist.DetermineGpuFeatureFlags(
+ GpuBlacklist::kOsMacosx, os_version.get(), gpu_info);
+ EXPECT_EQ(flags.flags(), 0u);
+ flags = blacklist.DetermineGpuFeatureFlags(
+ GpuBlacklist::kOsWin, os_version.get(), gpu_info);
+ EXPECT_EQ(flags.flags(), 0u);
+ flags = blacklist.DetermineGpuFeatureFlags(
+ GpuBlacklist::kOsLinux, os_version.get(), gpu_info);
+ EXPECT_EQ(
+ flags.flags(),
+ static_cast<uint32>(GpuFeatureFlags::kGpuFeatureAccelerated2dCanvas));
}