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 3// found in the LICENSE file. 4 5#include "gpu/config/gpu_control_list.h" 6 7#include "base/cpu.h" 8#include "base/json/json_reader.h" 9#include "base/logging.h" 10#include "base/strings/string_number_conversions.h" 11#include "base/strings/string_split.h" 12#include "base/strings/string_util.h" 13#include "base/sys_info.h" 14#include "gpu/config/gpu_info.h" 15#include "gpu/config/gpu_util.h" 16 17namespace gpu { 18namespace { 19 20// Break a version string into segments. Return true if each segment is 21// a valid number. 22bool 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} 45 46// Compare two number strings using numerical ordering. 47// Return 0 if number = number_ref, 48// 1 if number > number_ref, 49// -1 if number < number_ref. 50int 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. 73int 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 88bool 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 105const char kMultiGpuStyleStringAMDSwitchable[] = "amd_switchable"; 106const char kMultiGpuStyleStringOptimus[] = "optimus"; 107 108const char kMultiGpuCategoryStringPrimary[] = "primary"; 109const char kMultiGpuCategoryStringSecondary[] = "secondary"; 110const char kMultiGpuCategoryStringAny[] = "any"; 111 112const char kVersionStyleStringNumerical[] = "numerical"; 113const char kVersionStyleStringLexical[] = "lexical"; 114 115const char kOp[] = "op"; 116 117} // namespace anonymous 118 119GpuControlList::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 139GpuControlList::VersionInfo::~VersionInfo() { 140} 141 142bool GpuControlList::VersionInfo::Contains( 143 const std::string& version_string) const { 144 return Contains(version_string, '.'); 145} 146 147bool GpuControlList::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 173bool GpuControlList::VersionInfo::IsValid() const { 174 return (op_ != kUnknown && version_style_ != kVersionStyleUnknown); 175} 176 177bool GpuControlList::VersionInfo::IsLexical() const { 178 return version_style_ == kVersionStyleLexical; 179} 180 181// static 182int GpuControlList::VersionInfo::Compare( 183 const std::vector<std::string>& version, 184 const std::vector<std::string>& version_ref, 185 VersionStyle version_style) { 186 DCHECK(version.size() > 0 && version_ref.size() > 0); 187 DCHECK(version_style != kVersionStyleUnknown); 188 for (size_t i = 0; i < version_ref.size(); ++i) { 189 if (i >= version.size()) 190 return 0; 191 int ret = 0; 192 // We assume both versions are checked by ProcessVersionString(). 193 if (i > 0 && version_style == kVersionStyleLexical) 194 ret = CompareLexicalNumberStrings(version[i], version_ref[i]); 195 else 196 ret = CompareNumericalNumberStrings(version[i], version_ref[i]); 197 if (ret != 0) 198 return ret; 199 } 200 return 0; 201} 202 203// static 204GpuControlList::VersionInfo::VersionStyle 205GpuControlList::VersionInfo::StringToVersionStyle( 206 const std::string& version_style) { 207 if (version_style.empty() || version_style == kVersionStyleStringNumerical) 208 return kVersionStyleNumerical; 209 if (version_style == kVersionStyleStringLexical) 210 return kVersionStyleLexical; 211 return kVersionStyleUnknown; 212} 213 214GpuControlList::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(new VersionInfo( 221 version_op, std::string(), version_string, version_string2)); 222 } 223} 224 225GpuControlList::OsInfo::~OsInfo() {} 226 227bool GpuControlList::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 236bool GpuControlList::OsInfo::IsValid() const { 237 return type_ != kOsUnknown && version_info_->IsValid(); 238} 239 240GpuControlList::OsType GpuControlList::OsInfo::type() const { 241 return type_; 242} 243 244GpuControlList::OsType GpuControlList::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 261GpuControlList::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(new VersionInfo( 269 version_op, std::string(), version_string, version_string2)); 270} 271 272GpuControlList::MachineModelInfo::~MachineModelInfo() {} 273 274bool GpuControlList::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 283bool GpuControlList::MachineModelInfo::IsValid() const { 284 return name_info_->IsValid() && version_info_->IsValid(); 285} 286 287GpuControlList::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 293bool GpuControlList::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 309bool GpuControlList::StringInfo::IsValid() const { 310 return op_ != kUnknown; 311} 312 313GpuControlList::StringInfo::Op GpuControlList::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 326GpuControlList::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 op_ = StringToNumericOp(float_op); 333 if (op_ == kAny) 334 return; 335 double dvalue = 0; 336 if (!base::StringToDouble(float_value, &dvalue)) { 337 op_ = kUnknown; 338 return; 339 } 340 value_ = static_cast<float>(dvalue); 341 if (op_ == kBetween) { 342 if (!base::StringToDouble(float_value2, &dvalue)) { 343 op_ = kUnknown; 344 return; 345 } 346 value2_ = static_cast<float>(dvalue); 347 } 348} 349 350bool GpuControlList::FloatInfo::Contains(float value) const { 351 if (op_ == kUnknown) 352 return false; 353 if (op_ == kAny) 354 return true; 355 if (op_ == kEQ) 356 return (value == value_); 357 if (op_ == kLT) 358 return (value < value_); 359 if (op_ == kLE) 360 return (value <= value_); 361 if (op_ == kGT) 362 return (value > value_); 363 if (op_ == kGE) 364 return (value >= value_); 365 DCHECK(op_ == kBetween); 366 return ((value_ <= value && value <= value2_) || 367 (value2_ <= value && value <= value_)); 368} 369 370bool GpuControlList::FloatInfo::IsValid() const { 371 return op_ != kUnknown; 372} 373 374GpuControlList::IntInfo::IntInfo(const std::string& int_op, 375 const std::string& int_value, 376 const std::string& int_value2) 377 : op_(kUnknown), 378 value_(0), 379 value2_(0) { 380 op_ = StringToNumericOp(int_op); 381 if (op_ == kAny) 382 return; 383 if (!base::StringToInt(int_value, &value_)) { 384 op_ = kUnknown; 385 return; 386 } 387 if (op_ == kBetween && 388 !base::StringToInt(int_value2, &value2_)) 389 op_ = kUnknown; 390} 391 392bool GpuControlList::IntInfo::Contains(int value) const { 393 if (op_ == kUnknown) 394 return false; 395 if (op_ == kAny) 396 return true; 397 if (op_ == kEQ) 398 return (value == value_); 399 if (op_ == kLT) 400 return (value < value_); 401 if (op_ == kLE) 402 return (value <= value_); 403 if (op_ == kGT) 404 return (value > value_); 405 if (op_ == kGE) 406 return (value >= value_); 407 DCHECK(op_ == kBetween); 408 return ((value_ <= value && value <= value2_) || 409 (value2_ <= value && value <= value_)); 410} 411 412bool GpuControlList::IntInfo::IsValid() const { 413 return op_ != kUnknown; 414} 415 416// static 417GpuControlList::ScopedGpuControlListEntry 418GpuControlList::GpuControlListEntry::GetEntryFromValue( 419 const base::DictionaryValue* value, bool top_level, 420 const FeatureMap& feature_map, 421 bool supports_feature_type_all) { 422 DCHECK(value); 423 ScopedGpuControlListEntry entry(new GpuControlListEntry()); 424 425 size_t dictionary_entry_count = 0; 426 427 if (top_level) { 428 uint32 id; 429 if (!value->GetInteger("id", reinterpret_cast<int*>(&id)) || 430 !entry->SetId(id)) { 431 LOG(WARNING) << "Malformed id entry " << entry->id(); 432 return NULL; 433 } 434 dictionary_entry_count++; 435 436 bool disabled; 437 if (value->GetBoolean("disabled", &disabled)) { 438 entry->SetDisabled(disabled); 439 dictionary_entry_count++; 440 } 441 } 442 443 std::string description; 444 if (value->GetString("description", &description)) { 445 entry->description_ = description; 446 dictionary_entry_count++; 447 } else { 448 entry->description_ = "The GPU is unavailable for an unexplained reason."; 449 } 450 451 const base::ListValue* cr_bugs; 452 if (value->GetList("cr_bugs", &cr_bugs)) { 453 for (size_t i = 0; i < cr_bugs->GetSize(); ++i) { 454 int bug_id; 455 if (cr_bugs->GetInteger(i, &bug_id)) { 456 entry->cr_bugs_.push_back(bug_id); 457 } else { 458 LOG(WARNING) << "Malformed cr_bugs entry " << entry->id(); 459 return NULL; 460 } 461 } 462 dictionary_entry_count++; 463 } 464 465 const base::ListValue* webkit_bugs; 466 if (value->GetList("webkit_bugs", &webkit_bugs)) { 467 for (size_t i = 0; i < webkit_bugs->GetSize(); ++i) { 468 int bug_id; 469 if (webkit_bugs->GetInteger(i, &bug_id)) { 470 entry->webkit_bugs_.push_back(bug_id); 471 } else { 472 LOG(WARNING) << "Malformed webkit_bugs entry " << entry->id(); 473 return NULL; 474 } 475 } 476 dictionary_entry_count++; 477 } 478 479 const base::DictionaryValue* os_value = NULL; 480 if (value->GetDictionary("os", &os_value)) { 481 std::string os_type; 482 std::string os_version_op = "any"; 483 std::string os_version_string; 484 std::string os_version_string2; 485 os_value->GetString("type", &os_type); 486 const base::DictionaryValue* os_version_value = NULL; 487 if (os_value->GetDictionary("version", &os_version_value)) { 488 os_version_value->GetString(kOp, &os_version_op); 489 os_version_value->GetString("number", &os_version_string); 490 os_version_value->GetString("number2", &os_version_string2); 491 } 492 if (!entry->SetOsInfo(os_type, os_version_op, os_version_string, 493 os_version_string2)) { 494 LOG(WARNING) << "Malformed os entry " << entry->id(); 495 return NULL; 496 } 497 dictionary_entry_count++; 498 } 499 500 std::string vendor_id; 501 if (value->GetString("vendor_id", &vendor_id)) { 502 if (!entry->SetVendorId(vendor_id)) { 503 LOG(WARNING) << "Malformed vendor_id entry " << entry->id(); 504 return NULL; 505 } 506 dictionary_entry_count++; 507 } 508 509 const base::ListValue* device_id_list; 510 if (value->GetList("device_id", &device_id_list)) { 511 for (size_t i = 0; i < device_id_list->GetSize(); ++i) { 512 std::string device_id; 513 if (!device_id_list->GetString(i, &device_id) || 514 !entry->AddDeviceId(device_id)) { 515 LOG(WARNING) << "Malformed device_id entry " << entry->id(); 516 return NULL; 517 } 518 } 519 dictionary_entry_count++; 520 } 521 522 std::string multi_gpu_style; 523 if (value->GetString("multi_gpu_style", &multi_gpu_style)) { 524 if (!entry->SetMultiGpuStyle(multi_gpu_style)) { 525 LOG(WARNING) << "Malformed multi_gpu_style entry " << entry->id(); 526 return NULL; 527 } 528 dictionary_entry_count++; 529 } 530 531 std::string multi_gpu_category; 532 if (value->GetString("multi_gpu_category", &multi_gpu_category)) { 533 if (!entry->SetMultiGpuCategory(multi_gpu_category)) { 534 LOG(WARNING) << "Malformed multi_gpu_category entry " << entry->id(); 535 return NULL; 536 } 537 dictionary_entry_count++; 538 } 539 540 const base::DictionaryValue* driver_vendor_value = NULL; 541 if (value->GetDictionary("driver_vendor", &driver_vendor_value)) { 542 std::string vendor_op; 543 std::string vendor_value; 544 driver_vendor_value->GetString(kOp, &vendor_op); 545 driver_vendor_value->GetString("value", &vendor_value); 546 if (!entry->SetDriverVendorInfo(vendor_op, vendor_value)) { 547 LOG(WARNING) << "Malformed driver_vendor entry " << entry->id(); 548 return NULL; 549 } 550 dictionary_entry_count++; 551 } 552 553 const base::DictionaryValue* driver_version_value = NULL; 554 if (value->GetDictionary("driver_version", &driver_version_value)) { 555 std::string driver_version_op = "any"; 556 std::string driver_version_style; 557 std::string driver_version_string; 558 std::string driver_version_string2; 559 driver_version_value->GetString(kOp, &driver_version_op); 560 driver_version_value->GetString("style", &driver_version_style); 561 driver_version_value->GetString("number", &driver_version_string); 562 driver_version_value->GetString("number2", &driver_version_string2); 563 if (!entry->SetDriverVersionInfo(driver_version_op, 564 driver_version_style, 565 driver_version_string, 566 driver_version_string2)) { 567 LOG(WARNING) << "Malformed driver_version entry " << entry->id(); 568 return NULL; 569 } 570 dictionary_entry_count++; 571 } 572 573 const base::DictionaryValue* driver_date_value = NULL; 574 if (value->GetDictionary("driver_date", &driver_date_value)) { 575 std::string driver_date_op = "any"; 576 std::string driver_date_string; 577 std::string driver_date_string2; 578 driver_date_value->GetString(kOp, &driver_date_op); 579 driver_date_value->GetString("number", &driver_date_string); 580 driver_date_value->GetString("number2", &driver_date_string2); 581 if (!entry->SetDriverDateInfo(driver_date_op, driver_date_string, 582 driver_date_string2)) { 583 LOG(WARNING) << "Malformed driver_date entry " << entry->id(); 584 return NULL; 585 } 586 dictionary_entry_count++; 587 } 588 589 const base::DictionaryValue* gl_vendor_value = NULL; 590 if (value->GetDictionary("gl_vendor", &gl_vendor_value)) { 591 std::string vendor_op; 592 std::string vendor_value; 593 gl_vendor_value->GetString(kOp, &vendor_op); 594 gl_vendor_value->GetString("value", &vendor_value); 595 if (!entry->SetGLVendorInfo(vendor_op, vendor_value)) { 596 LOG(WARNING) << "Malformed gl_vendor entry " << entry->id(); 597 return NULL; 598 } 599 dictionary_entry_count++; 600 } 601 602 const base::DictionaryValue* gl_renderer_value = NULL; 603 if (value->GetDictionary("gl_renderer", &gl_renderer_value)) { 604 std::string renderer_op; 605 std::string renderer_value; 606 gl_renderer_value->GetString(kOp, &renderer_op); 607 gl_renderer_value->GetString("value", &renderer_value); 608 if (!entry->SetGLRendererInfo(renderer_op, renderer_value)) { 609 LOG(WARNING) << "Malformed gl_renderer entry " << entry->id(); 610 return NULL; 611 } 612 dictionary_entry_count++; 613 } 614 615 const base::DictionaryValue* gl_extensions_value = NULL; 616 if (value->GetDictionary("gl_extensions", &gl_extensions_value)) { 617 std::string extensions_op; 618 std::string extensions_value; 619 gl_extensions_value->GetString(kOp, &extensions_op); 620 gl_extensions_value->GetString("value", &extensions_value); 621 if (!entry->SetGLExtensionsInfo(extensions_op, extensions_value)) { 622 LOG(WARNING) << "Malformed gl_extensions entry " << entry->id(); 623 return NULL; 624 } 625 dictionary_entry_count++; 626 } 627 628 const base::DictionaryValue* gl_reset_notification_strategy_value = NULL; 629 if (value->GetDictionary("gl_reset_notification_strategy", 630 &gl_reset_notification_strategy_value)) { 631 std::string op; 632 std::string int_value; 633 std::string int_value2; 634 gl_reset_notification_strategy_value->GetString(kOp, &op); 635 gl_reset_notification_strategy_value->GetString("value", &int_value); 636 gl_reset_notification_strategy_value->GetString("value2", &int_value2); 637 if (!entry->SetGLResetNotificationStrategyInfo( 638 op, int_value, int_value2)) { 639 LOG(WARNING) << "Malformed gl_reset_notification_strategy entry " 640 << entry->id(); 641 return NULL; 642 } 643 dictionary_entry_count++; 644 } 645 646 const base::DictionaryValue* cpu_brand_value = NULL; 647 if (value->GetDictionary("cpu_info", &cpu_brand_value)) { 648 std::string cpu_op; 649 std::string cpu_value; 650 cpu_brand_value->GetString(kOp, &cpu_op); 651 cpu_brand_value->GetString("value", &cpu_value); 652 if (!entry->SetCpuBrand(cpu_op, cpu_value)) { 653 LOG(WARNING) << "Malformed cpu_brand entry " << entry->id(); 654 return NULL; 655 } 656 dictionary_entry_count++; 657 } 658 659 const base::DictionaryValue* perf_graphics_value = NULL; 660 if (value->GetDictionary("perf_graphics", &perf_graphics_value)) { 661 std::string op; 662 std::string float_value; 663 std::string float_value2; 664 perf_graphics_value->GetString(kOp, &op); 665 perf_graphics_value->GetString("value", &float_value); 666 perf_graphics_value->GetString("value2", &float_value2); 667 if (!entry->SetPerfGraphicsInfo(op, float_value, float_value2)) { 668 LOG(WARNING) << "Malformed perf_graphics entry " << entry->id(); 669 return NULL; 670 } 671 dictionary_entry_count++; 672 } 673 674 const base::DictionaryValue* perf_gaming_value = NULL; 675 if (value->GetDictionary("perf_gaming", &perf_gaming_value)) { 676 std::string op; 677 std::string float_value; 678 std::string float_value2; 679 perf_gaming_value->GetString(kOp, &op); 680 perf_gaming_value->GetString("value", &float_value); 681 perf_gaming_value->GetString("value2", &float_value2); 682 if (!entry->SetPerfGamingInfo(op, float_value, float_value2)) { 683 LOG(WARNING) << "Malformed perf_gaming entry " << entry->id(); 684 return NULL; 685 } 686 dictionary_entry_count++; 687 } 688 689 const base::DictionaryValue* perf_overall_value = NULL; 690 if (value->GetDictionary("perf_overall", &perf_overall_value)) { 691 std::string op; 692 std::string float_value; 693 std::string float_value2; 694 perf_overall_value->GetString(kOp, &op); 695 perf_overall_value->GetString("value", &float_value); 696 perf_overall_value->GetString("value2", &float_value2); 697 if (!entry->SetPerfOverallInfo(op, float_value, float_value2)) { 698 LOG(WARNING) << "Malformed perf_overall entry " << entry->id(); 699 return NULL; 700 } 701 dictionary_entry_count++; 702 } 703 704 const base::DictionaryValue* machine_model_value = NULL; 705 if (value->GetDictionary("machine_model", &machine_model_value)) { 706 std::string name_op; 707 std::string name_value; 708 const base::DictionaryValue* name = NULL; 709 if (machine_model_value->GetDictionary("name", &name)) { 710 name->GetString(kOp, &name_op); 711 name->GetString("value", &name_value); 712 } 713 714 std::string version_op = "any"; 715 std::string version_string; 716 std::string version_string2; 717 const base::DictionaryValue* version_value = NULL; 718 if (machine_model_value->GetDictionary("version", &version_value)) { 719 version_value->GetString(kOp, &version_op); 720 version_value->GetString("number", &version_string); 721 version_value->GetString("number2", &version_string2); 722 } 723 if (!entry->SetMachineModelInfo( 724 name_op, name_value, version_op, version_string, version_string2)) { 725 LOG(WARNING) << "Malformed machine_model entry " << entry->id(); 726 return NULL; 727 } 728 dictionary_entry_count++; 729 } 730 731 const base::DictionaryValue* gpu_count_value = NULL; 732 if (value->GetDictionary("gpu_count", &gpu_count_value)) { 733 std::string op; 734 std::string int_value; 735 std::string int_value2; 736 gpu_count_value->GetString(kOp, &op); 737 gpu_count_value->GetString("value", &int_value); 738 gpu_count_value->GetString("value2", &int_value2); 739 if (!entry->SetGpuCountInfo(op, int_value, int_value2)) { 740 LOG(WARNING) << "Malformed gpu_count entry " << entry->id(); 741 return NULL; 742 } 743 dictionary_entry_count++; 744 } 745 746 if (top_level) { 747 const base::ListValue* feature_value = NULL; 748 if (value->GetList("features", &feature_value)) { 749 std::vector<std::string> feature_list; 750 for (size_t i = 0; i < feature_value->GetSize(); ++i) { 751 std::string feature; 752 if (feature_value->GetString(i, &feature)) { 753 feature_list.push_back(feature); 754 } else { 755 LOG(WARNING) << "Malformed feature entry " << entry->id(); 756 return NULL; 757 } 758 } 759 if (!entry->SetFeatures( 760 feature_list, feature_map, supports_feature_type_all)) { 761 LOG(WARNING) << "Malformed feature entry " << entry->id(); 762 return NULL; 763 } 764 dictionary_entry_count++; 765 } 766 } 767 768 if (top_level) { 769 const base::ListValue* exception_list_value = NULL; 770 if (value->GetList("exceptions", &exception_list_value)) { 771 for (size_t i = 0; i < exception_list_value->GetSize(); ++i) { 772 const base::DictionaryValue* exception_value = NULL; 773 if (!exception_list_value->GetDictionary(i, &exception_value)) { 774 LOG(WARNING) << "Malformed exceptions entry " << entry->id(); 775 return NULL; 776 } 777 ScopedGpuControlListEntry exception(GetEntryFromValue( 778 exception_value, false, feature_map, supports_feature_type_all)); 779 if (exception.get() == NULL) { 780 LOG(WARNING) << "Malformed exceptions entry " << entry->id(); 781 return NULL; 782 } 783 // Exception should inherit vendor_id from parent, otherwise if only 784 // device_ids are specified in Exception, the info will be incomplete. 785 if (exception->vendor_id_ == 0 && entry->vendor_id_ != 0) 786 exception->vendor_id_ = entry->vendor_id_; 787 if (exception->contains_unknown_fields_) { 788 LOG(WARNING) << "Exception with unknown fields " << entry->id(); 789 entry->contains_unknown_fields_ = true; 790 } else { 791 entry->AddException(exception); 792 } 793 } 794 dictionary_entry_count++; 795 } 796 797 const base::DictionaryValue* browser_version_value = NULL; 798 // browser_version is processed in LoadGpuControlList(). 799 if (value->GetDictionary("browser_version", &browser_version_value)) 800 dictionary_entry_count++; 801 } 802 803 if (value->size() != dictionary_entry_count) { 804 LOG(WARNING) << "Entry with unknown fields " << entry->id(); 805 entry->contains_unknown_fields_ = true; 806 } 807 return entry; 808} 809 810GpuControlList::GpuControlListEntry::GpuControlListEntry() 811 : id_(0), 812 disabled_(false), 813 vendor_id_(0), 814 multi_gpu_style_(kMultiGpuStyleNone), 815 multi_gpu_category_(kMultiGpuCategoryPrimary), 816 contains_unknown_fields_(false), 817 contains_unknown_features_(false) { 818} 819 820GpuControlList::GpuControlListEntry::~GpuControlListEntry() { } 821 822bool GpuControlList::GpuControlListEntry::SetId(uint32 id) { 823 if (id != 0) { 824 id_ = id; 825 return true; 826 } 827 return false; 828} 829 830void GpuControlList::GpuControlListEntry::SetDisabled(bool disabled) { 831 disabled_ = disabled; 832} 833 834bool GpuControlList::GpuControlListEntry::SetOsInfo( 835 const std::string& os, 836 const std::string& version_op, 837 const std::string& version_string, 838 const std::string& version_string2) { 839 os_info_.reset(new OsInfo(os, version_op, version_string, version_string2)); 840 return os_info_->IsValid(); 841} 842 843bool GpuControlList::GpuControlListEntry::SetVendorId( 844 const std::string& vendor_id_string) { 845 vendor_id_ = 0; 846 return base::HexStringToInt(vendor_id_string, 847 reinterpret_cast<int*>(&vendor_id_)); 848} 849 850bool GpuControlList::GpuControlListEntry::AddDeviceId( 851 const std::string& device_id_string) { 852 uint32 device_id = 0; 853 if (base::HexStringToInt(device_id_string, 854 reinterpret_cast<int*>(&device_id))) { 855 device_id_list_.push_back(device_id); 856 return true; 857 } 858 return false; 859} 860 861bool GpuControlList::GpuControlListEntry::SetMultiGpuStyle( 862 const std::string& multi_gpu_style_string) { 863 MultiGpuStyle style = StringToMultiGpuStyle(multi_gpu_style_string); 864 if (style == kMultiGpuStyleNone) 865 return false; 866 multi_gpu_style_ = style; 867 return true; 868} 869 870bool GpuControlList::GpuControlListEntry::SetMultiGpuCategory( 871 const std::string& multi_gpu_category_string) { 872 MultiGpuCategory category = 873 StringToMultiGpuCategory(multi_gpu_category_string); 874 if (category == kMultiGpuCategoryNone) 875 return false; 876 multi_gpu_category_ = category; 877 return true; 878} 879 880bool GpuControlList::GpuControlListEntry::SetDriverVendorInfo( 881 const std::string& vendor_op, 882 const std::string& vendor_value) { 883 driver_vendor_info_.reset(new StringInfo(vendor_op, vendor_value)); 884 return driver_vendor_info_->IsValid(); 885} 886 887bool GpuControlList::GpuControlListEntry::SetDriverVersionInfo( 888 const std::string& version_op, 889 const std::string& version_style, 890 const std::string& version_string, 891 const std::string& version_string2) { 892 driver_version_info_.reset(new VersionInfo( 893 version_op, version_style, version_string, version_string2)); 894 return driver_version_info_->IsValid(); 895} 896 897bool GpuControlList::GpuControlListEntry::SetDriverDateInfo( 898 const std::string& date_op, 899 const std::string& date_string, 900 const std::string& date_string2) { 901 driver_date_info_.reset( 902 new VersionInfo(date_op, std::string(), date_string, date_string2)); 903 return driver_date_info_->IsValid(); 904} 905 906bool GpuControlList::GpuControlListEntry::SetGLVendorInfo( 907 const std::string& vendor_op, 908 const std::string& vendor_value) { 909 gl_vendor_info_.reset(new StringInfo(vendor_op, vendor_value)); 910 return gl_vendor_info_->IsValid(); 911} 912 913bool GpuControlList::GpuControlListEntry::SetGLRendererInfo( 914 const std::string& renderer_op, 915 const std::string& renderer_value) { 916 gl_renderer_info_.reset(new StringInfo(renderer_op, renderer_value)); 917 return gl_renderer_info_->IsValid(); 918} 919 920bool GpuControlList::GpuControlListEntry::SetGLExtensionsInfo( 921 const std::string& extensions_op, 922 const std::string& extensions_value) { 923 gl_extensions_info_.reset(new StringInfo(extensions_op, extensions_value)); 924 return gl_extensions_info_->IsValid(); 925} 926 927bool GpuControlList::GpuControlListEntry::SetGLResetNotificationStrategyInfo( 928 const std::string& op, 929 const std::string& int_string, 930 const std::string& int_string2) { 931 gl_reset_notification_strategy_info_.reset( 932 new IntInfo(op, int_string, int_string2)); 933 return gl_reset_notification_strategy_info_->IsValid(); 934} 935 936bool GpuControlList::GpuControlListEntry::SetCpuBrand( 937 const std::string& cpu_op, 938 const std::string& cpu_value) { 939 cpu_brand_.reset(new StringInfo(cpu_op, cpu_value)); 940 return cpu_brand_->IsValid(); 941} 942 943bool GpuControlList::GpuControlListEntry::SetPerfGraphicsInfo( 944 const std::string& op, 945 const std::string& float_string, 946 const std::string& float_string2) { 947 perf_graphics_info_.reset(new FloatInfo(op, float_string, float_string2)); 948 return perf_graphics_info_->IsValid(); 949} 950 951bool GpuControlList::GpuControlListEntry::SetPerfGamingInfo( 952 const std::string& op, 953 const std::string& float_string, 954 const std::string& float_string2) { 955 perf_gaming_info_.reset(new FloatInfo(op, float_string, float_string2)); 956 return perf_gaming_info_->IsValid(); 957} 958 959bool GpuControlList::GpuControlListEntry::SetPerfOverallInfo( 960 const std::string& op, 961 const std::string& float_string, 962 const std::string& float_string2) { 963 perf_overall_info_.reset(new FloatInfo(op, float_string, float_string2)); 964 return perf_overall_info_->IsValid(); 965} 966 967bool GpuControlList::GpuControlListEntry::SetMachineModelInfo( 968 const std::string& name_op, 969 const std::string& name_value, 970 const std::string& version_op, 971 const std::string& version_string, 972 const std::string& version_string2) { 973 machine_model_info_.reset(new MachineModelInfo( 974 name_op, name_value, version_op, version_string, version_string2)); 975 return machine_model_info_->IsValid(); 976} 977 978bool GpuControlList::GpuControlListEntry::SetGpuCountInfo( 979 const std::string& op, 980 const std::string& int_string, 981 const std::string& int_string2) { 982 gpu_count_info_.reset(new IntInfo(op, int_string, int_string2)); 983 return gpu_count_info_->IsValid(); 984} 985 986bool GpuControlList::GpuControlListEntry::SetFeatures( 987 const std::vector<std::string>& feature_strings, 988 const FeatureMap& feature_map, 989 bool supports_feature_type_all) { 990 size_t size = feature_strings.size(); 991 if (size == 0) 992 return false; 993 features_.clear(); 994 for (size_t i = 0; i < size; ++i) { 995 int feature = 0; 996 if (supports_feature_type_all && feature_strings[i] == "all") { 997 for (FeatureMap::const_iterator iter = feature_map.begin(); 998 iter != feature_map.end(); ++iter) 999 features_.insert(iter->second); 1000 continue; 1001 } 1002 if (StringToFeature(feature_strings[i], &feature, feature_map)) 1003 features_.insert(feature); 1004 else 1005 contains_unknown_features_ = true; 1006 } 1007 return true; 1008} 1009 1010void GpuControlList::GpuControlListEntry::AddException( 1011 ScopedGpuControlListEntry exception) { 1012 exceptions_.push_back(exception); 1013} 1014 1015// static 1016GpuControlList::GpuControlListEntry::MultiGpuStyle 1017GpuControlList::GpuControlListEntry::StringToMultiGpuStyle( 1018 const std::string& style) { 1019 if (style == kMultiGpuStyleStringOptimus) 1020 return kMultiGpuStyleOptimus; 1021 if (style == kMultiGpuStyleStringAMDSwitchable) 1022 return kMultiGpuStyleAMDSwitchable; 1023 return kMultiGpuStyleNone; 1024} 1025 1026// static 1027GpuControlList::GpuControlListEntry::MultiGpuCategory 1028GpuControlList::GpuControlListEntry::StringToMultiGpuCategory( 1029 const std::string& category) { 1030 if (category == kMultiGpuCategoryStringPrimary) 1031 return kMultiGpuCategoryPrimary; 1032 if (category == kMultiGpuCategoryStringSecondary) 1033 return kMultiGpuCategorySecondary; 1034 if (category == kMultiGpuCategoryStringAny) 1035 return kMultiGpuCategoryAny; 1036 return kMultiGpuCategoryNone; 1037} 1038 1039bool GpuControlList::GpuControlListEntry::Contains( 1040 OsType os_type, const std::string& os_version, 1041 const GPUInfo& gpu_info) const { 1042 DCHECK(os_type != kOsAny); 1043 if (os_info_.get() != NULL && !os_info_->Contains(os_type, os_version)) 1044 return false; 1045 bool is_not_primary_gpu = 1046 GpuUnmatched(vendor_id_, device_id_list_, gpu_info.gpu); 1047 bool is_not_secondary_gpu = true; 1048 for (size_t i = 0; i < gpu_info.secondary_gpus.size(); ++i) { 1049 is_not_secondary_gpu = is_not_secondary_gpu && 1050 GpuUnmatched(vendor_id_, device_id_list_, gpu_info.secondary_gpus[i]); 1051 } 1052 switch (multi_gpu_category_) { 1053 case kMultiGpuCategoryPrimary: 1054 if (is_not_primary_gpu) 1055 return false; 1056 break; 1057 case kMultiGpuCategorySecondary: 1058 if (is_not_secondary_gpu) 1059 return false; 1060 break; 1061 case kMultiGpuCategoryAny: 1062 if (is_not_primary_gpu && is_not_secondary_gpu) 1063 return false; 1064 break; 1065 case kMultiGpuCategoryNone: 1066 break; 1067 } 1068 switch (multi_gpu_style_) { 1069 case kMultiGpuStyleOptimus: 1070 if (!gpu_info.optimus) 1071 return false; 1072 break; 1073 case kMultiGpuStyleAMDSwitchable: 1074 if (!gpu_info.amd_switchable) 1075 return false; 1076 break; 1077 case kMultiGpuStyleNone: 1078 break; 1079 } 1080 if (driver_vendor_info_.get() != NULL && !gpu_info.driver_vendor.empty() && 1081 !driver_vendor_info_->Contains(gpu_info.driver_vendor)) 1082 return false; 1083 if (driver_version_info_.get() != NULL && !gpu_info.driver_version.empty()) { 1084 if (!driver_version_info_->Contains(gpu_info.driver_version)) 1085 return false; 1086 } 1087 if (driver_date_info_.get() != NULL && !gpu_info.driver_date.empty()) { 1088 if (!driver_date_info_->Contains(gpu_info.driver_date, '-')) 1089 return false; 1090 } 1091 if (gl_vendor_info_.get() != NULL && !gpu_info.gl_vendor.empty() && 1092 !gl_vendor_info_->Contains(gpu_info.gl_vendor)) 1093 return false; 1094 if (gl_renderer_info_.get() != NULL && !gpu_info.gl_renderer.empty() && 1095 !gl_renderer_info_->Contains(gpu_info.gl_renderer)) 1096 return false; 1097 if (gl_extensions_info_.get() != NULL && !gpu_info.gl_extensions.empty() && 1098 !gl_extensions_info_->Contains(gpu_info.gl_extensions)) 1099 return false; 1100 if (gl_reset_notification_strategy_info_.get() != NULL && 1101 !gl_reset_notification_strategy_info_->Contains( 1102 gpu_info.gl_reset_notification_strategy)) 1103 return false; 1104 if (perf_graphics_info_.get() != NULL && 1105 (gpu_info.performance_stats.graphics == 0.0 || 1106 !perf_graphics_info_->Contains(gpu_info.performance_stats.graphics))) 1107 return false; 1108 if (perf_gaming_info_.get() != NULL && 1109 (gpu_info.performance_stats.gaming == 0.0 || 1110 !perf_gaming_info_->Contains(gpu_info.performance_stats.gaming))) 1111 return false; 1112 if (perf_overall_info_.get() != NULL && 1113 (gpu_info.performance_stats.overall == 0.0 || 1114 !perf_overall_info_->Contains(gpu_info.performance_stats.overall))) 1115 return false; 1116 if (machine_model_info_.get() != NULL) { 1117 std::vector<std::string> name_version; 1118 base::SplitString(gpu_info.machine_model, ' ', &name_version); 1119 if (name_version.size() == 2 && 1120 !machine_model_info_->Contains(name_version[0], name_version[1])) 1121 return false; 1122 } 1123 if (gpu_count_info_.get() != NULL && 1124 !gpu_count_info_->Contains(gpu_info.secondary_gpus.size() + 1)) 1125 return false; 1126 if (cpu_brand_.get() != NULL) { 1127 base::CPU cpu_info; 1128 if (!cpu_brand_->Contains(cpu_info.cpu_brand())) 1129 return false; 1130 } 1131 1132 for (size_t i = 0; i < exceptions_.size(); ++i) { 1133 if (exceptions_[i]->Contains(os_type, os_version, gpu_info) && 1134 !exceptions_[i]->NeedsMoreInfo(gpu_info)) 1135 return false; 1136 } 1137 return true; 1138} 1139 1140bool GpuControlList::GpuControlListEntry::NeedsMoreInfo( 1141 const GPUInfo& gpu_info) const { 1142 // We only check for missing info that might be collected with a gl context. 1143 // If certain info is missing due to some error, say, we fail to collect 1144 // vendor_id/device_id, then even if we launch GPU process and create a gl 1145 // context, we won't gather such missing info, so we still return false. 1146 if (driver_vendor_info_.get() && gpu_info.driver_vendor.empty()) 1147 return true; 1148 if (driver_version_info_.get() && gpu_info.driver_version.empty()) 1149 return true; 1150 if (gl_vendor_info_.get() && gpu_info.gl_vendor.empty()) 1151 return true; 1152 if (gl_renderer_info_.get() && gpu_info.gl_renderer.empty()) 1153 return true; 1154 for (size_t i = 0; i < exceptions_.size(); ++i) { 1155 if (exceptions_[i]->NeedsMoreInfo(gpu_info)) 1156 return true; 1157 } 1158 return false; 1159} 1160 1161GpuControlList::OsType GpuControlList::GpuControlListEntry::GetOsType() const { 1162 if (os_info_.get() == NULL) 1163 return kOsAny; 1164 return os_info_->type(); 1165} 1166 1167uint32 GpuControlList::GpuControlListEntry::id() const { 1168 return id_; 1169} 1170 1171bool GpuControlList::GpuControlListEntry::disabled() const { 1172 return disabled_; 1173} 1174 1175const std::set<int>& GpuControlList::GpuControlListEntry::features() const { 1176 return features_; 1177} 1178 1179// static 1180bool GpuControlList::GpuControlListEntry::StringToFeature( 1181 const std::string& feature_name, int* feature_id, 1182 const FeatureMap& feature_map) { 1183 FeatureMap::const_iterator iter = feature_map.find(feature_name); 1184 if (iter != feature_map.end()) { 1185 *feature_id = iter->second; 1186 return true; 1187 } 1188 return false; 1189} 1190 1191GpuControlList::GpuControlList() 1192 : max_entry_id_(0), 1193 contains_unknown_fields_(false), 1194 needs_more_info_(false), 1195 supports_feature_type_all_(false) { 1196} 1197 1198GpuControlList::~GpuControlList() { 1199 Clear(); 1200} 1201 1202bool GpuControlList::LoadList( 1203 const std::string& json_context, GpuControlList::OsFilter os_filter) { 1204 const std::string browser_version_string = "0"; 1205 return LoadList(browser_version_string, json_context, os_filter); 1206} 1207 1208bool GpuControlList::LoadList( 1209 const std::string& browser_version_string, 1210 const std::string& json_context, 1211 GpuControlList::OsFilter os_filter) { 1212 std::vector<std::string> pieces; 1213 if (!ProcessVersionString(browser_version_string, '.', &pieces)) 1214 return false; 1215 browser_version_ = browser_version_string; 1216 1217 scoped_ptr<base::Value> root; 1218 root.reset(base::JSONReader::Read(json_context)); 1219 if (root.get() == NULL || !root->IsType(base::Value::TYPE_DICTIONARY)) 1220 return false; 1221 1222 base::DictionaryValue* root_dictionary = 1223 static_cast<base::DictionaryValue*>(root.get()); 1224 DCHECK(root_dictionary); 1225 return LoadList(*root_dictionary, os_filter); 1226} 1227 1228bool GpuControlList::LoadList(const base::DictionaryValue& parsed_json, 1229 GpuControlList::OsFilter os_filter) { 1230 std::vector<ScopedGpuControlListEntry> entries; 1231 1232 parsed_json.GetString("version", &version_); 1233 std::vector<std::string> pieces; 1234 if (!ProcessVersionString(version_, '.', &pieces)) 1235 return false; 1236 1237 const base::ListValue* list = NULL; 1238 if (!parsed_json.GetList("entries", &list)) 1239 return false; 1240 1241 uint32 max_entry_id = 0; 1242 bool contains_unknown_fields = false; 1243 for (size_t i = 0; i < list->GetSize(); ++i) { 1244 const base::DictionaryValue* list_item = NULL; 1245 bool valid = list->GetDictionary(i, &list_item); 1246 if (!valid || list_item == NULL) 1247 return false; 1248 // Check browser version compatibility: if the entry is not for the 1249 // current browser version, don't process it. 1250 BrowserVersionSupport browser_version_support = 1251 IsEntrySupportedByCurrentBrowserVersion(list_item); 1252 if (browser_version_support == kMalformed) 1253 return false; 1254 if (browser_version_support == kUnsupported) 1255 continue; 1256 DCHECK(browser_version_support == kSupported); 1257 ScopedGpuControlListEntry entry(GpuControlListEntry::GetEntryFromValue( 1258 list_item, true, feature_map_, supports_feature_type_all_)); 1259 if (entry.get() == NULL) 1260 return false; 1261 if (entry->id() > max_entry_id) 1262 max_entry_id = entry->id(); 1263 // If an unknown field is encountered, skip the entry; if an unknown 1264 // feature is encountered, ignore the feature, but keep the entry. 1265 if (entry->contains_unknown_fields()) { 1266 contains_unknown_fields = true; 1267 continue; 1268 } 1269 if (entry->contains_unknown_features()) 1270 contains_unknown_fields = true; 1271 entries.push_back(entry); 1272 } 1273 1274 Clear(); 1275 OsType my_os = GetOsType(); 1276 for (size_t i = 0; i < entries.size(); ++i) { 1277 OsType entry_os = entries[i]->GetOsType(); 1278 if (os_filter == GpuControlList::kAllOs || 1279 entry_os == kOsAny || entry_os == my_os) 1280 entries_.push_back(entries[i]); 1281 } 1282 max_entry_id_ = max_entry_id; 1283 contains_unknown_fields_ = contains_unknown_fields; 1284 return true; 1285} 1286 1287std::set<int> GpuControlList::MakeDecision( 1288 GpuControlList::OsType os, 1289 std::string os_version, 1290 const GPUInfo& gpu_info) { 1291 active_entries_.clear(); 1292 std::set<int> features; 1293 1294 needs_more_info_ = false; 1295 std::set<int> possible_features; 1296 1297 if (os == kOsAny) 1298 os = GetOsType(); 1299 if (os_version.empty()) { 1300 os_version = base::SysInfo::OperatingSystemVersion(); 1301 size_t pos = os_version.find_first_not_of("0123456789."); 1302 if (pos != std::string::npos) 1303 os_version = os_version.substr(0, pos); 1304 } 1305 std::vector<std::string> pieces; 1306 if (!ProcessVersionString(os_version, '.', &pieces)) 1307 os_version = "0"; 1308 1309 for (size_t i = 0; i < entries_.size(); ++i) { 1310 if (entries_[i]->Contains(os, os_version, gpu_info)) { 1311 if (!entries_[i]->disabled()) { 1312 MergeFeatureSets(&possible_features, entries_[i]->features()); 1313 if (!entries_[i]->NeedsMoreInfo(gpu_info)) 1314 MergeFeatureSets(&features, entries_[i]->features()); 1315 } 1316 active_entries_.push_back(entries_[i]); 1317 } 1318 } 1319 1320 if (possible_features.size() > features.size()) 1321 needs_more_info_ = true; 1322 1323 return features; 1324} 1325 1326void GpuControlList::GetDecisionEntries( 1327 std::vector<uint32>* entry_ids, bool disabled) const { 1328 DCHECK(entry_ids); 1329 entry_ids->clear(); 1330 for (size_t i = 0; i < active_entries_.size(); ++i) { 1331 if (disabled == active_entries_[i]->disabled()) 1332 entry_ids->push_back(active_entries_[i]->id()); 1333 } 1334} 1335 1336void GpuControlList::GetReasons(base::ListValue* problem_list) const { 1337 DCHECK(problem_list); 1338 for (size_t i = 0; i < active_entries_.size(); ++i) { 1339 GpuControlListEntry* entry = active_entries_[i].get(); 1340 if (entry->disabled()) 1341 continue; 1342 base::DictionaryValue* problem = new base::DictionaryValue(); 1343 1344 problem->SetString("description", entry->description()); 1345 1346 base::ListValue* cr_bugs = new base::ListValue(); 1347 for (size_t j = 0; j < entry->cr_bugs().size(); ++j) 1348 cr_bugs->Append(new base::FundamentalValue(entry->cr_bugs()[j])); 1349 problem->Set("crBugs", cr_bugs); 1350 1351 base::ListValue* webkit_bugs = new base::ListValue(); 1352 for (size_t j = 0; j < entry->webkit_bugs().size(); ++j) { 1353 webkit_bugs->Append(new base::FundamentalValue(entry->webkit_bugs()[j])); 1354 } 1355 problem->Set("webkitBugs", webkit_bugs); 1356 1357 problem_list->Append(problem); 1358 } 1359} 1360 1361size_t GpuControlList::num_entries() const { 1362 return entries_.size(); 1363} 1364 1365uint32 GpuControlList::max_entry_id() const { 1366 return max_entry_id_; 1367} 1368 1369std::string GpuControlList::version() const { 1370 return version_; 1371} 1372 1373GpuControlList::OsType GpuControlList::GetOsType() { 1374#if defined(OS_CHROMEOS) 1375 return kOsChromeOS; 1376#elif defined(OS_WIN) 1377 return kOsWin; 1378#elif defined(OS_ANDROID) 1379 return kOsAndroid; 1380#elif defined(OS_LINUX) || defined(OS_OPENBSD) 1381 return kOsLinux; 1382#elif defined(OS_MACOSX) 1383 return kOsMacosx; 1384#else 1385 return kOsUnknown; 1386#endif 1387} 1388 1389void GpuControlList::Clear() { 1390 entries_.clear(); 1391 active_entries_.clear(); 1392 max_entry_id_ = 0; 1393 contains_unknown_fields_ = false; 1394} 1395 1396GpuControlList::BrowserVersionSupport 1397GpuControlList::IsEntrySupportedByCurrentBrowserVersion( 1398 const base::DictionaryValue* value) { 1399 DCHECK(value); 1400 const base::DictionaryValue* browser_version_value = NULL; 1401 if (value->GetDictionary("browser_version", &browser_version_value)) { 1402 std::string version_op = "any"; 1403 std::string version_string; 1404 std::string version_string2; 1405 browser_version_value->GetString(kOp, &version_op); 1406 browser_version_value->GetString("number", &version_string); 1407 browser_version_value->GetString("number2", &version_string2); 1408 scoped_ptr<VersionInfo> browser_version_info; 1409 browser_version_info.reset(new VersionInfo( 1410 version_op, std::string(), version_string, version_string2)); 1411 if (!browser_version_info->IsValid()) 1412 return kMalformed; 1413 if (browser_version_info->Contains(browser_version_)) 1414 return kSupported; 1415 return kUnsupported; 1416 } 1417 return kSupported; 1418} 1419 1420// static 1421GpuControlList::NumericOp GpuControlList::StringToNumericOp( 1422 const std::string& op) { 1423 if (op == "=") 1424 return kEQ; 1425 if (op == "<") 1426 return kLT; 1427 if (op == "<=") 1428 return kLE; 1429 if (op == ">") 1430 return kGT; 1431 if (op == ">=") 1432 return kGE; 1433 if (op == "any") 1434 return kAny; 1435 if (op == "between") 1436 return kBetween; 1437 return kUnknown; 1438} 1439 1440void GpuControlList::AddSupportedFeature( 1441 const std::string& feature_name, int feature_id) { 1442 feature_map_[feature_name] = feature_id; 1443} 1444 1445void GpuControlList::set_supports_feature_type_all(bool supported) { 1446 supports_feature_type_all_ = supported; 1447} 1448 1449} // namespace gpu 1450 1451