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

Side by Side Diff: content/browser/gpu/gpu_blacklist.cc

Issue 10907098: Revert 155218 - Move gpu blacklist to content side. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 3 months 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 | « content/browser/gpu/gpu_blacklist.h ('k') | content/browser/gpu/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) 2012 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 "content/browser/gpu/gpu_blacklist.h"
6
7 #include "base/command_line.h"
8 #include "base/json/json_reader.h"
9 #include "base/logging.h"
10 #include "base/string_number_conversions.h"
11 #include "base/string_split.h"
12 #include "base/string_util.h"
13 #include "base/sys_info.h"
14 #include "base/version.h"
15 #include "content/browser/gpu/gpu_util.h"
16 #include "content/public/common/content_switches.h"
17 #include "content/public/common/gpu_info.h"
18
19 using content::GpuFeatureType;
20
21 namespace {
22
23 // 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 // TODO(zmo): verify if in Windows registry, driver dates are always in the
26 // format of "mm-dd-yyyy".
27 std::vector<std::string> pieces;
28 base::SplitString(date_string, '-', &pieces);
29 if (pieces.size() != 3) {
30 *version = Version();
31 return;
32 }
33 std::string date_as_version_string = pieces[2];
34 for (size_t i = 0; i < 2; ++i) {
35 date_as_version_string += ".";
36 date_as_version_string += pieces[i];
37 }
38 *version = Version(date_as_version_string);
39 }
40
41 // We assume the input format is major.minor, and we treat major version
42 // as numerical and minor as lexical.
43 // Otherwise we simply return the original string.
44 // For example, if input numerical is 8.103, returned lexical is 8.1.0.3.
45 std::string NumericalToLexical(const std::string& numerical) {
46 std::string lexical;
47 bool valid = true;
48 size_t pos = numerical.find_first_of('.');
49 if (pos != std::string::npos && pos + 1 < numerical.length()) {
50 lexical = numerical.substr(0, pos);
51 for (size_t i = pos + 1; i < numerical.length(); ++i) {
52 if (!IsAsciiDigit(numerical[i])) {
53 valid = false;
54 break;
55 }
56 lexical += '.';
57 lexical += numerical[i];
58 }
59 } else {
60 valid = false;
61 }
62 if (valid)
63 return lexical;
64 return numerical;
65 }
66
67 bool GpuUnmatched(uint32 vendor_id, const std::vector<uint32>& device_id_list,
68 const content::GPUInfo::GPUDevice& gpu) {
69 if (vendor_id == 0)
70 return false;
71 if (vendor_id != gpu.vendor_id)
72 return true;
73 bool device_specified = false;
74 for (size_t i = 0; i < device_id_list.size(); ++i) {
75 if (device_id_list[i] == 0)
76 continue;
77 if (device_id_list[i] == gpu.device_id)
78 return false;
79 device_specified = true;
80 }
81 return device_specified;
82 }
83
84 const char kMultiGpuStyleStringAMDSwitchable[] = "amd_switchable";
85 const char kMultiGpuStyleStringOptimus[] = "optimus";
86
87 const char kMultiGpuCategoryStringPrimary[] = "primary";
88 const char kMultiGpuCategoryStringSecondary[] = "secondary";
89 const char kMultiGpuCategoryStringAny[] = "any";
90
91 const char kVersionStyleStringNumerical[] = "numerical";
92 const char kVersionStyleStringLexical[] = "lexical";
93
94 } // namespace anonymous
95
96 GpuBlacklist::VersionInfo::VersionInfo(
97 const std::string& version_op,
98 const std::string& version_style,
99 const std::string& version_string,
100 const std::string& version_string2)
101 : version_style_(kVersionStyleNumerical) {
102 op_ = StringToNumericOp(version_op);
103 if (op_ == kUnknown || op_ == kAny)
104 return;
105 version_style_ = StringToVersionStyle(version_style);
106 std::string processed_version_string, processed_version_string2;
107 if (version_style_ == kVersionStyleLexical) {
108 processed_version_string = NumericalToLexical(version_string);
109 processed_version_string2 = NumericalToLexical(version_string2);
110 } else {
111 processed_version_string = version_string;
112 processed_version_string2 = version_string2;
113 }
114 version_.reset(new Version(processed_version_string));
115 if (!version_->IsValid()) {
116 op_ = kUnknown;
117 return;
118 }
119 if (op_ == kBetween) {
120 version2_.reset(new Version(processed_version_string2));
121 if (!version2_->IsValid())
122 op_ = kUnknown;
123 }
124 }
125
126 GpuBlacklist::VersionInfo::~VersionInfo() {
127 }
128
129 bool GpuBlacklist::VersionInfo::Contains(const Version& version) const {
130 if (op_ == kUnknown)
131 return false;
132 if (op_ == kAny)
133 return true;
134 if (op_ == kEQ) {
135 // Handles cases where 10.6 is considered as containing 10.6.*.
136 const std::vector<uint16>& components_reference = version_->components();
137 const std::vector<uint16>& components = version.components();
138 for (size_t i = 0; i < components_reference.size(); ++i) {
139 if (i >= components.size() && components_reference[i] != 0)
140 return false;
141 if (components[i] != components_reference[i])
142 return false;
143 }
144 return true;
145 }
146 int relation = version.CompareTo(*version_);
147 if (op_ == kEQ)
148 return (relation == 0);
149 else if (op_ == kLT)
150 return (relation < 0);
151 else if (op_ == kLE)
152 return (relation <= 0);
153 else if (op_ == kGT)
154 return (relation > 0);
155 else if (op_ == kGE)
156 return (relation >= 0);
157 // op_ == kBetween
158 if (relation < 0)
159 return false;
160 return version.CompareTo(*version2_) <= 0;
161 }
162
163 bool GpuBlacklist::VersionInfo::IsValid() const {
164 return (op_ != kUnknown && version_style_ != kVersionStyleUnknown);
165 }
166
167 bool GpuBlacklist::VersionInfo::IsLexical() const {
168 return version_style_ == kVersionStyleLexical;
169 }
170
171 // static
172 GpuBlacklist::VersionInfo::VersionStyle
173 GpuBlacklist::VersionInfo::StringToVersionStyle(
174 const std::string& version_style) {
175 if (version_style.empty() || version_style == kVersionStyleStringNumerical)
176 return kVersionStyleNumerical;
177 if (version_style == kVersionStyleStringLexical)
178 return kVersionStyleLexical;
179 return kVersionStyleUnknown;
180 }
181
182 GpuBlacklist::OsInfo::OsInfo(const std::string& os,
183 const std::string& version_op,
184 const std::string& version_string,
185 const std::string& version_string2) {
186 type_ = StringToOsType(os);
187 if (type_ != kOsUnknown) {
188 version_info_.reset(
189 new VersionInfo(version_op, "", version_string, version_string2));
190 }
191 }
192
193 GpuBlacklist::OsInfo::~OsInfo() {}
194
195 bool GpuBlacklist::OsInfo::Contains(OsType type,
196 const Version& version) const {
197 if (!IsValid())
198 return false;
199 if (type_ != type && type_ != kOsAny)
200 return false;
201 return version_info_->Contains(version);
202 }
203
204 bool GpuBlacklist::OsInfo::IsValid() const {
205 return type_ != kOsUnknown && version_info_->IsValid();
206 }
207
208 GpuBlacklist::OsType GpuBlacklist::OsInfo::type() const {
209 return type_;
210 }
211
212 GpuBlacklist::OsType GpuBlacklist::OsInfo::StringToOsType(
213 const std::string& os) {
214 if (os == "win")
215 return kOsWin;
216 else if (os == "macosx")
217 return kOsMacosx;
218 else if (os == "linux")
219 return kOsLinux;
220 else if (os == "chromeos")
221 return kOsChromeOS;
222 else if (os == "any")
223 return kOsAny;
224 return kOsUnknown;
225 }
226
227 GpuBlacklist::StringInfo::StringInfo(const std::string& string_op,
228 const std::string& string_value) {
229 op_ = StringToOp(string_op);
230 value_ = StringToLowerASCII(string_value);
231 }
232
233 bool GpuBlacklist::StringInfo::Contains(const std::string& value) const {
234 std::string my_value = StringToLowerASCII(value);
235 switch (op_) {
236 case kContains:
237 return strstr(my_value.c_str(), value_.c_str()) != NULL;
238 case kBeginWith:
239 return StartsWithASCII(my_value, value_, false);
240 case kEndWith:
241 return EndsWith(my_value, value_, false);
242 case kEQ:
243 return value_ == my_value;
244 default:
245 return false;
246 }
247 }
248
249 bool GpuBlacklist::StringInfo::IsValid() const {
250 return op_ != kUnknown;
251 }
252
253 GpuBlacklist::StringInfo::Op GpuBlacklist::StringInfo::StringToOp(
254 const std::string& string_op) {
255 if (string_op == "=")
256 return kEQ;
257 else if (string_op == "contains")
258 return kContains;
259 else if (string_op == "beginwith")
260 return kBeginWith;
261 else if (string_op == "endwith")
262 return kEndWith;
263 return kUnknown;
264 }
265
266 GpuBlacklist::FloatInfo::FloatInfo(const std::string& float_op,
267 const std::string& float_value,
268 const std::string& float_value2)
269 : op_(kUnknown),
270 value_(0.f),
271 value2_(0.f) {
272 double dvalue = 0;
273 if (!base::StringToDouble(float_value, &dvalue)) {
274 op_ = kUnknown;
275 return;
276 }
277 value_ = static_cast<float>(dvalue);
278 op_ = StringToNumericOp(float_op);
279 if (op_ == kBetween) {
280 if (!base::StringToDouble(float_value2, &dvalue)) {
281 op_ = kUnknown;
282 return;
283 }
284 value2_ = static_cast<float>(dvalue);
285 }
286 }
287
288 bool GpuBlacklist::FloatInfo::Contains(float value) const {
289 if (op_ == kUnknown)
290 return false;
291 if (op_ == kAny)
292 return true;
293 if (op_ == kEQ)
294 return (value == value_);
295 if (op_ == kLT)
296 return (value < value_);
297 if (op_ == kLE)
298 return (value <= value_);
299 if (op_ == kGT)
300 return (value > value_);
301 if (op_ == kGE)
302 return (value >= value_);
303 DCHECK(op_ == kBetween);
304 return ((value_ <= value && value <= value2_) ||
305 (value2_ <= value && value <= value_));
306 }
307
308 bool GpuBlacklist::FloatInfo::IsValid() const {
309 return op_ != kUnknown;
310 }
311
312 // static
313 GpuBlacklist::ScopedGpuBlacklistEntry
314 GpuBlacklist::GpuBlacklistEntry::GetGpuBlacklistEntryFromValue(
315 const DictionaryValue* value, bool top_level) {
316 DCHECK(value);
317 ScopedGpuBlacklistEntry entry(new GpuBlacklistEntry());
318
319 size_t dictionary_entry_count = 0;
320
321 if (top_level) {
322 uint32 id;
323 if (!value->GetInteger("id", reinterpret_cast<int*>(&id)) ||
324 !entry->SetId(id)) {
325 LOG(WARNING) << "Malformed id entry " << entry->id();
326 return NULL;
327 }
328 dictionary_entry_count++;
329
330 bool disabled;
331 if (value->GetBoolean("disabled", &disabled)) {
332 entry->SetDisabled(disabled);
333 dictionary_entry_count++;
334 }
335 }
336
337 std::string description;
338 if (value->GetString("description", &description)) {
339 entry->description_ = description;
340 dictionary_entry_count++;
341 } else {
342 entry->description_ = "The GPU is unavailable for an unexplained reason.";
343 }
344
345 const ListValue* cr_bugs;
346 if (value->GetList("cr_bugs", &cr_bugs)) {
347 for (size_t i = 0; i < cr_bugs->GetSize(); ++i) {
348 int bug_id;
349 if (cr_bugs->GetInteger(i, &bug_id)) {
350 entry->cr_bugs_.push_back(bug_id);
351 } else {
352 LOG(WARNING) << "Malformed cr_bugs entry " << entry->id();
353 return NULL;
354 }
355 }
356 dictionary_entry_count++;
357 }
358
359 const ListValue* webkit_bugs;
360 if (value->GetList("webkit_bugs", &webkit_bugs)) {
361 for (size_t i = 0; i < webkit_bugs->GetSize(); ++i) {
362 int bug_id;
363 if (webkit_bugs->GetInteger(i, &bug_id)) {
364 entry->webkit_bugs_.push_back(bug_id);
365 } else {
366 LOG(WARNING) << "Malformed webkit_bugs entry " << entry->id();
367 return NULL;
368 }
369 }
370 dictionary_entry_count++;
371 }
372
373 const DictionaryValue* os_value = NULL;
374 if (value->GetDictionary("os", &os_value)) {
375 std::string os_type;
376 std::string os_version_op = "any";
377 std::string os_version_string;
378 std::string os_version_string2;
379 os_value->GetString("type", &os_type);
380 const DictionaryValue* os_version_value = NULL;
381 if (os_value->GetDictionary("version", &os_version_value)) {
382 os_version_value->GetString("op", &os_version_op);
383 os_version_value->GetString("number", &os_version_string);
384 os_version_value->GetString("number2", &os_version_string2);
385 }
386 if (!entry->SetOsInfo(os_type, os_version_op, os_version_string,
387 os_version_string2)) {
388 LOG(WARNING) << "Malformed os entry " << entry->id();
389 return NULL;
390 }
391 dictionary_entry_count++;
392 }
393
394 std::string vendor_id;
395 if (value->GetString("vendor_id", &vendor_id)) {
396 if (!entry->SetVendorId(vendor_id)) {
397 LOG(WARNING) << "Malformed vendor_id entry " << entry->id();
398 return NULL;
399 }
400 dictionary_entry_count++;
401 }
402
403 const ListValue* device_id_list;
404 if (value->GetList("device_id", &device_id_list)) {
405 for (size_t i = 0; i < device_id_list->GetSize(); ++i) {
406 std::string device_id;
407 if (!device_id_list->GetString(i, &device_id) ||
408 !entry->AddDeviceId(device_id)) {
409 LOG(WARNING) << "Malformed device_id entry " << entry->id();
410 return NULL;
411 }
412 }
413 dictionary_entry_count++;
414 }
415
416 std::string multi_gpu_style;
417 if (value->GetString("multi_gpu_style", &multi_gpu_style)) {
418 if (!entry->SetMultiGpuStyle(multi_gpu_style)) {
419 LOG(WARNING) << "Malformed multi_gpu_style entry " << entry->id();
420 return NULL;
421 }
422 dictionary_entry_count++;
423 }
424
425 std::string multi_gpu_category;
426 if (value->GetString("multi_gpu_category", &multi_gpu_category)) {
427 if (!entry->SetMultiGpuCategory(multi_gpu_category)) {
428 LOG(WARNING) << "Malformed multi_gpu_category entry " << entry->id();
429 return NULL;
430 }
431 dictionary_entry_count++;
432 }
433
434 const DictionaryValue* driver_vendor_value = NULL;
435 if (value->GetDictionary("driver_vendor", &driver_vendor_value)) {
436 std::string vendor_op;
437 std::string vendor_value;
438 driver_vendor_value->GetString("op", &vendor_op);
439 driver_vendor_value->GetString("value", &vendor_value);
440 if (!entry->SetDriverVendorInfo(vendor_op, vendor_value)) {
441 LOG(WARNING) << "Malformed driver_vendor entry " << entry->id();
442 return NULL;
443 }
444 dictionary_entry_count++;
445 }
446
447 const DictionaryValue* driver_version_value = NULL;
448 if (value->GetDictionary("driver_version", &driver_version_value)) {
449 std::string driver_version_op = "any";
450 std::string driver_version_style;
451 std::string driver_version_string;
452 std::string driver_version_string2;
453 driver_version_value->GetString("op", &driver_version_op);
454 driver_version_value->GetString("style", &driver_version_style);
455 driver_version_value->GetString("number", &driver_version_string);
456 driver_version_value->GetString("number2", &driver_version_string2);
457 if (!entry->SetDriverVersionInfo(driver_version_op,
458 driver_version_style,
459 driver_version_string,
460 driver_version_string2)) {
461 LOG(WARNING) << "Malformed driver_version entry " << entry->id();
462 return NULL;
463 }
464 dictionary_entry_count++;
465 }
466
467 const DictionaryValue* driver_date_value = NULL;
468 if (value->GetDictionary("driver_date", &driver_date_value)) {
469 std::string driver_date_op = "any";
470 std::string driver_date_string;
471 std::string driver_date_string2;
472 driver_date_value->GetString("op", &driver_date_op);
473 driver_date_value->GetString("number", &driver_date_string);
474 driver_date_value->GetString("number2", &driver_date_string2);
475 if (!entry->SetDriverDateInfo(driver_date_op, driver_date_string,
476 driver_date_string2)) {
477 LOG(WARNING) << "Malformed driver_date entry " << entry->id();
478 return NULL;
479 }
480 dictionary_entry_count++;
481 }
482
483 const DictionaryValue* gl_vendor_value = NULL;
484 if (value->GetDictionary("gl_vendor", &gl_vendor_value)) {
485 std::string vendor_op;
486 std::string vendor_value;
487 gl_vendor_value->GetString("op", &vendor_op);
488 gl_vendor_value->GetString("value", &vendor_value);
489 if (!entry->SetGLVendorInfo(vendor_op, vendor_value)) {
490 LOG(WARNING) << "Malformed gl_vendor entry " << entry->id();
491 return NULL;
492 }
493 dictionary_entry_count++;
494 }
495
496 const DictionaryValue* gl_renderer_value = NULL;
497 if (value->GetDictionary("gl_renderer", &gl_renderer_value)) {
498 std::string renderer_op;
499 std::string renderer_value;
500 gl_renderer_value->GetString("op", &renderer_op);
501 gl_renderer_value->GetString("value", &renderer_value);
502 if (!entry->SetGLRendererInfo(renderer_op, renderer_value)) {
503 LOG(WARNING) << "Malformed gl_renderer entry " << entry->id();
504 return NULL;
505 }
506 dictionary_entry_count++;
507 }
508
509 const DictionaryValue* perf_graphics_value = NULL;
510 if (value->GetDictionary("perf_graphics", &perf_graphics_value)) {
511 std::string op;
512 std::string float_value;
513 std::string float_value2;
514 perf_graphics_value->GetString("op", &op);
515 perf_graphics_value->GetString("value", &float_value);
516 perf_graphics_value->GetString("value2", &float_value2);
517 if (!entry->SetPerfGraphicsInfo(op, float_value, float_value2)) {
518 LOG(WARNING) << "Malformed perf_graphics entry " << entry->id();
519 return NULL;
520 }
521 dictionary_entry_count++;
522 }
523
524 const DictionaryValue* perf_gaming_value = NULL;
525 if (value->GetDictionary("perf_gaming", &perf_gaming_value)) {
526 std::string op;
527 std::string float_value;
528 std::string float_value2;
529 perf_gaming_value->GetString("op", &op);
530 perf_gaming_value->GetString("value", &float_value);
531 perf_gaming_value->GetString("value2", &float_value2);
532 if (!entry->SetPerfGamingInfo(op, float_value, float_value2)) {
533 LOG(WARNING) << "Malformed perf_gaming entry " << entry->id();
534 return NULL;
535 }
536 dictionary_entry_count++;
537 }
538
539 const DictionaryValue* perf_overall_value = NULL;
540 if (value->GetDictionary("perf_overall", &perf_overall_value)) {
541 std::string op;
542 std::string float_value;
543 std::string float_value2;
544 perf_overall_value->GetString("op", &op);
545 perf_overall_value->GetString("value", &float_value);
546 perf_overall_value->GetString("value2", &float_value2);
547 if (!entry->SetPerfOverallInfo(op, float_value, float_value2)) {
548 LOG(WARNING) << "Malformed perf_overall entry " << entry->id();
549 return NULL;
550 }
551 dictionary_entry_count++;
552 }
553
554 if (top_level) {
555 const ListValue* blacklist_value = NULL;
556 if (!value->GetList("blacklist", &blacklist_value)) {
557 LOG(WARNING) << "Malformed blacklist entry " << entry->id();
558 return NULL;
559 }
560 std::vector<std::string> blacklist;
561 for (size_t i = 0; i < blacklist_value->GetSize(); ++i) {
562 std::string feature;
563 if (blacklist_value->GetString(i, &feature)) {
564 blacklist.push_back(feature);
565 } else {
566 LOG(WARNING) << "Malformed blacklist entry " << entry->id();
567 return NULL;
568 }
569 }
570 if (!entry->SetBlacklistedFeatures(blacklist)) {
571 LOG(WARNING) << "Malformed blacklist entry " << entry->id();
572 return NULL;
573 }
574 dictionary_entry_count++;
575 }
576
577 if (top_level) {
578 const ListValue* exception_list_value = NULL;
579 if (value->GetList("exceptions", &exception_list_value)) {
580 for (size_t i = 0; i < exception_list_value->GetSize(); ++i) {
581 const DictionaryValue* exception_value = NULL;
582 if (!exception_list_value->GetDictionary(i, &exception_value)) {
583 LOG(WARNING) << "Malformed exceptions entry " << entry->id();
584 return NULL;
585 }
586 ScopedGpuBlacklistEntry exception(
587 GetGpuBlacklistEntryFromValue(exception_value, false));
588 if (exception == NULL) {
589 LOG(WARNING) << "Malformed exceptions entry " << entry->id();
590 return NULL;
591 }
592 if (exception->contains_unknown_fields_) {
593 LOG(WARNING) << "Exception with unknown fields " << entry->id();
594 entry->contains_unknown_fields_ = true;
595 } else {
596 entry->AddException(exception);
597 }
598 }
599 dictionary_entry_count++;
600 }
601
602 const DictionaryValue* browser_version_value = NULL;
603 // browser_version is processed in LoadGpuBlacklist().
604 if (value->GetDictionary("browser_version", &browser_version_value))
605 dictionary_entry_count++;
606 }
607
608 if (value->size() != dictionary_entry_count) {
609 LOG(WARNING) << "Entry with unknown fields " << entry->id();
610 entry->contains_unknown_fields_ = true;
611 }
612 return entry;
613 }
614
615 GpuBlacklist::GpuBlacklistEntry::GpuBlacklistEntry()
616 : id_(0),
617 disabled_(false),
618 vendor_id_(0),
619 multi_gpu_style_(kMultiGpuStyleNone),
620 multi_gpu_category_(kMultiGpuCategoryPrimary),
621 feature_type_(content::GPU_FEATURE_TYPE_UNKNOWN),
622 contains_unknown_fields_(false),
623 contains_unknown_features_(false) {
624 }
625
626 GpuBlacklist::GpuBlacklistEntry::~GpuBlacklistEntry() { }
627
628 bool GpuBlacklist::GpuBlacklistEntry::SetId(uint32 id) {
629 if (id != 0) {
630 id_ = id;
631 return true;
632 }
633 return false;
634 }
635
636 void GpuBlacklist::GpuBlacklistEntry::SetDisabled(bool disabled) {
637 disabled_ = disabled;
638 }
639
640 bool GpuBlacklist::GpuBlacklistEntry::SetOsInfo(
641 const std::string& os,
642 const std::string& version_op,
643 const std::string& version_string,
644 const std::string& version_string2) {
645 os_info_.reset(new OsInfo(os, version_op, version_string, version_string2));
646 return os_info_->IsValid();
647 }
648
649 bool GpuBlacklist::GpuBlacklistEntry::SetVendorId(
650 const std::string& vendor_id_string) {
651 vendor_id_ = 0;
652 return base::HexStringToInt(vendor_id_string,
653 reinterpret_cast<int*>(&vendor_id_));
654 }
655
656 bool GpuBlacklist::GpuBlacklistEntry::AddDeviceId(
657 const std::string& device_id_string) {
658 uint32 device_id = 0;
659 if (base::HexStringToInt(device_id_string,
660 reinterpret_cast<int*>(&device_id))) {
661 device_id_list_.push_back(device_id);
662 return true;
663 }
664 return false;
665 }
666
667 bool GpuBlacklist::GpuBlacklistEntry::SetMultiGpuStyle(
668 const std::string& multi_gpu_style_string) {
669 MultiGpuStyle style = StringToMultiGpuStyle(multi_gpu_style_string);
670 if (style == kMultiGpuStyleNone)
671 return false;
672 multi_gpu_style_ = style;
673 return true;
674 }
675
676 bool GpuBlacklist::GpuBlacklistEntry::SetMultiGpuCategory(
677 const std::string& multi_gpu_category_string) {
678 MultiGpuCategory category =
679 StringToMultiGpuCategory(multi_gpu_category_string);
680 if (category == kMultiGpuCategoryNone)
681 return false;
682 multi_gpu_category_ = category;
683 return true;
684 }
685
686 bool GpuBlacklist::GpuBlacklistEntry::SetDriverVendorInfo(
687 const std::string& vendor_op,
688 const std::string& vendor_value) {
689 driver_vendor_info_.reset(
690 new StringInfo(vendor_op, vendor_value));
691 return driver_vendor_info_->IsValid();
692 }
693
694 bool GpuBlacklist::GpuBlacklistEntry::SetDriverVersionInfo(
695 const std::string& version_op,
696 const std::string& version_style,
697 const std::string& version_string,
698 const std::string& version_string2) {
699 driver_version_info_.reset(new VersionInfo(
700 version_op, version_style, version_string, version_string2));
701 return driver_version_info_->IsValid();
702 }
703
704 bool GpuBlacklist::GpuBlacklistEntry::SetDriverDateInfo(
705 const std::string& date_op,
706 const std::string& date_string,
707 const std::string& date_string2) {
708 driver_date_info_.reset(
709 new VersionInfo(date_op, "", date_string, date_string2));
710 return driver_date_info_->IsValid();
711 }
712
713 bool GpuBlacklist::GpuBlacklistEntry::SetGLVendorInfo(
714 const std::string& vendor_op,
715 const std::string& vendor_value) {
716 gl_vendor_info_.reset(
717 new StringInfo(vendor_op, vendor_value));
718 return gl_vendor_info_->IsValid();
719 }
720
721 bool GpuBlacklist::GpuBlacklistEntry::SetGLRendererInfo(
722 const std::string& renderer_op,
723 const std::string& renderer_value) {
724 gl_renderer_info_.reset(
725 new StringInfo(renderer_op, renderer_value));
726 return gl_renderer_info_->IsValid();
727 }
728
729 bool GpuBlacklist::GpuBlacklistEntry::SetPerfGraphicsInfo(
730 const std::string& op,
731 const std::string& float_string,
732 const std::string& float_string2) {
733 perf_graphics_info_.reset(
734 new FloatInfo(op, float_string, float_string2));
735 return perf_graphics_info_->IsValid();
736 }
737
738 bool GpuBlacklist::GpuBlacklistEntry::SetPerfGamingInfo(
739 const std::string& op,
740 const std::string& float_string,
741 const std::string& float_string2) {
742 perf_gaming_info_.reset(
743 new FloatInfo(op, float_string, float_string2));
744 return perf_gaming_info_->IsValid();
745 }
746
747 bool GpuBlacklist::GpuBlacklistEntry::SetPerfOverallInfo(
748 const std::string& op,
749 const std::string& float_string,
750 const std::string& float_string2) {
751 perf_overall_info_.reset(
752 new FloatInfo(op, float_string, float_string2));
753 return perf_overall_info_->IsValid();
754 }
755
756 bool GpuBlacklist::GpuBlacklistEntry::SetBlacklistedFeatures(
757 const std::vector<std::string>& blacklisted_features) {
758 size_t size = blacklisted_features.size();
759 if (size == 0)
760 return false;
761 int feature_type = content::GPU_FEATURE_TYPE_UNKNOWN;
762 for (size_t i = 0; i < size; ++i) {
763 GpuFeatureType type =
764 gpu_util::StringToGpuFeatureType(blacklisted_features[i]);
765 switch (type) {
766 case content::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS:
767 case content::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING:
768 case content::GPU_FEATURE_TYPE_WEBGL:
769 case content::GPU_FEATURE_TYPE_MULTISAMPLING:
770 case content::GPU_FEATURE_TYPE_FLASH3D:
771 case content::GPU_FEATURE_TYPE_FLASH_STAGE3D:
772 case content::GPU_FEATURE_TYPE_TEXTURE_SHARING:
773 case content::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE:
774 case content::GPU_FEATURE_TYPE_ALL:
775 feature_type |= type;
776 break;
777 case content::GPU_FEATURE_TYPE_UNKNOWN:
778 contains_unknown_features_ = true;
779 break;
780 }
781 }
782 feature_type_ = static_cast<GpuFeatureType>(feature_type);
783 return true;
784 }
785
786 void GpuBlacklist::GpuBlacklistEntry::AddException(
787 ScopedGpuBlacklistEntry exception) {
788 exceptions_.push_back(exception);
789 }
790
791 // static
792 GpuBlacklist::GpuBlacklistEntry::MultiGpuStyle
793 GpuBlacklist::GpuBlacklistEntry::StringToMultiGpuStyle(
794 const std::string& style) {
795 if (style == kMultiGpuStyleStringOptimus)
796 return kMultiGpuStyleOptimus;
797 if (style == kMultiGpuStyleStringAMDSwitchable)
798 return kMultiGpuStyleAMDSwitchable;
799 return kMultiGpuStyleNone;
800 }
801
802 // static
803 GpuBlacklist::GpuBlacklistEntry::MultiGpuCategory
804 GpuBlacklist::GpuBlacklistEntry::StringToMultiGpuCategory(
805 const std::string& category) {
806 if (category == kMultiGpuCategoryStringPrimary)
807 return kMultiGpuCategoryPrimary;
808 if (category == kMultiGpuCategoryStringSecondary)
809 return kMultiGpuCategorySecondary;
810 if (category == kMultiGpuCategoryStringAny)
811 return kMultiGpuCategoryAny;
812 return kMultiGpuCategoryNone;
813 }
814
815 bool GpuBlacklist::GpuBlacklistEntry::Contains(
816 OsType os_type, const Version& os_version,
817 const content::GPUInfo& gpu_info) const {
818 DCHECK(os_type != kOsAny);
819 if (os_info_.get() != NULL && !os_info_->Contains(os_type, os_version))
820 return false;
821 bool is_not_primary_gpu =
822 GpuUnmatched(vendor_id_, device_id_list_, gpu_info.gpu);
823 bool is_not_secondary_gpu = true;
824 for (size_t i = 0; i < gpu_info.secondary_gpus.size(); ++i) {
825 is_not_secondary_gpu = is_not_secondary_gpu &&
826 GpuUnmatched(vendor_id_, device_id_list_, gpu_info.secondary_gpus[i]);
827 }
828 switch (multi_gpu_category_) {
829 case kMultiGpuCategoryPrimary:
830 if (is_not_primary_gpu)
831 return false;
832 break;
833 case kMultiGpuCategorySecondary:
834 if (is_not_secondary_gpu)
835 return false;
836 break;
837 case kMultiGpuCategoryAny:
838 if (is_not_primary_gpu && is_not_secondary_gpu)
839 return false;
840 break;
841 default:
842 break;
843 }
844 switch (multi_gpu_style_) {
845 case kMultiGpuStyleOptimus:
846 if (!gpu_info.optimus)
847 return false;
848 break;
849 case kMultiGpuStyleAMDSwitchable:
850 if (!gpu_info.amd_switchable)
851 return false;
852 break;
853 default:
854 break;
855 }
856 if (driver_vendor_info_.get() != NULL &&
857 !driver_vendor_info_->Contains(gpu_info.driver_vendor))
858 return false;
859 if (driver_version_info_.get() != NULL) {
860 std::string processed_driver_version;
861 if (driver_version_info_->IsLexical())
862 processed_driver_version = NumericalToLexical(gpu_info.driver_version);
863 else
864 processed_driver_version = gpu_info.driver_version;
865 Version driver_version(processed_driver_version);
866 if (!driver_version.IsValid() ||
867 !driver_version_info_->Contains(driver_version))
868 return false;
869 }
870 if (driver_date_info_.get() != NULL) {
871 Version driver_date;
872 GetDateFromString(gpu_info.driver_date, &driver_date);
873 if (!driver_date.IsValid() || !driver_date_info_->Contains(driver_date))
874 return false;
875 }
876 if (gl_vendor_info_.get() != NULL &&
877 !gl_vendor_info_->Contains(gpu_info.gl_vendor))
878 return false;
879 if (gl_renderer_info_.get() != NULL &&
880 !gl_renderer_info_->Contains(gpu_info.gl_renderer))
881 return false;
882 if (perf_graphics_info_.get() != NULL &&
883 (gpu_info.performance_stats.graphics == 0.0 ||
884 !perf_graphics_info_->Contains(gpu_info.performance_stats.graphics)))
885 return false;
886 if (perf_gaming_info_.get() != NULL &&
887 (gpu_info.performance_stats.gaming == 0.0 ||
888 !perf_gaming_info_->Contains(gpu_info.performance_stats.gaming)))
889 return false;
890 if (perf_overall_info_.get() != NULL &&
891 (gpu_info.performance_stats.overall == 0.0 ||
892 !perf_overall_info_->Contains(gpu_info.performance_stats.overall)))
893 return false;
894 for (size_t i = 0; i < exceptions_.size(); ++i) {
895 if (exceptions_[i]->Contains(os_type, os_version, gpu_info))
896 return false;
897 }
898 return true;
899 }
900
901 GpuBlacklist::OsType GpuBlacklist::GpuBlacklistEntry::GetOsType() const {
902 if (os_info_.get() == NULL)
903 return kOsAny;
904 return os_info_->type();
905 }
906
907 uint32 GpuBlacklist::GpuBlacklistEntry::id() const {
908 return id_;
909 }
910
911 bool GpuBlacklist::GpuBlacklistEntry::disabled() const {
912 return disabled_;
913 }
914
915 GpuFeatureType GpuBlacklist::GpuBlacklistEntry::GetGpuFeatureType() const {
916 return feature_type_;
917 }
918
919 GpuBlacklist::GpuBlacklist()
920 : max_entry_id_(0),
921 contains_unknown_fields_(false) {
922 }
923
924 GpuBlacklist::~GpuBlacklist() {
925 Clear();
926 }
927
928 bool GpuBlacklist::LoadGpuBlacklist(
929 const std::string& json_context, GpuBlacklist::OsFilter os_filter) {
930 const std::string browser_version_string = "0";
931 return LoadGpuBlacklist(browser_version_string, json_context, os_filter);
932 }
933
934 bool GpuBlacklist::LoadGpuBlacklist(
935 const std::string& browser_version_string,
936 const std::string& json_context,
937 GpuBlacklist::OsFilter os_filter) {
938 browser_version_.reset(new Version(browser_version_string));
939 DCHECK(browser_version_->IsValid());
940
941 scoped_ptr<Value> root;
942 root.reset(base::JSONReader::Read(json_context));
943 if (root.get() == NULL || !root->IsType(Value::TYPE_DICTIONARY))
944 return false;
945
946 DictionaryValue* root_dictionary = static_cast<DictionaryValue*>(root.get());
947 DCHECK(root_dictionary);
948 return LoadGpuBlacklist(*root_dictionary, os_filter);
949 }
950
951 bool GpuBlacklist::LoadGpuBlacklist(
952 const DictionaryValue& parsed_json, GpuBlacklist::OsFilter os_filter) {
953 std::vector<ScopedGpuBlacklistEntry> entries;
954
955 std::string version_string;
956 parsed_json.GetString("version", &version_string);
957 version_.reset(new Version(version_string));
958 if (!version_->IsValid())
959 return false;
960
961 const ListValue* list = NULL;
962 if (!parsed_json.GetList("entries", &list))
963 return false;
964
965 uint32 max_entry_id = 0;
966 bool contains_unknown_fields = false;
967 for (size_t i = 0; i < list->GetSize(); ++i) {
968 const DictionaryValue* list_item = NULL;
969 bool valid = list->GetDictionary(i, &list_item);
970 if (!valid || list_item == NULL)
971 return false;
972 // Check browser version compatibility: if the entry is not for the
973 // current browser version, don't process it.
974 BrowserVersionSupport browser_version_support =
975 IsEntrySupportedByCurrentBrowserVersion(list_item);
976 if (browser_version_support == kMalformed)
977 return false;
978 if (browser_version_support == kUnsupported)
979 continue;
980 DCHECK(browser_version_support == kSupported);
981 ScopedGpuBlacklistEntry entry(
982 GpuBlacklistEntry::GetGpuBlacklistEntryFromValue(list_item, true));
983 if (entry == NULL)
984 return false;
985 if (entry->id() > max_entry_id)
986 max_entry_id = entry->id();
987 // If an unknown field is encountered, skip the entry; if an unknown
988 // feature is encountered, ignore the feature, but keep the entry.
989 if (entry->contains_unknown_fields()) {
990 contains_unknown_fields = true;
991 continue;
992 }
993 if (entry->contains_unknown_features())
994 contains_unknown_fields = true;
995 entries.push_back(entry);
996 }
997
998 Clear();
999 OsType my_os = GetOsType();
1000 for (size_t i = 0; i < entries.size(); ++i) {
1001 OsType entry_os = entries[i]->GetOsType();
1002 if (os_filter == GpuBlacklist::kAllOs ||
1003 entry_os == kOsAny || entry_os == my_os)
1004 blacklist_.push_back(entries[i]);
1005 }
1006 max_entry_id_ = max_entry_id;
1007 contains_unknown_fields_ = contains_unknown_fields;
1008 return true;
1009 }
1010
1011 GpuFeatureType GpuBlacklist::DetermineGpuFeatureType(
1012 GpuBlacklist::OsType os,
1013 Version* os_version,
1014 const content::GPUInfo& gpu_info) {
1015 active_entries_.clear();
1016 int type = 0;
1017
1018 if (os == kOsAny)
1019 os = GetOsType();
1020 scoped_ptr<Version> my_os_version;
1021 if (os_version == NULL) {
1022 std::string version_string = base::SysInfo::OperatingSystemVersion();
1023 size_t pos = version_string.find_first_not_of("0123456789.");
1024 if (pos != std::string::npos)
1025 version_string = version_string.substr(0, pos);
1026 my_os_version.reset(new Version(version_string));
1027 os_version = my_os_version.get();
1028 }
1029 DCHECK(os_version != NULL);
1030
1031 for (size_t i = 0; i < blacklist_.size(); ++i) {
1032 if (blacklist_[i]->Contains(os, *os_version, gpu_info)) {
1033 if (!blacklist_[i]->disabled())
1034 type |= blacklist_[i]->GetGpuFeatureType();
1035 active_entries_.push_back(blacklist_[i]);
1036 }
1037 }
1038 return static_cast<GpuFeatureType>(type);
1039 }
1040
1041 void GpuBlacklist::GetGpuFeatureTypeEntries(
1042 content::GpuFeatureType feature,
1043 std::vector<uint32>& entry_ids,
1044 bool disabled) const {
1045 entry_ids.clear();
1046 for (size_t i = 0; i < active_entries_.size(); ++i) {
1047 if (((feature & active_entries_[i]->GetGpuFeatureType()) != 0) &&
1048 disabled == active_entries_[i]->disabled())
1049 entry_ids.push_back(active_entries_[i]->id());
1050 }
1051 }
1052
1053 void GpuBlacklist::GetBlacklistReasons(ListValue* problem_list) const {
1054 DCHECK(problem_list);
1055 for (size_t i = 0; i < active_entries_.size(); ++i) {
1056 GpuBlacklistEntry* entry = active_entries_[i];
1057 if (entry->disabled())
1058 continue;
1059 DictionaryValue* problem = new DictionaryValue();
1060
1061 problem->SetString("description", entry->description());
1062
1063 ListValue* cr_bugs = new ListValue();
1064 for (size_t j = 0; j < entry->cr_bugs().size(); ++j)
1065 cr_bugs->Append(Value::CreateIntegerValue(entry->cr_bugs()[j]));
1066 problem->Set("crBugs", cr_bugs);
1067
1068 ListValue* webkit_bugs = new ListValue();
1069 for (size_t j = 0; j < entry->webkit_bugs().size(); ++j) {
1070 webkit_bugs->Append(Value::CreateIntegerValue(
1071 entry->webkit_bugs()[j]));
1072 }
1073 problem->Set("webkitBugs", webkit_bugs);
1074
1075 problem_list->Append(problem);
1076 }
1077 }
1078
1079 size_t GpuBlacklist::num_entries() const {
1080 return blacklist_.size();
1081 }
1082
1083 uint32 GpuBlacklist::max_entry_id() const {
1084 return max_entry_id_;
1085 }
1086
1087 std::string GpuBlacklist::GetVersion() const {
1088 if (version_.get() == NULL)
1089 return std::string();
1090 const std::vector<uint16>& components_reference = version_->components();
1091 if (components_reference.size() != 2)
1092 return std::string();
1093
1094 std::string version_string =
1095 base::UintToString(static_cast<unsigned>(components_reference[0])) +
1096 "." +
1097 base::UintToString(static_cast<unsigned>(components_reference[1]));
1098 return version_string;
1099 }
1100
1101 GpuBlacklist::OsType GpuBlacklist::GetOsType() {
1102 #if defined(OS_CHROMEOS)
1103 return kOsChromeOS;
1104 #elif defined(OS_WIN)
1105 return kOsWin;
1106 #elif defined(OS_LINUX) || defined(OS_OPENBSD)
1107 return kOsLinux;
1108 #elif defined(OS_MACOSX)
1109 return kOsMacosx;
1110 #else
1111 return kOsUnknown;
1112 #endif
1113 }
1114
1115 void GpuBlacklist::Clear() {
1116 blacklist_.clear();
1117 active_entries_.clear();
1118 max_entry_id_ = 0;
1119 contains_unknown_fields_ = false;
1120 }
1121
1122 GpuBlacklist::BrowserVersionSupport
1123 GpuBlacklist::IsEntrySupportedByCurrentBrowserVersion(
1124 const DictionaryValue* value) {
1125 DCHECK(value);
1126 const DictionaryValue* browser_version_value = NULL;
1127 if (value->GetDictionary("browser_version", &browser_version_value)) {
1128 std::string version_op = "any";
1129 std::string version_string;
1130 std::string version_string2;
1131 browser_version_value->GetString("op", &version_op);
1132 browser_version_value->GetString("number", &version_string);
1133 browser_version_value->GetString("number2", &version_string2);
1134 scoped_ptr<VersionInfo> browser_version_info;
1135 browser_version_info.reset(
1136 new VersionInfo(version_op, "", version_string, version_string2));
1137 if (!browser_version_info->IsValid())
1138 return kMalformed;
1139 if (browser_version_info->Contains(*browser_version_))
1140 return kSupported;
1141 return kUnsupported;
1142 }
1143 return kSupported;
1144 }
1145
1146 // static
1147 GpuBlacklist::NumericOp GpuBlacklist::StringToNumericOp(
1148 const std::string& op) {
1149 if (op == "=")
1150 return kEQ;
1151 if (op == "<")
1152 return kLT;
1153 if (op == "<=")
1154 return kLE;
1155 if (op == ">")
1156 return kGT;
1157 if (op == ">=")
1158 return kGE;
1159 if (op == "any")
1160 return kAny;
1161 if (op == "between")
1162 return kBetween;
1163 return kUnknown;
1164 }
OLDNEW
« no previous file with comments | « content/browser/gpu/gpu_blacklist.h ('k') | content/browser/gpu/gpu_blacklist_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698