Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(692)

Side by Side Diff: chrome/browser/gpu_blacklist.cc

Issue 5612002: Blacklist bad GPU drivers: currenly we disable all gpu related features if th... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/gpu_blacklist.h ('k') | chrome/browser/gpu_blacklist_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/gpu_blacklist.h"
6
7 #include "base/json/json_reader.h"
8 #include "base/logging.h"
9 #include "base/string_number_conversions.h"
10 #include "base/stringprintf.h"
11 #include "base/sys_info.h"
12 #include "base/values.h"
13 #include "base/version.h"
14 #include "chrome/common/gpu_info.h"
15
16 GpuBlacklist::VersionInfo::VersionInfo(const std::string& version_op,
17 const std::string& version_string,
18 const std::string& version_string2) {
19 op_ = StringToOp(version_op);
20 if (op_ == kUnknown || op_ == kAny)
21 return;
22 version_.reset(Version::GetVersionFromString(version_string));
23 if (version_.get() == NULL) {
24 op_ = kUnknown;
25 return;
26 }
27 if (op_ == kBetween) {
28 version2_.reset(Version::GetVersionFromString(version_string2));
29 if (version2_.get() == NULL)
30 op_ = kUnknown;
31 }
32 }
33
34 GpuBlacklist::VersionInfo::~VersionInfo() {
35 }
36
37 bool GpuBlacklist::VersionInfo::Contains(const Version& version) const {
38 if (op_ == kUnknown)
39 return false;
40 if (op_ == kAny)
41 return true;
42 if (op_ == kEQ) {
43 // Handles cases where 10.6 is considered as containing 10.6.*.
44 const std::vector<uint16>& components_reference = version_->components();
45 const std::vector<uint16>& components = version.components();
46 for (size_t i = 0; i < components_reference.size(); ++i) {
47 if (i >= components.size() && components_reference[i] != 0)
48 return false;
49 if (components[i] != components_reference[i])
50 return false;
51 }
52 return true;
53 }
54 int relation = version.CompareTo(*version_);
55 if (op_ == kEQ)
56 return (relation == 0);
57 else if (op_ == kLT)
58 return (relation < 0);
59 else if (op_ == kLE)
60 return (relation <= 0);
61 else if (op_ == kGT)
62 return (relation > 0);
63 else if (op_ == kGE)
64 return (relation >= 0);
65 // op_ == kBetween
66 if (relation < 0)
67 return false;
68 return version.CompareTo(*version2_) <= 0;
69 }
70
71 bool GpuBlacklist::VersionInfo::IsValid() const {
72 return op_ != kUnknown;
73 }
74
75 GpuBlacklist::VersionInfo::Op GpuBlacklist::VersionInfo::StringToOp(
76 const std::string& version_op) {
77 if (version_op == "=")
78 return kEQ;
79 else if (version_op == "<")
80 return kLT;
81 else if (version_op == "<=")
82 return kLE;
83 else if (version_op == ">")
84 return kGT;
85 else if (version_op == ">=")
86 return kGE;
87 else if (version_op == "any")
88 return kAny;
89 else if (version_op == "between")
90 return kBetween;
91 return kUnknown;
92 }
93
94 GpuBlacklist::OsInfo::OsInfo(const std::string& os,
95 const std::string& version_op,
96 const std::string& version_string,
97 const std::string& version_string2) {
98 type_ = StringToOsType(os);
99 if (type_ != kOsUnknown) {
100 version_info_.reset(
101 new VersionInfo(version_op, version_string, version_string2));
102 }
103 }
104
105 bool GpuBlacklist::OsInfo::Contains(OsType type,
106 const Version& version) const {
107 if (!IsValid())
108 return false;
109 if (type_ != type && type_ != kOsAny)
110 return false;
111 return version_info_->Contains(version);
112 }
113
114 bool GpuBlacklist::OsInfo::IsValid() const {
115 return type_ != kOsUnknown && version_info_->IsValid();
116 }
117
118 GpuBlacklist::OsType GpuBlacklist::OsInfo::type() const {
119 return type_;
120 }
121
122 GpuBlacklist::OsType GpuBlacklist::OsInfo::StringToOsType(
123 const std::string& os) {
124 if (os == "win")
125 return kOsWin;
126 else if (os == "macosx")
127 return kOsMacosx;
128 else if (os == "linux")
129 return kOsLinux;
130 else if (os == "any")
131 return kOsAny;
132 return kOsUnknown;
133 }
134
135 GpuBlacklist::GpuBlacklistEntry*
136 GpuBlacklist::GpuBlacklistEntry::GetGpuBlacklistEntryFromValue(
137 DictionaryValue* value) {
138 if (value == NULL)
139 return NULL;
140
141 GpuBlacklistEntry* entry = new GpuBlacklistEntry();
142
143 DictionaryValue* os_value = NULL;
144 if (value->GetDictionary("os", &os_value)) {
145 std::string os_type;
146 std::string os_version_op = "any";
147 std::string os_version_string;
148 std::string os_version_string2;
149 os_value->GetString("type", &os_type);
150 DictionaryValue* os_version_value = NULL;
151 if (os_value->GetDictionary("version", &os_version_value)) {
152 os_version_value->GetString("op", &os_version_op);
153 os_version_value->GetString("number", &os_version_string);
154 os_version_value->GetString("number2", &os_version_string2);
155 }
156 if (!entry->SetOsInfo(os_type, os_version_op, os_version_string,
157 os_version_string2)) {
158 delete entry;
159 return NULL;
160 }
161 }
162
163 std::string vendor_id;
164 if (value->GetString("vendor_id", &vendor_id)) {
165 if (!entry->SetVendorId(vendor_id)) {
166 delete entry;
167 return NULL;
168 }
169 }
170
171 std::string device_id;
172 if (value->GetString("device_id", &device_id)) {
173 if (!entry->SetDeviceId(device_id)) {
174 delete entry;
175 return NULL;
176 }
177 }
178
179 DictionaryValue* driver_version_value = NULL;
180 if (value->GetDictionary("driver_version", &driver_version_value)) {
181 std::string driver_version_op = "any";
182 std::string driver_version_string;
183 std::string driver_version_string2;
184 driver_version_value->GetString("op", &driver_version_op);
185 driver_version_value->GetString("number", &driver_version_string);
186 driver_version_value->GetString("number2", &driver_version_string2);
187 if (!entry->SetDriverVersionInfo(driver_version_op, driver_version_string,
188 driver_version_string2)) {
189 delete entry;
190 return NULL;
191 }
192 }
193
194 ListValue* blacklist_value = NULL;
195 if (!value->GetList("blacklist", &blacklist_value)) {
196 delete entry;
197 return NULL;
198 }
199 std::vector<std::string> blacklist;
200 for (size_t i = 0; i < blacklist_value->GetSize(); ++i) {
201 std::string feature;
202 if (blacklist_value->GetString(i, &feature)) {
203 blacklist.push_back(feature);
204 } else {
205 delete entry;
206 return NULL;
207 }
208 }
209 if (!entry->SetBlacklistedFeatures(blacklist)) {
210 delete entry;
211 return NULL;
212 }
213
214 return entry;
215 }
216
217 GpuBlacklist::GpuBlacklistEntry::GpuBlacklistEntry()
218 : vendor_id_(0),
219 device_id_(0) {
220 }
221
222 bool GpuBlacklist::GpuBlacklistEntry::SetOsInfo(
223 const std::string& os,
224 const std::string& version_op,
225 const std::string& version_string,
226 const std::string& version_string2) {
227 os_info_.reset(new OsInfo(os, version_op, version_string, version_string2));
228 return os_info_->IsValid();
229 }
230
231 bool GpuBlacklist::GpuBlacklistEntry::SetVendorId(
232 const std::string& vendor_id_string) {
233 vendor_id_ = 0;
234 return base::HexStringToInt(vendor_id_string,
235 reinterpret_cast<int*>(&vendor_id_));
236 }
237
238 bool GpuBlacklist::GpuBlacklistEntry::SetDeviceId(
239 const std::string& device_id_string) {
240 device_id_ = 0;
241 return base::HexStringToInt(device_id_string,
242 reinterpret_cast<int*>(&device_id_));
243 }
244
245 bool GpuBlacklist::GpuBlacklistEntry::SetDriverVersionInfo(
246 const std::string& version_op,
247 const std::string& version_string,
248 const std::string& version_string2) {
249 driver_version_info_.reset(
250 new VersionInfo(version_op, version_string, version_string2));
251 return driver_version_info_->IsValid();
252 }
253
254 bool GpuBlacklist::GpuBlacklistEntry::SetBlacklistedFeatures(
255 const std::vector<std::string>& blacklisted_features) {
256 size_t size = blacklisted_features.size();
257 if (size == 0)
258 return false;
259 uint32 flags = 0;
260 for (size_t i = 0; i < size; ++i) {
261 GpuFeatureFlags::GpuFeatureType type =
262 GpuFeatureFlags::StringToGpuFeatureType(blacklisted_features[i]);
263 switch (type) {
264 case GpuFeatureFlags::kGpuFeatureAccelerated2dCanvas:
265 case GpuFeatureFlags::kGpuFeatureAcceleratedCompositing:
266 case GpuFeatureFlags::kGpuFeatureWebgl:
267 case GpuFeatureFlags::kGpuFeatureAll:
268 flags |= type;
269 break;
270 case GpuFeatureFlags::kGpuFeatureUnknown:
271 return false;
272 }
273 }
274 feature_flags_.reset(new GpuFeatureFlags());
275 feature_flags_->set_flags(flags);
276 return true;
277 }
278
279 bool GpuBlacklist::GpuBlacklistEntry::Contains(
280 OsType os_type, const Version& os_version,
281 uint32 vendor_id, uint32 device_id,
282 const Version& driver_version) const {
283 DCHECK(os_type != kOsAny);
284 if (os_info_.get() != NULL && !os_info_->Contains(os_type, os_version))
285 return false;
286 if (vendor_id_ != 0 && vendor_id_ != vendor_id)
287 return false;
288 if (device_id_ != 0 && device_id_ != device_id)
289 return false;
290 if (driver_version_info_.get() == NULL)
291 return true;
292 return driver_version_info_->Contains(driver_version);
293 }
294
295 GpuBlacklist::OsType GpuBlacklist::GpuBlacklistEntry::GetOsType() const {
296 if (os_info_.get() == NULL)
297 return kOsUnknown;
298 return os_info_->type();
299 }
300
301 GpuFeatureFlags GpuBlacklist::GpuBlacklistEntry::GetGpuFeatureFlags() const {
302 return *feature_flags_;
303 }
304
305 GpuBlacklist::GpuBlacklist() {
306 }
307
308 GpuBlacklist::~GpuBlacklist() {
309 Clear();
310 }
311
312 bool GpuBlacklist::LoadGpuBlacklist(const std::string& json_context,
313 bool current_os_only) {
314 std::vector<GpuBlacklistEntry*> entries;
315 scoped_ptr<Value> root;
316 root.reset(base::JSONReader::Read(json_context, false));
317 if (root.get() == NULL || !root->IsType(Value::TYPE_DICTIONARY))
318 return false;
319
320 ListValue* list = NULL;
321 static_cast<DictionaryValue*>(root.get())->GetList("entries", &list);
322 if (list == NULL)
323 return false;
324
325 for (size_t i = 0; i < list->GetSize(); ++i) {
326 DictionaryValue* list_item = NULL;
327 bool valid = list->GetDictionary(i, &list_item);
328 if (!valid)
329 break;
330 GpuBlacklistEntry* entry =
331 GpuBlacklistEntry::GetGpuBlacklistEntryFromValue(list_item);
332 if (entry == NULL)
333 break;
334 entries.push_back(entry);
335 }
336
337 if (entries.size() < list->GetSize()) {
338 for (size_t i = 0; i < entries.size(); ++i)
339 delete entries[i];
340 return false;
341 }
342
343 Clear();
344 // Don't apply GPU blacklist for a non-registered OS.
345 OsType os_filter = GetOsType();
346 if (os_filter != kOsUnknown) {
347 for (size_t i = 0; i < entries.size(); ++i) {
348 OsType entry_os = entries[i]->GetOsType();
349 if (!current_os_only ||
350 entry_os == kOsAny || entry_os == os_filter)
351 blacklist_.push_back(entries[i]);
352 }
353 }
354 return true;
355 }
356
357 GpuFeatureFlags GpuBlacklist::DetermineGpuFeatureFlags(
358 GpuBlacklist::OsType os,
359 Version* os_version,
360 const GPUInfo& gpu_info) const {
361 GpuFeatureFlags flags;
362 // No need to go through blacklist entries if GPUInfo isn't available.
363 if (gpu_info.progress() == GPUInfo::kUninitialized)
364 return flags;
365 scoped_ptr<Version> driver_version(
366 Version::GetVersionFromString(gpu_info.driver_version()));
367 if (driver_version.get() == NULL)
368 return flags;
369
370 if (os == kOsAny)
371 os = GetOsType();
372 scoped_ptr<Version> my_os_version;
373 if (os_version == NULL) {
374 std::string version_string;
375 #if defined(OS_MACOSX)
376 // Seems like base::SysInfo::OperatingSystemVersion() returns the wrong
377 // version in MacOsx.
378 int32 version_major, version_minor, version_bugfix;
379 base::SysInfo::OperatingSystemVersionNumbers(
380 &version_major, &version_minor, &version_bugfix);
381 version_string = base::StringPrintf("%d.%d.%d",
382 version_major,
383 version_minor,
384 version_bugfix);
385 #else
386 version_string = base::SysInfo::OperatingSystemVersion();
387 #endif
388 my_os_version.reset(Version::GetVersionFromString(version_string));
389 os_version = my_os_version.get();
390 }
391 DCHECK(os_version != NULL);
392
393 for (size_t i = 0; i < blacklist_.size(); ++i) {
394 if (blacklist_[i]->Contains(os, *os_version,
395 gpu_info.vendor_id(), gpu_info.device_id(),
396 *driver_version)) {
397 flags.Combine(blacklist_[i]->GetGpuFeatureFlags());
398 }
399 }
400 return flags;
401 }
402
403 GpuBlacklist::OsType GpuBlacklist::GetOsType() {
404 #if defined(OS_WIN)
405 return kOsWin;
406 #elif defined(OS_LINUX)
407 return kOsLinux;
408 #elif defined(OS_MACOSX)
409 return kOsMacosx;
410 #else
411 return kOsUnknown;
412 #endif
413 }
414
415 void GpuBlacklist::Clear() {
416 for (size_t i = 0; i < blacklist_.size(); ++i)
417 delete blacklist_[i];
418 blacklist_.clear();
419 }
420
OLDNEW
« no previous file with comments | « chrome/browser/gpu_blacklist.h ('k') | chrome/browser/gpu_blacklist_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698