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 |