Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/gpu/gpu_blacklist.h" | 5 #include "content/browser/gpu/gpu_blacklist.h" |
| 6 | 6 |
| 7 #include "base/json/json_reader.h" | 7 #include "base/json/json_reader.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
| 10 #include "base/string_piece.h" | 10 #include "base/string_piece.h" |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 199 return kEQ; | 199 return kEQ; |
| 200 else if (string_op == "contains") | 200 else if (string_op == "contains") |
| 201 return kContains; | 201 return kContains; |
| 202 else if (string_op == "beginwith") | 202 else if (string_op == "beginwith") |
| 203 return kBeginWith; | 203 return kBeginWith; |
| 204 else if (string_op == "endwith") | 204 else if (string_op == "endwith") |
| 205 return kEndWith; | 205 return kEndWith; |
| 206 return kUnknown; | 206 return kUnknown; |
| 207 } | 207 } |
| 208 | 208 |
| 209 // static | |
| 209 GpuBlacklist::GpuBlacklistEntry* | 210 GpuBlacklist::GpuBlacklistEntry* |
| 210 GpuBlacklist::GpuBlacklistEntry::GetGpuBlacklistEntryFromValue( | 211 GpuBlacklist::GpuBlacklistEntry::GetGpuBlacklistEntryFromValue( |
| 211 DictionaryValue* value, bool top_level) { | 212 DictionaryValue* value, bool top_level) { |
| 212 DCHECK(value); | 213 DCHECK(value); |
| 213 scoped_ptr<GpuBlacklistEntry> entry(new GpuBlacklistEntry()); | 214 scoped_ptr<GpuBlacklistEntry> entry(new GpuBlacklistEntry()); |
| 214 | 215 |
| 215 size_t dictionary_entry_count = 0; | 216 size_t dictionary_entry_count = 0; |
| 216 | 217 |
| 217 if (top_level) { | 218 if (top_level) { |
| 218 uint32 id; | 219 uint32 id; |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 392 if (!exception_list_value->GetDictionary(i, &exception_value)) { | 393 if (!exception_list_value->GetDictionary(i, &exception_value)) { |
| 393 LOG(WARNING) << "Malformed exceptions entry " << entry->id(); | 394 LOG(WARNING) << "Malformed exceptions entry " << entry->id(); |
| 394 return NULL; | 395 return NULL; |
| 395 } | 396 } |
| 396 GpuBlacklistEntry* exception = GetGpuBlacklistEntryFromValue( | 397 GpuBlacklistEntry* exception = GetGpuBlacklistEntryFromValue( |
| 397 exception_value, false); | 398 exception_value, false); |
| 398 if (exception == NULL) { | 399 if (exception == NULL) { |
| 399 LOG(WARNING) << "Malformed exceptions entry " << entry->id(); | 400 LOG(WARNING) << "Malformed exceptions entry " << entry->id(); |
| 400 return NULL; | 401 return NULL; |
| 401 } | 402 } |
| 402 entry->AddException(exception); | 403 if (exception->contains_unknown_field_) { |
| 404 LOG(WARNING) << "Exception with unknown fields " << entry->id(); | |
| 405 delete exception; | |
| 406 entry->contains_exception_with_unknown_field_ = true; | |
| 407 } else { | |
| 408 entry->AddException(exception); | |
| 409 } | |
| 403 } | 410 } |
| 404 dictionary_entry_count++; | 411 dictionary_entry_count++; |
| 405 } | 412 } |
| 406 | 413 |
| 407 DictionaryValue* browser_version_value = NULL; | 414 DictionaryValue* browser_version_value = NULL; |
| 408 // browser_version is processed in LoadGpuBlacklist(). | 415 // browser_version is processed in LoadGpuBlacklist(). |
| 409 if (value->GetDictionary("browser_version", &browser_version_value)) | 416 if (value->GetDictionary("browser_version", &browser_version_value)) |
| 410 dictionary_entry_count++; | 417 dictionary_entry_count++; |
| 411 } | 418 } |
| 412 | 419 |
| 413 if (value->size() != dictionary_entry_count) { | 420 if (value->size() != dictionary_entry_count) { |
| 414 LOG(WARNING) << "Malformed entry " << entry->id(); | 421 LOG(WARNING) << "Entry with unknown fields " << entry->id(); |
| 415 return NULL; | 422 entry->contains_unknown_field_ = true; |
| 416 } | 423 } |
| 417 return entry.release(); | 424 return entry.release(); |
| 418 } | 425 } |
| 419 | 426 |
| 420 GpuBlacklist::GpuBlacklistEntry::~GpuBlacklistEntry() { | 427 GpuBlacklist::GpuBlacklistEntry::~GpuBlacklistEntry() { |
| 421 for (size_t i = 0; i < exceptions_.size(); ++i) | 428 for (size_t i = 0; i < exceptions_.size(); ++i) |
| 422 delete exceptions_[i]; | 429 delete exceptions_[i]; |
| 423 } | 430 } |
| 424 | 431 |
| 425 GpuBlacklist::GpuBlacklistEntry::GpuBlacklistEntry() | 432 GpuBlacklist::GpuBlacklistEntry::GpuBlacklistEntry() |
| 426 : id_(0), | 433 : id_(0), |
| 427 vendor_id_(0) { | 434 vendor_id_(0), |
| 435 contains_unknown_field_(false), | |
| 436 contains_exception_with_unknown_field_(false) { | |
| 428 } | 437 } |
| 429 | 438 |
| 430 bool GpuBlacklist::GpuBlacklistEntry::SetId(uint32 id) { | 439 bool GpuBlacklist::GpuBlacklistEntry::SetId(uint32 id) { |
| 431 if (id != 0) { | 440 if (id != 0) { |
| 432 id_ = id; | 441 id_ = id; |
| 433 return true; | 442 return true; |
| 434 } | 443 } |
| 435 return false; | 444 return false; |
| 436 } | 445 } |
| 437 | 446 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 507 GpuFeatureFlags::StringToGpuFeatureType(blacklisted_features[i]); | 516 GpuFeatureFlags::StringToGpuFeatureType(blacklisted_features[i]); |
| 508 switch (type) { | 517 switch (type) { |
| 509 case GpuFeatureFlags::kGpuFeatureAccelerated2dCanvas: | 518 case GpuFeatureFlags::kGpuFeatureAccelerated2dCanvas: |
| 510 case GpuFeatureFlags::kGpuFeatureAcceleratedCompositing: | 519 case GpuFeatureFlags::kGpuFeatureAcceleratedCompositing: |
| 511 case GpuFeatureFlags::kGpuFeatureWebgl: | 520 case GpuFeatureFlags::kGpuFeatureWebgl: |
| 512 case GpuFeatureFlags::kGpuFeatureMultisampling: | 521 case GpuFeatureFlags::kGpuFeatureMultisampling: |
| 513 case GpuFeatureFlags::kGpuFeatureAll: | 522 case GpuFeatureFlags::kGpuFeatureAll: |
| 514 flags |= type; | 523 flags |= type; |
| 515 break; | 524 break; |
| 516 case GpuFeatureFlags::kGpuFeatureUnknown: | 525 case GpuFeatureFlags::kGpuFeatureUnknown: |
| 517 return false; | 526 contains_unknown_field_ = true; |
| 527 break; | |
| 518 } | 528 } |
| 519 } | 529 } |
| 520 feature_flags_.reset(new GpuFeatureFlags()); | 530 feature_flags_.reset(new GpuFeatureFlags()); |
| 521 feature_flags_->set_flags(flags); | 531 feature_flags_->set_flags(flags); |
| 522 return true; | 532 return true; |
| 523 } | 533 } |
| 524 | 534 |
| 525 void GpuBlacklist::GpuBlacklistEntry::AddException( | 535 void GpuBlacklist::GpuBlacklistEntry::AddException( |
| 526 GpuBlacklistEntry* exception) { | 536 GpuBlacklistEntry* exception) { |
| 527 exceptions_.push_back(exception); | 537 exceptions_.push_back(exception); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 588 GpuBlacklist::GpuBlacklist(const std::string& browser_version_string) | 598 GpuBlacklist::GpuBlacklist(const std::string& browser_version_string) |
| 589 : max_entry_id_(0) { | 599 : max_entry_id_(0) { |
| 590 browser_version_.reset(Version::GetVersionFromString(browser_version_string)); | 600 browser_version_.reset(Version::GetVersionFromString(browser_version_string)); |
| 591 DCHECK(browser_version_.get() != NULL); | 601 DCHECK(browser_version_.get() != NULL); |
| 592 } | 602 } |
| 593 | 603 |
| 594 GpuBlacklist::~GpuBlacklist() { | 604 GpuBlacklist::~GpuBlacklist() { |
| 595 Clear(); | 605 Clear(); |
| 596 } | 606 } |
| 597 | 607 |
| 598 bool GpuBlacklist::LoadGpuBlacklist(const std::string& json_context, | 608 bool GpuBlacklist::LoadGpuBlacklist( |
| 599 bool current_os_only) { | 609 const std::string& json_context, |
| 610 GpuBlacklist::OsFilter os_filter, | |
| 611 GpuBlacklist::UnknownFieldOption unknown_field_option) { | |
| 600 scoped_ptr<Value> root; | 612 scoped_ptr<Value> root; |
| 601 root.reset(base::JSONReader::Read(json_context, false)); | 613 root.reset(base::JSONReader::Read(json_context, false)); |
| 602 if (root.get() == NULL || !root->IsType(Value::TYPE_DICTIONARY)) | 614 if (root.get() == NULL || !root->IsType(Value::TYPE_DICTIONARY)) |
| 603 return false; | 615 return false; |
| 604 | 616 |
| 605 DictionaryValue* root_dictionary = static_cast<DictionaryValue*>(root.get()); | 617 DictionaryValue* root_dictionary = static_cast<DictionaryValue*>(root.get()); |
| 606 DCHECK(root_dictionary); | 618 DCHECK(root_dictionary); |
| 607 return LoadGpuBlacklist(*root_dictionary, current_os_only); | 619 return LoadGpuBlacklist(*root_dictionary, os_filter, unknown_field_option); |
| 608 } | 620 } |
| 609 | 621 |
| 610 bool GpuBlacklist::LoadGpuBlacklist(const DictionaryValue& parsed_json, | 622 bool GpuBlacklist::LoadGpuBlacklist( |
| 611 bool current_os_only) { | 623 const DictionaryValue& parsed_json, |
| 624 GpuBlacklist::OsFilter os_filter, | |
| 625 GpuBlacklist::UnknownFieldOption unknown_field_option) { | |
| 612 std::vector<GpuBlacklistEntry*> entries; | 626 std::vector<GpuBlacklistEntry*> entries; |
| 613 | 627 |
| 614 std::string version_string; | 628 std::string version_string; |
| 615 parsed_json.GetString("version", &version_string); | 629 parsed_json.GetString("version", &version_string); |
| 616 version_.reset(Version::GetVersionFromString(version_string)); | 630 version_.reset(Version::GetVersionFromString(version_string)); |
| 617 if (version_.get() == NULL) | 631 if (version_.get() == NULL) |
| 618 return false; | 632 return false; |
| 619 | 633 |
| 620 ListValue* list = NULL; | 634 ListValue* list = NULL; |
| 621 if (!parsed_json.GetList("entries", &list)) | 635 if (!parsed_json.GetList("entries", &list)) |
| 622 return false; | 636 return false; |
| 623 | 637 |
| 638 bool error = false; | |
| 624 uint32 max_entry_id = 0; | 639 uint32 max_entry_id = 0; |
| 625 size_t entry_count_expectation = list->GetSize(); | |
| 626 for (size_t i = 0; i < list->GetSize(); ++i) { | 640 for (size_t i = 0; i < list->GetSize(); ++i) { |
| 641 error = true; | |
|
vangelis
2011/08/19 22:50:07
I find the use of the error variable is a bit conf
Zhenyao Mo
2011/08/23 22:16:44
Done.
| |
| 627 DictionaryValue* list_item = NULL; | 642 DictionaryValue* list_item = NULL; |
| 628 bool valid = list->GetDictionary(i, &list_item); | 643 bool valid = list->GetDictionary(i, &list_item); |
| 629 if (!valid) | 644 if (!valid) |
| 630 break; | 645 break; |
| 631 if (list_item == NULL) | 646 if (list_item == NULL) |
| 632 break; | 647 break; |
| 633 // Check browser version compatibility: if the entry is not for the | 648 // Check browser version compatibility: if the entry is not for the |
| 634 // current browser version, don't process it. | 649 // current browser version, don't process it. |
| 635 BrowserVersionSupport browser_version_support = | 650 BrowserVersionSupport browser_version_support = |
| 636 IsEntrySupportedByCurrentBrowserVersion(list_item); | 651 IsEntrySupportedByCurrentBrowserVersion(list_item); |
| 637 if (browser_version_support == kMalformed) | 652 if (browser_version_support == kMalformed) |
| 638 break; | 653 break; |
| 639 if (browser_version_support == kUnsupported) { | 654 if (browser_version_support == kUnsupported) { |
| 640 entry_count_expectation--; | 655 error = false; |
| 641 continue; | 656 continue; |
| 642 } | 657 } |
| 643 DCHECK(browser_version_support == kSupported); | 658 DCHECK(browser_version_support == kSupported); |
| 644 GpuBlacklistEntry* entry = | 659 GpuBlacklistEntry* entry = |
| 645 GpuBlacklistEntry::GetGpuBlacklistEntryFromValue(list_item, true); | 660 GpuBlacklistEntry::GetGpuBlacklistEntryFromValue(list_item, true); |
| 646 if (entry == NULL) | 661 if (entry == NULL) |
| 647 break; | 662 break; |
| 663 if (entry->contains_unknown_field()) { | |
| 664 delete entry; | |
| 665 if (unknown_field_option == kFailOnUnknownField) | |
|
vangelis
2011/08/19 22:50:07
I think kFailOnUnknownField adds a lot of unnecess
Zhenyao Mo
2011/08/23 22:16:44
Done.
| |
| 666 break; | |
| 667 error = false; | |
| 668 continue; | |
| 669 } else if (entry->contains_exception_with_unknown_field()) { | |
|
vangelis
2011/08/19 22:50:07
Don't need an else if here. Previous if clause ei
Zhenyao Mo
2011/08/23 22:16:44
Done.
| |
| 670 if (unknown_field_option == kFailOnUnknownField) { | |
| 671 delete entry; | |
|
vangelis
2011/08/19 22:50:07
Don't need to delete the entry here. It will be t
Zhenyao Mo
2011/08/23 22:16:44
Done.
| |
| 672 break; | |
| 673 } else if (unknown_field_option == kIgnoreEntryWithUnknownField) { | |
| 674 delete entry; | |
| 675 error = false; | |
| 676 continue; | |
| 677 } | |
| 678 } | |
| 648 if (entry->id() > max_entry_id) | 679 if (entry->id() > max_entry_id) |
| 649 max_entry_id = entry->id(); | 680 max_entry_id = entry->id(); |
| 650 entries.push_back(entry); | 681 entries.push_back(entry); |
| 682 error = false; | |
| 651 } | 683 } |
| 652 | 684 |
| 653 if (entries.size() != entry_count_expectation) { | 685 if (error) { |
| 654 for (size_t i = 0; i < entries.size(); ++i) | 686 for (size_t i = 0; i < entries.size(); ++i) |
| 655 delete entries[i]; | 687 delete entries[i]; |
|
vangelis
2011/08/19 22:50:07
The management of entries is getting kind of hairy
Zhenyao Mo
2011/08/23 22:16:44
Done.
| |
| 656 return false; | 688 return false; |
| 657 } | 689 } |
| 658 | 690 |
| 659 Clear(); | 691 Clear(); |
| 660 // Don't apply GPU blacklist for a non-registered OS. | 692 // Don't apply GPU blacklist for a non-registered OS. |
| 661 OsType os_filter = GetOsType(); | 693 OsType my_os = GetOsType(); |
| 662 if (os_filter != kOsUnknown) { | 694 if (my_os != kOsUnknown) { |
| 663 for (size_t i = 0; i < entries.size(); ++i) { | 695 for (size_t i = 0; i < entries.size(); ++i) { |
| 664 OsType entry_os = entries[i]->GetOsType(); | 696 OsType entry_os = entries[i]->GetOsType(); |
| 665 if (!current_os_only || | 697 if (os_filter == GpuBlacklist::kAllOs || |
| 666 entry_os == kOsAny || entry_os == os_filter) | 698 entry_os == kOsAny || entry_os == my_os) |
| 667 blacklist_.push_back(entries[i]); | 699 blacklist_.push_back(entries[i]); |
| 668 else | 700 else |
| 669 delete entries[i]; | 701 delete entries[i]; |
| 670 } | 702 } |
| 703 } else { | |
| 704 for (size_t i = 0; i < entries.size(); ++i) | |
|
vangelis
2011/08/19 22:50:07
You could avoid adding another deletion loop here
Zhenyao Mo
2011/08/23 22:16:44
Turns out we don't need to deal with kOsUnknown at
| |
| 705 delete entries[i]; | |
| 671 } | 706 } |
| 672 max_entry_id_ = max_entry_id; | 707 max_entry_id_ = max_entry_id; |
| 673 return true; | 708 return true; |
| 674 } | 709 } |
| 675 | 710 |
| 676 GpuFeatureFlags GpuBlacklist::DetermineGpuFeatureFlags( | 711 GpuFeatureFlags GpuBlacklist::DetermineGpuFeatureFlags( |
| 677 GpuBlacklist::OsType os, | 712 GpuBlacklist::OsType os, |
| 678 Version* os_version, | 713 Version* os_version, |
| 679 const GPUInfo& gpu_info) { | 714 const GPUInfo& gpu_info) { |
| 680 active_entries_.clear(); | 715 active_entries_.clear(); |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 882 entry->webkit_bugs()[j])); | 917 entry->webkit_bugs()[j])); |
| 883 problem->Set("webkitBugs", webkit_bugs); | 918 problem->Set("webkitBugs", webkit_bugs); |
| 884 | 919 |
| 885 problem_list->Append(problem); | 920 problem_list->Append(problem); |
| 886 } | 921 } |
| 887 status->Set("problems", problem_list); | 922 status->Set("problems", problem_list); |
| 888 } | 923 } |
| 889 return status; | 924 return status; |
| 890 } | 925 } |
| 891 | 926 |
| 927 size_t GpuBlacklist::num_entries() const { | |
| 928 return blacklist_.size(); | |
| 929 } | |
| 930 | |
| 892 uint32 GpuBlacklist::max_entry_id() const { | 931 uint32 GpuBlacklist::max_entry_id() const { |
| 893 return max_entry_id_; | 932 return max_entry_id_; |
| 894 } | 933 } |
| 895 | 934 |
| 896 bool GpuBlacklist::GetVersion(uint16* major, uint16* minor) const { | 935 bool GpuBlacklist::GetVersion(uint16* major, uint16* minor) const { |
| 897 DCHECK(major && minor); | 936 DCHECK(major && minor); |
| 898 *major = 0; | 937 *major = 0; |
| 899 *minor = 0; | 938 *minor = 0; |
| 900 if (version_.get() == NULL) | 939 if (version_.get() == NULL) |
| 901 return false; | 940 return false; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 963 browser_version_info.reset( | 1002 browser_version_info.reset( |
| 964 new VersionInfo(version_op, version_string, version_string2)); | 1003 new VersionInfo(version_op, version_string, version_string2)); |
| 965 if (!browser_version_info->IsValid()) | 1004 if (!browser_version_info->IsValid()) |
| 966 return kMalformed; | 1005 return kMalformed; |
| 967 if (browser_version_info->Contains(*browser_version_)) | 1006 if (browser_version_info->Contains(*browser_version_)) |
| 968 return kSupported; | 1007 return kSupported; |
| 969 return kUnsupported; | 1008 return kUnsupported; |
| 970 } | 1009 } |
| 971 return kSupported; | 1010 return kSupported; |
| 972 } | 1011 } |
| OLD | NEW |