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