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

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

Issue 12976004: Generalzie GpuBlacklist to GpuControlList. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 7 years, 9 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/cpu.h" 7 #include "content/public/common/gpu_feature_type.h"
8 #include "base/json/json_reader.h"
9 #include "base/logging.h"
10 #include "base/string_number_conversions.h"
11 #include "base/string_util.h"
12 #include "base/strings/string_split.h"
13 #include "base/sys_info.h"
14 #include "content/browser/gpu/gpu_util.h"
15 #include "content/public/common/gpu_info.h"
16 8
17 namespace content { 9 namespace content {
18 namespace {
19 10
20 // Break a version string into segments. Return true if each segment is 11 GpuBlacklist::GpuBlacklist()
21 // a valid number. 12 : GpuControlList() {
22 bool ProcessVersionString(const std::string& version_string,
23 char splitter,
24 std::vector<std::string>* version) {
25 DCHECK(version);
26 base::SplitString(version_string, splitter, version);
27 if (version->size() == 0)
28 return false;
29 // If the splitter is '-', we assume it's a date with format "mm-dd-yyyy";
30 // we split it into the order of "yyyy", "mm", "dd".
31 if (splitter == '-') {
32 std::string year = (*version)[version->size() - 1];
33 for (int i = version->size() - 1; i > 0; --i) {
34 (*version)[i] = (*version)[i - 1];
35 }
36 (*version)[0] = year;
37 }
38 for (size_t i = 0; i < version->size(); ++i) {
39 unsigned num = 0;
40 if (!base::StringToUint((*version)[i], &num))
41 return false;
42 }
43 return true;
44 } 13 }
45 14
46 // Compare two number strings using numerical ordering. 15 GpuBlacklist::~GpuBlacklist() {
47 // Return 0 if number = number_ref,
48 // 1 if number > number_ref,
49 // -1 if number < number_ref.
50 int CompareNumericalNumberStrings(
51 const std::string& number, const std::string& number_ref) {
52 unsigned value1 = 0;
53 unsigned value2 = 0;
54 bool valid = base::StringToUint(number, &value1);
55 DCHECK(valid);
56 valid = base::StringToUint(number_ref, &value2);
57 DCHECK(valid);
58 if (value1 == value2)
59 return 0;
60 if (value1 > value2)
61 return 1;
62 return -1;
63 }
64
65 // Compare two number strings using lexical ordering.
66 // Return 0 if number = number_ref,
67 // 1 if number > number_ref,
68 // -1 if number < number_ref.
69 // We only compare as many digits as number_ref contains.
70 // If number_ref is xxx, it's considered as xxx*
71 // For example: CompareLexicalNumberStrings("121", "12") returns 0,
72 // CompareLexicalNumberStrings("12", "121") returns -1.
73 int CompareLexicalNumberStrings(
74 const std::string& number, const std::string& number_ref) {
75 for (size_t i = 0; i < number_ref.length(); ++i) {
76 unsigned value1 = 0;
77 if (i < number.length())
78 value1 = number[i] - '0';
79 unsigned value2 = number_ref[i] - '0';
80 if (value1 > value2)
81 return 1;
82 if (value1 < value2)
83 return -1;
84 }
85 return 0;
86 }
87
88 bool GpuUnmatched(uint32 vendor_id, const std::vector<uint32>& device_id_list,
89 const GPUInfo::GPUDevice& gpu) {
90 if (vendor_id == 0)
91 return false;
92 if (vendor_id != gpu.vendor_id)
93 return true;
94 bool device_specified = false;
95 for (size_t i = 0; i < device_id_list.size(); ++i) {
96 if (device_id_list[i] == 0)
97 continue;
98 if (device_id_list[i] == gpu.device_id)
99 return false;
100 device_specified = true;
101 }
102 return device_specified;
103 }
104
105 const char kMultiGpuStyleStringAMDSwitchable[] = "amd_switchable";
106 const char kMultiGpuStyleStringOptimus[] = "optimus";
107
108 const char kMultiGpuCategoryStringPrimary[] = "primary";
109 const char kMultiGpuCategoryStringSecondary[] = "secondary";
110 const char kMultiGpuCategoryStringAny[] = "any";
111
112 const char kVersionStyleStringNumerical[] = "numerical";
113 const char kVersionStyleStringLexical[] = "lexical";
114
115 const char kOp[] = "op";
116
117 } // namespace anonymous
118
119 GpuBlacklist::VersionInfo::VersionInfo(
120 const std::string& version_op,
121 const std::string& version_style,
122 const std::string& version_string,
123 const std::string& version_string2)
124 : version_style_(kVersionStyleNumerical) {
125 op_ = StringToNumericOp(version_op);
126 if (op_ == kUnknown || op_ == kAny)
127 return;
128 version_style_ = StringToVersionStyle(version_style);
129 if (!ProcessVersionString(version_string, '.', &version_)) {
130 op_ = kUnknown;
131 return;
132 }
133 if (op_ == kBetween) {
134 if (!ProcessVersionString(version_string2, '.', &version2_))
135 op_ = kUnknown;
136 }
137 }
138
139 GpuBlacklist::VersionInfo::~VersionInfo() {
140 }
141
142 bool GpuBlacklist::VersionInfo::Contains(
143 const std::string& version_string) const {
144 return Contains(version_string, '.');
145 }
146
147 bool GpuBlacklist::VersionInfo::Contains(
148 const std::string& version_string, char splitter) const {
149 if (op_ == kUnknown)
150 return false;
151 if (op_ == kAny)
152 return true;
153 std::vector<std::string> version;
154 if (!ProcessVersionString(version_string, splitter, &version))
155 return false;
156 int relation = Compare(version, version_, version_style_);
157 if (op_ == kEQ)
158 return (relation == 0);
159 else if (op_ == kLT)
160 return (relation < 0);
161 else if (op_ == kLE)
162 return (relation <= 0);
163 else if (op_ == kGT)
164 return (relation > 0);
165 else if (op_ == kGE)
166 return (relation >= 0);
167 // op_ == kBetween
168 if (relation < 0)
169 return false;
170 return Compare(version, version2_, version_style_) <= 0;
171 }
172
173 bool GpuBlacklist::VersionInfo::IsValid() const {
174 return (op_ != kUnknown && version_style_ != kVersionStyleUnknown);
175 }
176
177 bool GpuBlacklist::VersionInfo::IsLexical() const {
178 return version_style_ == kVersionStyleLexical;
179 } 16 }
180 17
181 // static 18 // static
182 int GpuBlacklist::VersionInfo::Compare( 19 GpuBlacklist* GpuBlacklist::Create() {
183 const std::vector<std::string>& version, 20 GpuBlacklist* list = new GpuBlacklist();
184 const std::vector<std::string>& version_ref, 21 list->AddFeature("accelerated_2d_canvas",
185 VersionStyle version_style) { 22 GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS);
186 DCHECK(version.size() > 0 && version_ref.size() > 0); 23 list->AddFeature("accelerated_compositing",
187 DCHECK(version_style != kVersionStyleUnknown); 24 GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING);
188 for (size_t i = 0; i < version_ref.size(); ++i) { 25 list->AddFeature("webgl",
189 if (i >= version.size()) 26 GPU_FEATURE_TYPE_WEBGL);
190 return 0; 27 list->AddFeature("multisampling",
191 int ret = 0; 28 GPU_FEATURE_TYPE_MULTISAMPLING);
192 // We assume both versions are checked by ProcessVersionString(). 29 list->AddFeature("flash_3d",
193 if (i > 0 && version_style == kVersionStyleLexical) 30 GPU_FEATURE_TYPE_FLASH3D);
194 ret = CompareLexicalNumberStrings(version[i], version_ref[i]); 31 list->AddFeature("flash_stage3d",
195 else 32 GPU_FEATURE_TYPE_FLASH_STAGE3D);
196 ret = CompareNumericalNumberStrings(version[i], version_ref[i]); 33 list->AddFeature("flash_stage3d_baseline",
197 if (ret != 0) 34 GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE);
198 return ret; 35 list->AddFeature("texture_sharing",
199 } 36 GPU_FEATURE_TYPE_TEXTURE_SHARING);
200 return 0; 37 list->AddFeature("accelerated_video_decode",
201 } 38 GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE);
202 39 list->AddFeature("3d_css",
203 // static 40 GPU_FEATURE_TYPE_3D_CSS);
204 GpuBlacklist::VersionInfo::VersionStyle 41 list->AddFeature("accelerated_video",
205 GpuBlacklist::VersionInfo::StringToVersionStyle( 42 GPU_FEATURE_TYPE_ACCELERATED_VIDEO);
206 const std::string& version_style) { 43 list->AddFeature("panel_fitting",
207 if (version_style.empty() || version_style == kVersionStyleStringNumerical) 44 GPU_FEATURE_TYPE_PANEL_FITTING);
208 return kVersionStyleNumerical; 45 list->AddFeature("force_compositing_mode",
209 if (version_style == kVersionStyleStringLexical) 46 GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE);
210 return kVersionStyleLexical; 47 list->AddFeature("all",
211 return kVersionStyleUnknown; 48 GPU_FEATURE_TYPE_ALL);
212 } 49 return list;
213
214 GpuBlacklist::OsInfo::OsInfo(const std::string& os,
215 const std::string& version_op,
216 const std::string& version_string,
217 const std::string& version_string2) {
218 type_ = StringToOsType(os);
219 if (type_ != kOsUnknown) {
220 version_info_.reset(
221 new VersionInfo(version_op, "", version_string, version_string2));
222 }
223 }
224
225 GpuBlacklist::OsInfo::~OsInfo() {}
226
227 bool GpuBlacklist::OsInfo::Contains(OsType type,
228 const std::string& version) const {
229 if (!IsValid())
230 return false;
231 if (type_ != type && type_ != kOsAny)
232 return false;
233 return version_info_->Contains(version);
234 }
235
236 bool GpuBlacklist::OsInfo::IsValid() const {
237 return type_ != kOsUnknown && version_info_->IsValid();
238 }
239
240 GpuBlacklist::OsType GpuBlacklist::OsInfo::type() const {
241 return type_;
242 }
243
244 GpuBlacklist::OsType GpuBlacklist::OsInfo::StringToOsType(
245 const std::string& os) {
246 if (os == "win")
247 return kOsWin;
248 else if (os == "macosx")
249 return kOsMacosx;
250 else if (os == "android")
251 return kOsAndroid;
252 else if (os == "linux")
253 return kOsLinux;
254 else if (os == "chromeos")
255 return kOsChromeOS;
256 else if (os == "any")
257 return kOsAny;
258 return kOsUnknown;
259 }
260
261 GpuBlacklist::MachineModelInfo::MachineModelInfo(
262 const std::string& name_op,
263 const std::string& name_value,
264 const std::string& version_op,
265 const std::string& version_string,
266 const std::string& version_string2) {
267 name_info_.reset(new StringInfo(name_op, name_value));
268 version_info_.reset(
269 new VersionInfo(version_op, "", version_string, version_string2));
270 }
271
272 GpuBlacklist::MachineModelInfo::~MachineModelInfo() {}
273
274 bool GpuBlacklist::MachineModelInfo::Contains(
275 const std::string& name, const std::string& version) const {
276 if (!IsValid())
277 return false;
278 if (!name_info_->Contains(name))
279 return false;
280 return version_info_->Contains(version);
281 }
282
283 bool GpuBlacklist::MachineModelInfo::IsValid() const {
284 return name_info_->IsValid() && version_info_->IsValid();
285 }
286
287 GpuBlacklist::StringInfo::StringInfo(const std::string& string_op,
288 const std::string& string_value) {
289 op_ = StringToOp(string_op);
290 value_ = StringToLowerASCII(string_value);
291 }
292
293 bool GpuBlacklist::StringInfo::Contains(const std::string& value) const {
294 std::string my_value = StringToLowerASCII(value);
295 switch (op_) {
296 case kContains:
297 return strstr(my_value.c_str(), value_.c_str()) != NULL;
298 case kBeginWith:
299 return StartsWithASCII(my_value, value_, false);
300 case kEndWith:
301 return EndsWith(my_value, value_, false);
302 case kEQ:
303 return value_ == my_value;
304 default:
305 return false;
306 }
307 }
308
309 bool GpuBlacklist::StringInfo::IsValid() const {
310 return op_ != kUnknown;
311 }
312
313 GpuBlacklist::StringInfo::Op GpuBlacklist::StringInfo::StringToOp(
314 const std::string& string_op) {
315 if (string_op == "=")
316 return kEQ;
317 else if (string_op == "contains")
318 return kContains;
319 else if (string_op == "beginwith")
320 return kBeginWith;
321 else if (string_op == "endwith")
322 return kEndWith;
323 return kUnknown;
324 }
325
326 GpuBlacklist::FloatInfo::FloatInfo(const std::string& float_op,
327 const std::string& float_value,
328 const std::string& float_value2)
329 : op_(kUnknown),
330 value_(0.f),
331 value2_(0.f) {
332 double dvalue = 0;
333 if (!base::StringToDouble(float_value, &dvalue)) {
334 op_ = kUnknown;
335 return;
336 }
337 value_ = static_cast<float>(dvalue);
338 op_ = StringToNumericOp(float_op);
339 if (op_ == kBetween) {
340 if (!base::StringToDouble(float_value2, &dvalue)) {
341 op_ = kUnknown;
342 return;
343 }
344 value2_ = static_cast<float>(dvalue);
345 }
346 }
347
348 bool GpuBlacklist::FloatInfo::Contains(float value) const {
349 if (op_ == kUnknown)
350 return false;
351 if (op_ == kAny)
352 return true;
353 if (op_ == kEQ)
354 return (value == value_);
355 if (op_ == kLT)
356 return (value < value_);
357 if (op_ == kLE)
358 return (value <= value_);
359 if (op_ == kGT)
360 return (value > value_);
361 if (op_ == kGE)
362 return (value >= value_);
363 DCHECK(op_ == kBetween);
364 return ((value_ <= value && value <= value2_) ||
365 (value2_ <= value && value <= value_));
366 }
367
368 bool GpuBlacklist::FloatInfo::IsValid() const {
369 return op_ != kUnknown;
370 }
371
372 GpuBlacklist::IntInfo::IntInfo(const std::string& int_op,
373 const std::string& int_value,
374 const std::string& int_value2)
375 : op_(kUnknown),
376 value_(0),
377 value2_(0) {
378 if (!base::StringToInt(int_value, &value_)) {
379 op_ = kUnknown;
380 return;
381 }
382 op_ = StringToNumericOp(int_op);
383 if (op_ == kBetween &&
384 !base::StringToInt(int_value2, &value2_))
385 op_ = kUnknown;
386 }
387
388 bool GpuBlacklist::IntInfo::Contains(int value) const {
389 if (op_ == kUnknown)
390 return false;
391 if (op_ == kAny)
392 return true;
393 if (op_ == kEQ)
394 return (value == value_);
395 if (op_ == kLT)
396 return (value < value_);
397 if (op_ == kLE)
398 return (value <= value_);
399 if (op_ == kGT)
400 return (value > value_);
401 if (op_ == kGE)
402 return (value >= value_);
403 DCHECK(op_ == kBetween);
404 return ((value_ <= value && value <= value2_) ||
405 (value2_ <= value && value <= value_));
406 }
407
408 bool GpuBlacklist::IntInfo::IsValid() const {
409 return op_ != kUnknown;
410 }
411
412 // static
413 GpuBlacklist::ScopedGpuBlacklistEntry
414 GpuBlacklist::GpuBlacklistEntry::GetGpuBlacklistEntryFromValue(
415 const base::DictionaryValue* value, bool top_level) {
416 DCHECK(value);
417 ScopedGpuBlacklistEntry entry(new GpuBlacklistEntry());
418
419 size_t dictionary_entry_count = 0;
420
421 if (top_level) {
422 uint32 id;
423 if (!value->GetInteger("id", reinterpret_cast<int*>(&id)) ||
424 !entry->SetId(id)) {
425 LOG(WARNING) << "Malformed id entry " << entry->id();
426 return NULL;
427 }
428 dictionary_entry_count++;
429
430 bool disabled;
431 if (value->GetBoolean("disabled", &disabled)) {
432 entry->SetDisabled(disabled);
433 dictionary_entry_count++;
434 }
435 }
436
437 std::string description;
438 if (value->GetString("description", &description)) {
439 entry->description_ = description;
440 dictionary_entry_count++;
441 } else {
442 entry->description_ = "The GPU is unavailable for an unexplained reason.";
443 }
444
445 const base::ListValue* cr_bugs;
446 if (value->GetList("cr_bugs", &cr_bugs)) {
447 for (size_t i = 0; i < cr_bugs->GetSize(); ++i) {
448 int bug_id;
449 if (cr_bugs->GetInteger(i, &bug_id)) {
450 entry->cr_bugs_.push_back(bug_id);
451 } else {
452 LOG(WARNING) << "Malformed cr_bugs entry " << entry->id();
453 return NULL;
454 }
455 }
456 dictionary_entry_count++;
457 }
458
459 const base::ListValue* webkit_bugs;
460 if (value->GetList("webkit_bugs", &webkit_bugs)) {
461 for (size_t i = 0; i < webkit_bugs->GetSize(); ++i) {
462 int bug_id;
463 if (webkit_bugs->GetInteger(i, &bug_id)) {
464 entry->webkit_bugs_.push_back(bug_id);
465 } else {
466 LOG(WARNING) << "Malformed webkit_bugs entry " << entry->id();
467 return NULL;
468 }
469 }
470 dictionary_entry_count++;
471 }
472
473 const base::DictionaryValue* os_value = NULL;
474 if (value->GetDictionary("os", &os_value)) {
475 std::string os_type;
476 std::string os_version_op = "any";
477 std::string os_version_string;
478 std::string os_version_string2;
479 os_value->GetString("type", &os_type);
480 const base::DictionaryValue* os_version_value = NULL;
481 if (os_value->GetDictionary("version", &os_version_value)) {
482 os_version_value->GetString(kOp, &os_version_op);
483 os_version_value->GetString("number", &os_version_string);
484 os_version_value->GetString("number2", &os_version_string2);
485 }
486 if (!entry->SetOsInfo(os_type, os_version_op, os_version_string,
487 os_version_string2)) {
488 LOG(WARNING) << "Malformed os entry " << entry->id();
489 return NULL;
490 }
491 dictionary_entry_count++;
492 }
493
494 std::string vendor_id;
495 if (value->GetString("vendor_id", &vendor_id)) {
496 if (!entry->SetVendorId(vendor_id)) {
497 LOG(WARNING) << "Malformed vendor_id entry " << entry->id();
498 return NULL;
499 }
500 dictionary_entry_count++;
501 }
502
503 const base::ListValue* device_id_list;
504 if (value->GetList("device_id", &device_id_list)) {
505 for (size_t i = 0; i < device_id_list->GetSize(); ++i) {
506 std::string device_id;
507 if (!device_id_list->GetString(i, &device_id) ||
508 !entry->AddDeviceId(device_id)) {
509 LOG(WARNING) << "Malformed device_id entry " << entry->id();
510 return NULL;
511 }
512 }
513 dictionary_entry_count++;
514 }
515
516 std::string multi_gpu_style;
517 if (value->GetString("multi_gpu_style", &multi_gpu_style)) {
518 if (!entry->SetMultiGpuStyle(multi_gpu_style)) {
519 LOG(WARNING) << "Malformed multi_gpu_style entry " << entry->id();
520 return NULL;
521 }
522 dictionary_entry_count++;
523 }
524
525 std::string multi_gpu_category;
526 if (value->GetString("multi_gpu_category", &multi_gpu_category)) {
527 if (!entry->SetMultiGpuCategory(multi_gpu_category)) {
528 LOG(WARNING) << "Malformed multi_gpu_category entry " << entry->id();
529 return NULL;
530 }
531 dictionary_entry_count++;
532 }
533
534 const base::DictionaryValue* driver_vendor_value = NULL;
535 if (value->GetDictionary("driver_vendor", &driver_vendor_value)) {
536 std::string vendor_op;
537 std::string vendor_value;
538 driver_vendor_value->GetString(kOp, &vendor_op);
539 driver_vendor_value->GetString("value", &vendor_value);
540 if (!entry->SetDriverVendorInfo(vendor_op, vendor_value)) {
541 LOG(WARNING) << "Malformed driver_vendor entry " << entry->id();
542 return NULL;
543 }
544 dictionary_entry_count++;
545 }
546
547 const base::DictionaryValue* driver_version_value = NULL;
548 if (value->GetDictionary("driver_version", &driver_version_value)) {
549 std::string driver_version_op = "any";
550 std::string driver_version_style;
551 std::string driver_version_string;
552 std::string driver_version_string2;
553 driver_version_value->GetString(kOp, &driver_version_op);
554 driver_version_value->GetString("style", &driver_version_style);
555 driver_version_value->GetString("number", &driver_version_string);
556 driver_version_value->GetString("number2", &driver_version_string2);
557 if (!entry->SetDriverVersionInfo(driver_version_op,
558 driver_version_style,
559 driver_version_string,
560 driver_version_string2)) {
561 LOG(WARNING) << "Malformed driver_version entry " << entry->id();
562 return NULL;
563 }
564 dictionary_entry_count++;
565 }
566
567 const base::DictionaryValue* driver_date_value = NULL;
568 if (value->GetDictionary("driver_date", &driver_date_value)) {
569 std::string driver_date_op = "any";
570 std::string driver_date_string;
571 std::string driver_date_string2;
572 driver_date_value->GetString(kOp, &driver_date_op);
573 driver_date_value->GetString("number", &driver_date_string);
574 driver_date_value->GetString("number2", &driver_date_string2);
575 if (!entry->SetDriverDateInfo(driver_date_op, driver_date_string,
576 driver_date_string2)) {
577 LOG(WARNING) << "Malformed driver_date entry " << entry->id();
578 return NULL;
579 }
580 dictionary_entry_count++;
581 }
582
583 const base::DictionaryValue* gl_vendor_value = NULL;
584 if (value->GetDictionary("gl_vendor", &gl_vendor_value)) {
585 std::string vendor_op;
586 std::string vendor_value;
587 gl_vendor_value->GetString(kOp, &vendor_op);
588 gl_vendor_value->GetString("value", &vendor_value);
589 if (!entry->SetGLVendorInfo(vendor_op, vendor_value)) {
590 LOG(WARNING) << "Malformed gl_vendor entry " << entry->id();
591 return NULL;
592 }
593 dictionary_entry_count++;
594 }
595
596 const base::DictionaryValue* gl_renderer_value = NULL;
597 if (value->GetDictionary("gl_renderer", &gl_renderer_value)) {
598 std::string renderer_op;
599 std::string renderer_value;
600 gl_renderer_value->GetString(kOp, &renderer_op);
601 gl_renderer_value->GetString("value", &renderer_value);
602 if (!entry->SetGLRendererInfo(renderer_op, renderer_value)) {
603 LOG(WARNING) << "Malformed gl_renderer entry " << entry->id();
604 return NULL;
605 }
606 dictionary_entry_count++;
607 }
608
609 const base::DictionaryValue* cpu_brand_value = NULL;
610 if (value->GetDictionary("cpu_info", &cpu_brand_value)) {
611 std::string cpu_op;
612 std::string cpu_value;
613 cpu_brand_value->GetString(kOp, &cpu_op);
614 cpu_brand_value->GetString("value", &cpu_value);
615 if (!entry->SetCpuBrand(cpu_op, cpu_value)) {
616 LOG(WARNING) << "Malformed cpu_brand entry " << entry->id();
617 return NULL;
618 }
619 dictionary_entry_count++;
620 }
621
622 const base::DictionaryValue* perf_graphics_value = NULL;
623 if (value->GetDictionary("perf_graphics", &perf_graphics_value)) {
624 std::string op;
625 std::string float_value;
626 std::string float_value2;
627 perf_graphics_value->GetString(kOp, &op);
628 perf_graphics_value->GetString("value", &float_value);
629 perf_graphics_value->GetString("value2", &float_value2);
630 if (!entry->SetPerfGraphicsInfo(op, float_value, float_value2)) {
631 LOG(WARNING) << "Malformed perf_graphics entry " << entry->id();
632 return NULL;
633 }
634 dictionary_entry_count++;
635 }
636
637 const base::DictionaryValue* perf_gaming_value = NULL;
638 if (value->GetDictionary("perf_gaming", &perf_gaming_value)) {
639 std::string op;
640 std::string float_value;
641 std::string float_value2;
642 perf_gaming_value->GetString(kOp, &op);
643 perf_gaming_value->GetString("value", &float_value);
644 perf_gaming_value->GetString("value2", &float_value2);
645 if (!entry->SetPerfGamingInfo(op, float_value, float_value2)) {
646 LOG(WARNING) << "Malformed perf_gaming entry " << entry->id();
647 return NULL;
648 }
649 dictionary_entry_count++;
650 }
651
652 const base::DictionaryValue* perf_overall_value = NULL;
653 if (value->GetDictionary("perf_overall", &perf_overall_value)) {
654 std::string op;
655 std::string float_value;
656 std::string float_value2;
657 perf_overall_value->GetString(kOp, &op);
658 perf_overall_value->GetString("value", &float_value);
659 perf_overall_value->GetString("value2", &float_value2);
660 if (!entry->SetPerfOverallInfo(op, float_value, float_value2)) {
661 LOG(WARNING) << "Malformed perf_overall entry " << entry->id();
662 return NULL;
663 }
664 dictionary_entry_count++;
665 }
666
667 const base::DictionaryValue* machine_model_value = NULL;
668 if (value->GetDictionary("machine_model", &machine_model_value)) {
669 std::string name_op;
670 std::string name_value;
671 const base::DictionaryValue* name = NULL;
672 if (machine_model_value->GetDictionary("name", &name)) {
673 name->GetString(kOp, &name_op);
674 name->GetString("value", &name_value);
675 }
676
677 std::string version_op = "any";
678 std::string version_string;
679 std::string version_string2;
680 const base::DictionaryValue* version_value = NULL;
681 if (machine_model_value->GetDictionary("version", &version_value)) {
682 version_value->GetString(kOp, &version_op);
683 version_value->GetString("number", &version_string);
684 version_value->GetString("number2", &version_string2);
685 }
686 if (!entry->SetMachineModelInfo(
687 name_op, name_value, version_op, version_string, version_string2)) {
688 LOG(WARNING) << "Malformed machine_model entry " << entry->id();
689 return NULL;
690 }
691 dictionary_entry_count++;
692 }
693
694 const base::DictionaryValue* gpu_count_value = NULL;
695 if (value->GetDictionary("gpu_count", &gpu_count_value)) {
696 std::string op;
697 std::string int_value;
698 std::string int_value2;
699 gpu_count_value->GetString(kOp, &op);
700 gpu_count_value->GetString("value", &int_value);
701 gpu_count_value->GetString("value2", &int_value2);
702 if (!entry->SetGpuCountInfo(op, int_value, int_value2)) {
703 LOG(WARNING) << "Malformed gpu_count entry " << entry->id();
704 return NULL;
705 }
706 dictionary_entry_count++;
707 }
708
709 if (top_level) {
710 const base::ListValue* blacklist_value = NULL;
711 if (value->GetList("blacklist", &blacklist_value)) {
712 std::vector<std::string> blacklist;
713 for (size_t i = 0; i < blacklist_value->GetSize(); ++i) {
714 std::string feature;
715 if (blacklist_value->GetString(i, &feature)) {
716 blacklist.push_back(feature);
717 } else {
718 LOG(WARNING) << "Malformed blacklist entry " << entry->id();
719 return NULL;
720 }
721 }
722 if (!entry->SetBlacklistedFeatures(blacklist)) {
723 LOG(WARNING) << "Malformed blacklist entry " << entry->id();
724 return NULL;
725 }
726 dictionary_entry_count++;
727 }
728
729 std::string switching_value;
730 if (value->GetString("gpu_switching", &switching_value)) {
731 if (!entry->SetGpuSwitchingOption(switching_value)) {
732 LOG(WARNING) << "Malformed gpu_switching entry " << entry->id();
733 return NULL;
734 }
735 dictionary_entry_count++;
736 }
737 }
738
739 if (top_level) {
740 const base::ListValue* exception_list_value = NULL;
741 if (value->GetList("exceptions", &exception_list_value)) {
742 for (size_t i = 0; i < exception_list_value->GetSize(); ++i) {
743 const base::DictionaryValue* exception_value = NULL;
744 if (!exception_list_value->GetDictionary(i, &exception_value)) {
745 LOG(WARNING) << "Malformed exceptions entry " << entry->id();
746 return NULL;
747 }
748 ScopedGpuBlacklistEntry exception(
749 GetGpuBlacklistEntryFromValue(exception_value, false));
750 if (exception == NULL) {
751 LOG(WARNING) << "Malformed exceptions entry " << entry->id();
752 return NULL;
753 }
754 if (exception->contains_unknown_fields_) {
755 LOG(WARNING) << "Exception with unknown fields " << entry->id();
756 entry->contains_unknown_fields_ = true;
757 } else {
758 entry->AddException(exception);
759 }
760 }
761 dictionary_entry_count++;
762 }
763
764 const base::DictionaryValue* browser_version_value = NULL;
765 // browser_version is processed in LoadGpuBlacklist().
766 if (value->GetDictionary("browser_version", &browser_version_value))
767 dictionary_entry_count++;
768 }
769
770 if (value->size() != dictionary_entry_count) {
771 LOG(WARNING) << "Entry with unknown fields " << entry->id();
772 entry->contains_unknown_fields_ = true;
773 }
774 return entry;
775 }
776
777 GpuBlacklist::GpuBlacklistEntry::GpuBlacklistEntry()
778 : id_(0),
779 disabled_(false),
780 vendor_id_(0),
781 multi_gpu_style_(kMultiGpuStyleNone),
782 multi_gpu_category_(kMultiGpuCategoryPrimary),
783 contains_unknown_fields_(false),
784 contains_unknown_features_(false) {
785 }
786
787 GpuBlacklist::GpuBlacklistEntry::~GpuBlacklistEntry() { }
788
789 bool GpuBlacklist::GpuBlacklistEntry::SetId(uint32 id) {
790 if (id != 0) {
791 id_ = id;
792 return true;
793 }
794 return false;
795 }
796
797 void GpuBlacklist::GpuBlacklistEntry::SetDisabled(bool disabled) {
798 disabled_ = disabled;
799 }
800
801 bool GpuBlacklist::GpuBlacklistEntry::SetOsInfo(
802 const std::string& os,
803 const std::string& version_op,
804 const std::string& version_string,
805 const std::string& version_string2) {
806 os_info_.reset(new OsInfo(os, version_op, version_string, version_string2));
807 return os_info_->IsValid();
808 }
809
810 bool GpuBlacklist::GpuBlacklistEntry::SetVendorId(
811 const std::string& vendor_id_string) {
812 vendor_id_ = 0;
813 return base::HexStringToInt(vendor_id_string,
814 reinterpret_cast<int*>(&vendor_id_));
815 }
816
817 bool GpuBlacklist::GpuBlacklistEntry::AddDeviceId(
818 const std::string& device_id_string) {
819 uint32 device_id = 0;
820 if (base::HexStringToInt(device_id_string,
821 reinterpret_cast<int*>(&device_id))) {
822 device_id_list_.push_back(device_id);
823 return true;
824 }
825 return false;
826 }
827
828 bool GpuBlacklist::GpuBlacklistEntry::SetMultiGpuStyle(
829 const std::string& multi_gpu_style_string) {
830 MultiGpuStyle style = StringToMultiGpuStyle(multi_gpu_style_string);
831 if (style == kMultiGpuStyleNone)
832 return false;
833 multi_gpu_style_ = style;
834 return true;
835 }
836
837 bool GpuBlacklist::GpuBlacklistEntry::SetMultiGpuCategory(
838 const std::string& multi_gpu_category_string) {
839 MultiGpuCategory category =
840 StringToMultiGpuCategory(multi_gpu_category_string);
841 if (category == kMultiGpuCategoryNone)
842 return false;
843 multi_gpu_category_ = category;
844 return true;
845 }
846
847 bool GpuBlacklist::GpuBlacklistEntry::SetDriverVendorInfo(
848 const std::string& vendor_op,
849 const std::string& vendor_value) {
850 driver_vendor_info_.reset(new StringInfo(vendor_op, vendor_value));
851 return driver_vendor_info_->IsValid();
852 }
853
854 bool GpuBlacklist::GpuBlacklistEntry::SetDriverVersionInfo(
855 const std::string& version_op,
856 const std::string& version_style,
857 const std::string& version_string,
858 const std::string& version_string2) {
859 driver_version_info_.reset(new VersionInfo(
860 version_op, version_style, version_string, version_string2));
861 return driver_version_info_->IsValid();
862 }
863
864 bool GpuBlacklist::GpuBlacklistEntry::SetDriverDateInfo(
865 const std::string& date_op,
866 const std::string& date_string,
867 const std::string& date_string2) {
868 driver_date_info_.reset(
869 new VersionInfo(date_op, "", date_string, date_string2));
870 return driver_date_info_->IsValid();
871 }
872
873 bool GpuBlacklist::GpuBlacklistEntry::SetGLVendorInfo(
874 const std::string& vendor_op,
875 const std::string& vendor_value) {
876 gl_vendor_info_.reset(new StringInfo(vendor_op, vendor_value));
877 return gl_vendor_info_->IsValid();
878 }
879
880 bool GpuBlacklist::GpuBlacklistEntry::SetGLRendererInfo(
881 const std::string& renderer_op,
882 const std::string& renderer_value) {
883 gl_renderer_info_.reset(new StringInfo(renderer_op, renderer_value));
884 return gl_renderer_info_->IsValid();
885 }
886
887 bool GpuBlacklist::GpuBlacklistEntry::SetCpuBrand(
888 const std::string& cpu_op,
889 const std::string& cpu_value) {
890 cpu_brand_.reset(new StringInfo(cpu_op, cpu_value));
891 return cpu_brand_->IsValid();
892 }
893
894 bool GpuBlacklist::GpuBlacklistEntry::SetPerfGraphicsInfo(
895 const std::string& op,
896 const std::string& float_string,
897 const std::string& float_string2) {
898 perf_graphics_info_.reset(new FloatInfo(op, float_string, float_string2));
899 return perf_graphics_info_->IsValid();
900 }
901
902 bool GpuBlacklist::GpuBlacklistEntry::SetPerfGamingInfo(
903 const std::string& op,
904 const std::string& float_string,
905 const std::string& float_string2) {
906 perf_gaming_info_.reset(new FloatInfo(op, float_string, float_string2));
907 return perf_gaming_info_->IsValid();
908 }
909
910 bool GpuBlacklist::GpuBlacklistEntry::SetPerfOverallInfo(
911 const std::string& op,
912 const std::string& float_string,
913 const std::string& float_string2) {
914 perf_overall_info_.reset(new FloatInfo(op, float_string, float_string2));
915 return perf_overall_info_->IsValid();
916 }
917
918 bool GpuBlacklist::GpuBlacklistEntry::SetMachineModelInfo(
919 const std::string& name_op,
920 const std::string& name_value,
921 const std::string& version_op,
922 const std::string& version_string,
923 const std::string& version_string2) {
924 machine_model_info_.reset(new MachineModelInfo(
925 name_op, name_value, version_op, version_string, version_string2));
926 return machine_model_info_->IsValid();
927 }
928
929 bool GpuBlacklist::GpuBlacklistEntry::SetGpuCountInfo(
930 const std::string& op,
931 const std::string& int_string,
932 const std::string& int_string2) {
933 gpu_count_info_.reset(new IntInfo(op, int_string, int_string2));
934 return gpu_count_info_->IsValid();
935 }
936
937 bool GpuBlacklist::GpuBlacklistEntry::SetBlacklistedFeatures(
938 const std::vector<std::string>& blacklisted_features) {
939 size_t size = blacklisted_features.size();
940 if (size == 0)
941 return false;
942 int feature_type = GPU_FEATURE_TYPE_UNKNOWN;
943 for (size_t i = 0; i < size; ++i) {
944 GpuFeatureType type = StringToGpuFeatureType(blacklisted_features[i]);
945 switch (type) {
946 case GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS:
947 case GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING:
948 case GPU_FEATURE_TYPE_WEBGL:
949 case GPU_FEATURE_TYPE_MULTISAMPLING:
950 case GPU_FEATURE_TYPE_FLASH3D:
951 case GPU_FEATURE_TYPE_FLASH_STAGE3D:
952 case GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE:
953 case GPU_FEATURE_TYPE_TEXTURE_SHARING:
954 case GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE:
955 case GPU_FEATURE_TYPE_3D_CSS:
956 case GPU_FEATURE_TYPE_ACCELERATED_VIDEO:
957 case GPU_FEATURE_TYPE_PANEL_FITTING:
958 case GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE:
959 case GPU_FEATURE_TYPE_ALL:
960 feature_type |= type;
961 break;
962 case GPU_FEATURE_TYPE_UNKNOWN:
963 contains_unknown_features_ = true;
964 break;
965 }
966 }
967 decision_.blacklisted_features = static_cast<GpuFeatureType>(feature_type);
968 return true;
969 }
970
971 bool GpuBlacklist::GpuBlacklistEntry::SetGpuSwitchingOption(
972 const std::string& switching_string) {
973 GpuSwitchingOption switching = StringToGpuSwitchingOption(switching_string);
974 if (switching == GPU_SWITCHING_OPTION_UNKNOWN)
975 return false;
976 decision_.gpu_switching = switching;
977 return true;
978 }
979
980 void GpuBlacklist::GpuBlacklistEntry::AddException(
981 ScopedGpuBlacklistEntry exception) {
982 exceptions_.push_back(exception);
983 }
984
985 // static
986 GpuBlacklist::GpuBlacklistEntry::MultiGpuStyle
987 GpuBlacklist::GpuBlacklistEntry::StringToMultiGpuStyle(
988 const std::string& style) {
989 if (style == kMultiGpuStyleStringOptimus)
990 return kMultiGpuStyleOptimus;
991 if (style == kMultiGpuStyleStringAMDSwitchable)
992 return kMultiGpuStyleAMDSwitchable;
993 return kMultiGpuStyleNone;
994 }
995
996 // static
997 GpuBlacklist::GpuBlacklistEntry::MultiGpuCategory
998 GpuBlacklist::GpuBlacklistEntry::StringToMultiGpuCategory(
999 const std::string& category) {
1000 if (category == kMultiGpuCategoryStringPrimary)
1001 return kMultiGpuCategoryPrimary;
1002 if (category == kMultiGpuCategoryStringSecondary)
1003 return kMultiGpuCategorySecondary;
1004 if (category == kMultiGpuCategoryStringAny)
1005 return kMultiGpuCategoryAny;
1006 return kMultiGpuCategoryNone;
1007 }
1008
1009 bool GpuBlacklist::GpuBlacklistEntry::Contains(
1010 OsType os_type, const std::string& os_version,
1011 const GPUInfo& gpu_info) const {
1012 DCHECK(os_type != kOsAny);
1013 if (os_info_.get() != NULL && !os_info_->Contains(os_type, os_version))
1014 return false;
1015 bool is_not_primary_gpu =
1016 GpuUnmatched(vendor_id_, device_id_list_, gpu_info.gpu);
1017 bool is_not_secondary_gpu = true;
1018 for (size_t i = 0; i < gpu_info.secondary_gpus.size(); ++i) {
1019 is_not_secondary_gpu = is_not_secondary_gpu &&
1020 GpuUnmatched(vendor_id_, device_id_list_, gpu_info.secondary_gpus[i]);
1021 }
1022 switch (multi_gpu_category_) {
1023 case kMultiGpuCategoryPrimary:
1024 if (is_not_primary_gpu)
1025 return false;
1026 break;
1027 case kMultiGpuCategorySecondary:
1028 if (is_not_secondary_gpu)
1029 return false;
1030 break;
1031 case kMultiGpuCategoryAny:
1032 if (is_not_primary_gpu && is_not_secondary_gpu)
1033 return false;
1034 break;
1035 case kMultiGpuCategoryNone:
1036 break;
1037 }
1038 switch (multi_gpu_style_) {
1039 case kMultiGpuStyleOptimus:
1040 if (!gpu_info.optimus)
1041 return false;
1042 break;
1043 case kMultiGpuStyleAMDSwitchable:
1044 if (!gpu_info.amd_switchable)
1045 return false;
1046 break;
1047 case kMultiGpuStyleNone:
1048 break;
1049 }
1050 if (driver_vendor_info_.get() != NULL && !gpu_info.driver_vendor.empty() &&
1051 !driver_vendor_info_->Contains(gpu_info.driver_vendor))
1052 return false;
1053 if (driver_version_info_.get() != NULL && !gpu_info.driver_version.empty()) {
1054 if (!driver_version_info_->Contains(gpu_info.driver_version))
1055 return false;
1056 }
1057 if (driver_date_info_.get() != NULL && !gpu_info.driver_date.empty()) {
1058 if (!driver_date_info_->Contains(gpu_info.driver_date, '-'))
1059 return false;
1060 }
1061 if (gl_vendor_info_.get() != NULL && !gpu_info.gl_vendor.empty() &&
1062 !gl_vendor_info_->Contains(gpu_info.gl_vendor))
1063 return false;
1064 if (gl_renderer_info_.get() != NULL && !gpu_info.gl_renderer.empty() &&
1065 !gl_renderer_info_->Contains(gpu_info.gl_renderer))
1066 return false;
1067 if (perf_graphics_info_.get() != NULL &&
1068 (gpu_info.performance_stats.graphics == 0.0 ||
1069 !perf_graphics_info_->Contains(gpu_info.performance_stats.graphics)))
1070 return false;
1071 if (perf_gaming_info_.get() != NULL &&
1072 (gpu_info.performance_stats.gaming == 0.0 ||
1073 !perf_gaming_info_->Contains(gpu_info.performance_stats.gaming)))
1074 return false;
1075 if (perf_overall_info_.get() != NULL &&
1076 (gpu_info.performance_stats.overall == 0.0 ||
1077 !perf_overall_info_->Contains(gpu_info.performance_stats.overall)))
1078 return false;
1079 if (machine_model_info_.get() != NULL) {
1080 std::vector<std::string> name_version;
1081 base::SplitString(gpu_info.machine_model, ' ', &name_version);
1082 if (name_version.size() == 2 &&
1083 !machine_model_info_->Contains(name_version[0], name_version[1]))
1084 return false;
1085 }
1086 if (gpu_count_info_.get() != NULL &&
1087 !gpu_count_info_->Contains(gpu_info.secondary_gpus.size() + 1))
1088 return false;
1089 if (cpu_brand_.get() != NULL) {
1090 base::CPU cpu_info;
1091 if (!cpu_brand_->Contains(cpu_info.cpu_brand()))
1092 return false;
1093 }
1094
1095 for (size_t i = 0; i < exceptions_.size(); ++i) {
1096 if (exceptions_[i]->Contains(os_type, os_version, gpu_info) &&
1097 !exceptions_[i]->NeedsMoreInfo(gpu_info))
1098 return false;
1099 }
1100 return true;
1101 }
1102
1103 bool GpuBlacklist::GpuBlacklistEntry::NeedsMoreInfo(
1104 const GPUInfo& gpu_info) const {
1105 // We only check for missing info that might be collected with a gl context.
1106 // If certain info is missing due to some error, say, we fail to collect
1107 // vendor_id/device_id, then even if we launch GPU process and create a gl
1108 // context, we won't gather such missing info, so we still return false.
1109 if (driver_vendor_info_.get() && gpu_info.driver_vendor.empty())
1110 return true;
1111 if (driver_version_info_.get() && gpu_info.driver_version.empty())
1112 return true;
1113 if (gl_vendor_info_.get() && gpu_info.gl_vendor.empty())
1114 return true;
1115 if (gl_renderer_info_.get() && gpu_info.gl_renderer.empty())
1116 return true;
1117 for (size_t i = 0; i < exceptions_.size(); ++i) {
1118 if (exceptions_[i]->NeedsMoreInfo(gpu_info))
1119 return true;
1120 }
1121 return false;
1122 }
1123
1124 GpuBlacklist::OsType GpuBlacklist::GpuBlacklistEntry::GetOsType() const {
1125 if (os_info_.get() == NULL)
1126 return kOsAny;
1127 return os_info_->type();
1128 }
1129
1130 uint32 GpuBlacklist::GpuBlacklistEntry::id() const {
1131 return id_;
1132 }
1133
1134 bool GpuBlacklist::GpuBlacklistEntry::disabled() const {
1135 return disabled_;
1136 }
1137
1138 GpuFeatureType GpuBlacklist::GpuBlacklistEntry::GetGpuFeatureType() const {
1139 return decision_.blacklisted_features;
1140 }
1141
1142 GpuSwitchingOption
1143 GpuBlacklist::GpuBlacklistEntry::GetGpuSwitchingOption() const {
1144 return decision_.gpu_switching;
1145 }
1146
1147 GpuBlacklist::GpuBlacklist()
1148 : max_entry_id_(0),
1149 contains_unknown_fields_(false),
1150 needs_more_info_(false) {
1151 }
1152
1153 GpuBlacklist::~GpuBlacklist() {
1154 Clear();
1155 }
1156
1157 bool GpuBlacklist::LoadGpuBlacklist(
1158 const std::string& json_context, GpuBlacklist::OsFilter os_filter) {
1159 const std::string browser_version_string = "0";
1160 return LoadGpuBlacklist(browser_version_string, json_context, os_filter);
1161 }
1162
1163 bool GpuBlacklist::LoadGpuBlacklist(
1164 const std::string& browser_version_string,
1165 const std::string& json_context,
1166 GpuBlacklist::OsFilter os_filter) {
1167 std::vector<std::string> pieces;
1168 if (!ProcessVersionString(browser_version_string, '.', &pieces))
1169 return false;
1170 browser_version_ = browser_version_string;
1171
1172 scoped_ptr<base::Value> root;
1173 root.reset(base::JSONReader::Read(json_context));
1174 if (root.get() == NULL || !root->IsType(base::Value::TYPE_DICTIONARY))
1175 return false;
1176
1177 base::DictionaryValue* root_dictionary =
1178 static_cast<DictionaryValue*>(root.get());
1179 DCHECK(root_dictionary);
1180 return LoadGpuBlacklist(*root_dictionary, os_filter);
1181 }
1182
1183 bool GpuBlacklist::LoadGpuBlacklist(const base::DictionaryValue& parsed_json,
1184 GpuBlacklist::OsFilter os_filter) {
1185 std::vector<ScopedGpuBlacklistEntry> entries;
1186
1187 parsed_json.GetString("version", &version_);
1188 std::vector<std::string> pieces;
1189 if (!ProcessVersionString(version_, '.', &pieces))
1190 return false;
1191
1192 const base::ListValue* list = NULL;
1193 if (!parsed_json.GetList("entries", &list))
1194 return false;
1195
1196 uint32 max_entry_id = 0;
1197 bool contains_unknown_fields = false;
1198 for (size_t i = 0; i < list->GetSize(); ++i) {
1199 const base::DictionaryValue* list_item = NULL;
1200 bool valid = list->GetDictionary(i, &list_item);
1201 if (!valid || list_item == NULL)
1202 return false;
1203 // Check browser version compatibility: if the entry is not for the
1204 // current browser version, don't process it.
1205 BrowserVersionSupport browser_version_support =
1206 IsEntrySupportedByCurrentBrowserVersion(list_item);
1207 if (browser_version_support == kMalformed)
1208 return false;
1209 if (browser_version_support == kUnsupported)
1210 continue;
1211 DCHECK(browser_version_support == kSupported);
1212 ScopedGpuBlacklistEntry entry(
1213 GpuBlacklistEntry::GetGpuBlacklistEntryFromValue(list_item, true));
1214 if (entry == NULL)
1215 return false;
1216 if (entry->id() > max_entry_id)
1217 max_entry_id = entry->id();
1218 // If an unknown field is encountered, skip the entry; if an unknown
1219 // feature is encountered, ignore the feature, but keep the entry.
1220 if (entry->contains_unknown_fields()) {
1221 contains_unknown_fields = true;
1222 continue;
1223 }
1224 if (entry->contains_unknown_features())
1225 contains_unknown_fields = true;
1226 entries.push_back(entry);
1227 }
1228
1229 Clear();
1230 OsType my_os = GetOsType();
1231 for (size_t i = 0; i < entries.size(); ++i) {
1232 OsType entry_os = entries[i]->GetOsType();
1233 if (os_filter == GpuBlacklist::kAllOs ||
1234 entry_os == kOsAny || entry_os == my_os)
1235 blacklist_.push_back(entries[i]);
1236 }
1237 max_entry_id_ = max_entry_id;
1238 contains_unknown_fields_ = contains_unknown_fields;
1239 return true;
1240 }
1241
1242 GpuBlacklist::Decision GpuBlacklist::MakeBlacklistDecision(
1243 GpuBlacklist::OsType os,
1244 std::string os_version,
1245 const GPUInfo& gpu_info) {
1246 active_entries_.clear();
1247 int type = 0;
1248 GpuSwitchingOption switching = GPU_SWITCHING_OPTION_UNKNOWN;
1249
1250 needs_more_info_ = false;
1251 int possible_type = 0;
1252 GpuSwitchingOption possible_switching = GPU_SWITCHING_OPTION_UNKNOWN;
1253
1254 if (os == kOsAny)
1255 os = GetOsType();
1256 if (os_version.empty()) {
1257 os_version = base::SysInfo::OperatingSystemVersion();
1258 size_t pos = os_version.find_first_not_of("0123456789.");
1259 if (pos != std::string::npos)
1260 os_version = os_version.substr(0, pos);
1261 }
1262 std::vector<std::string> pieces;
1263 if (!ProcessVersionString(os_version, '.', &pieces))
1264 os_version = "0";
1265
1266 for (size_t i = 0; i < blacklist_.size(); ++i) {
1267 if (blacklist_[i]->Contains(os, os_version, gpu_info)) {
1268 if (!blacklist_[i]->disabled()) {
1269 bool not_final = blacklist_[i]->NeedsMoreInfo(gpu_info);
1270 if (not_final)
1271 possible_type |= blacklist_[i]->GetGpuFeatureType();
1272 else
1273 type |= blacklist_[i]->GetGpuFeatureType();
1274 if (blacklist_[i]->GetGpuSwitchingOption() !=
1275 GPU_SWITCHING_OPTION_UNKNOWN) {
1276 if (not_final)
1277 possible_switching = blacklist_[i]->GetGpuSwitchingOption();
1278 else
1279 switching = blacklist_[i]->GetGpuSwitchingOption();
1280 }
1281 }
1282 active_entries_.push_back(blacklist_[i]);
1283 }
1284 }
1285
1286 if ((possible_type != 0 && (possible_type | type) != type) ||
1287 (possible_switching != GPU_SWITCHING_OPTION_UNKNOWN &&
1288 switching == GPU_SWITCHING_OPTION_UNKNOWN)) {
1289 needs_more_info_ = true;
1290 }
1291
1292 Decision decision;
1293 decision.blacklisted_features = static_cast<GpuFeatureType>(type);
1294 decision.gpu_switching = switching;
1295 return decision;
1296 }
1297
1298 void GpuBlacklist::GetDecisionEntries(
1299 std::vector<uint32>* entry_ids, bool disabled) const {
1300 DCHECK(entry_ids);
1301 entry_ids->clear();
1302 for (size_t i = 0; i < active_entries_.size(); ++i) {
1303 if (disabled == active_entries_[i]->disabled())
1304 entry_ids->push_back(active_entries_[i]->id());
1305 }
1306 }
1307
1308 void GpuBlacklist::GetBlacklistReasons(base::ListValue* problem_list) const {
1309 DCHECK(problem_list);
1310 for (size_t i = 0; i < active_entries_.size(); ++i) {
1311 GpuBlacklistEntry* entry = active_entries_[i];
1312 if (entry->disabled())
1313 continue;
1314 base::DictionaryValue* problem = new base::DictionaryValue();
1315
1316 problem->SetString("description", entry->description());
1317
1318 base::ListValue* cr_bugs = new base::ListValue();
1319 for (size_t j = 0; j < entry->cr_bugs().size(); ++j)
1320 cr_bugs->Append(new base::FundamentalValue(entry->cr_bugs()[j]));
1321 problem->Set("crBugs", cr_bugs);
1322
1323 base::ListValue* webkit_bugs = new base::ListValue();
1324 for (size_t j = 0; j < entry->webkit_bugs().size(); ++j) {
1325 webkit_bugs->Append(new base::FundamentalValue(entry->webkit_bugs()[j]));
1326 }
1327 problem->Set("webkitBugs", webkit_bugs);
1328
1329 problem_list->Append(problem);
1330 }
1331 }
1332
1333 size_t GpuBlacklist::num_entries() const {
1334 return blacklist_.size();
1335 }
1336
1337 uint32 GpuBlacklist::max_entry_id() const {
1338 return max_entry_id_;
1339 }
1340
1341 std::string GpuBlacklist::GetVersion() const {
1342 return version_;
1343 }
1344
1345 GpuBlacklist::OsType GpuBlacklist::GetOsType() {
1346 #if defined(OS_CHROMEOS)
1347 return kOsChromeOS;
1348 #elif defined(OS_WIN)
1349 return kOsWin;
1350 #elif defined(OS_ANDROID)
1351 return kOsAndroid;
1352 #elif defined(OS_LINUX) || defined(OS_OPENBSD)
1353 return kOsLinux;
1354 #elif defined(OS_MACOSX)
1355 return kOsMacosx;
1356 #else
1357 return kOsUnknown;
1358 #endif
1359 }
1360
1361 void GpuBlacklist::Clear() {
1362 blacklist_.clear();
1363 active_entries_.clear();
1364 max_entry_id_ = 0;
1365 contains_unknown_fields_ = false;
1366 }
1367
1368 GpuBlacklist::BrowserVersionSupport
1369 GpuBlacklist::IsEntrySupportedByCurrentBrowserVersion(
1370 const base::DictionaryValue* value) {
1371 DCHECK(value);
1372 const base::DictionaryValue* browser_version_value = NULL;
1373 if (value->GetDictionary("browser_version", &browser_version_value)) {
1374 std::string version_op = "any";
1375 std::string version_string;
1376 std::string version_string2;
1377 browser_version_value->GetString(kOp, &version_op);
1378 browser_version_value->GetString("number", &version_string);
1379 browser_version_value->GetString("number2", &version_string2);
1380 scoped_ptr<VersionInfo> browser_version_info;
1381 browser_version_info.reset(
1382 new VersionInfo(version_op, "", version_string, version_string2));
1383 if (!browser_version_info->IsValid())
1384 return kMalformed;
1385 if (browser_version_info->Contains(browser_version_))
1386 return kSupported;
1387 return kUnsupported;
1388 }
1389 return kSupported;
1390 }
1391
1392 // static
1393 GpuBlacklist::NumericOp GpuBlacklist::StringToNumericOp(
1394 const std::string& op) {
1395 if (op == "=")
1396 return kEQ;
1397 if (op == "<")
1398 return kLT;
1399 if (op == "<=")
1400 return kLE;
1401 if (op == ">")
1402 return kGT;
1403 if (op == ">=")
1404 return kGE;
1405 if (op == "any")
1406 return kAny;
1407 if (op == "between")
1408 return kBetween;
1409 return kUnknown;
1410 } 50 }
1411 51
1412 } // namespace content 52 } // namespace content
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