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 ScopedGpuBlacklistEntry 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; |
219 if (!value->GetInteger("id", reinterpret_cast<int*>(&id)) || | 220 if (!value->GetInteger("id", reinterpret_cast<int*>(&id)) || |
220 !entry->SetId(id)) { | 221 !entry->SetId(id)) { |
221 LOG(WARNING) << "Malformed id entry " << entry->id(); | 222 LOG(WARNING) << "Malformed id entry " << entry->id(); |
222 return NULL; | 223 return NULL; |
223 } | 224 } |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
386 | 387 |
387 if (top_level) { | 388 if (top_level) { |
388 ListValue* exception_list_value = NULL; | 389 ListValue* exception_list_value = NULL; |
389 if (value->GetList("exceptions", &exception_list_value)) { | 390 if (value->GetList("exceptions", &exception_list_value)) { |
390 for (size_t i = 0; i < exception_list_value->GetSize(); ++i) { | 391 for (size_t i = 0; i < exception_list_value->GetSize(); ++i) { |
391 DictionaryValue* exception_value = NULL; | 392 DictionaryValue* exception_value = NULL; |
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 ScopedGpuBlacklistEntry exception( |
397 exception_value, false); | 398 GetGpuBlacklistEntryFromValue(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_fields_) { |
404 LOG(WARNING) << "Exception with unknown fields " << entry->id(); | |
405 entry->contains_exceptions_with_unknown_fields_ = true; | |
406 } else { | |
407 entry->AddException(exception); | |
408 } | |
403 } | 409 } |
404 dictionary_entry_count++; | 410 dictionary_entry_count++; |
405 } | 411 } |
406 | 412 |
407 DictionaryValue* browser_version_value = NULL; | 413 DictionaryValue* browser_version_value = NULL; |
408 // browser_version is processed in LoadGpuBlacklist(). | 414 // browser_version is processed in LoadGpuBlacklist(). |
409 if (value->GetDictionary("browser_version", &browser_version_value)) | 415 if (value->GetDictionary("browser_version", &browser_version_value)) |
410 dictionary_entry_count++; | 416 dictionary_entry_count++; |
411 } | 417 } |
412 | 418 |
413 if (value->size() != dictionary_entry_count) { | 419 if (value->size() != dictionary_entry_count) { |
414 LOG(WARNING) << "Malformed entry " << entry->id(); | 420 LOG(WARNING) << "Entry with unknown fields " << entry->id(); |
415 return NULL; | 421 entry->contains_unknown_fields_ = true; |
416 } | 422 } |
417 return entry.release(); | 423 return entry.release(); |
418 } | 424 } |
419 | 425 |
420 GpuBlacklist::GpuBlacklistEntry::~GpuBlacklistEntry() { | |
421 for (size_t i = 0; i < exceptions_.size(); ++i) | |
422 delete exceptions_[i]; | |
423 } | |
424 | |
425 GpuBlacklist::GpuBlacklistEntry::GpuBlacklistEntry() | 426 GpuBlacklist::GpuBlacklistEntry::GpuBlacklistEntry() |
426 : id_(0), | 427 : id_(0), |
427 vendor_id_(0) { | 428 vendor_id_(0), |
429 contains_unknown_fields_(false), | |
430 contains_exceptions_with_unknown_fields_(false) { | |
428 } | 431 } |
429 | 432 |
430 bool GpuBlacklist::GpuBlacklistEntry::SetId(uint32 id) { | 433 bool GpuBlacklist::GpuBlacklistEntry::SetId(uint32 id) { |
431 if (id != 0) { | 434 if (id != 0) { |
432 id_ = id; | 435 id_ = id; |
433 return true; | 436 return true; |
434 } | 437 } |
435 return false; | 438 return false; |
436 } | 439 } |
437 | 440 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
507 GpuFeatureFlags::StringToGpuFeatureType(blacklisted_features[i]); | 510 GpuFeatureFlags::StringToGpuFeatureType(blacklisted_features[i]); |
508 switch (type) { | 511 switch (type) { |
509 case GpuFeatureFlags::kGpuFeatureAccelerated2dCanvas: | 512 case GpuFeatureFlags::kGpuFeatureAccelerated2dCanvas: |
510 case GpuFeatureFlags::kGpuFeatureAcceleratedCompositing: | 513 case GpuFeatureFlags::kGpuFeatureAcceleratedCompositing: |
511 case GpuFeatureFlags::kGpuFeatureWebgl: | 514 case GpuFeatureFlags::kGpuFeatureWebgl: |
512 case GpuFeatureFlags::kGpuFeatureMultisampling: | 515 case GpuFeatureFlags::kGpuFeatureMultisampling: |
513 case GpuFeatureFlags::kGpuFeatureAll: | 516 case GpuFeatureFlags::kGpuFeatureAll: |
514 flags |= type; | 517 flags |= type; |
515 break; | 518 break; |
516 case GpuFeatureFlags::kGpuFeatureUnknown: | 519 case GpuFeatureFlags::kGpuFeatureUnknown: |
517 return false; | 520 contains_unknown_fields_ = true; |
521 break; | |
518 } | 522 } |
519 } | 523 } |
520 feature_flags_.reset(new GpuFeatureFlags()); | 524 feature_flags_.reset(new GpuFeatureFlags()); |
521 feature_flags_->set_flags(flags); | 525 feature_flags_->set_flags(flags); |
522 return true; | 526 return true; |
523 } | 527 } |
524 | 528 |
525 void GpuBlacklist::GpuBlacklistEntry::AddException( | 529 void GpuBlacklist::GpuBlacklistEntry::AddException( |
526 GpuBlacklistEntry* exception) { | 530 GpuBlacklistEntry* exception) { |
527 exceptions_.push_back(exception); | 531 exceptions_.push_back(exception); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
579 | 583 |
580 uint32 GpuBlacklist::GpuBlacklistEntry::id() const { | 584 uint32 GpuBlacklist::GpuBlacklistEntry::id() const { |
581 return id_; | 585 return id_; |
582 } | 586 } |
583 | 587 |
584 GpuFeatureFlags GpuBlacklist::GpuBlacklistEntry::GetGpuFeatureFlags() const { | 588 GpuFeatureFlags GpuBlacklist::GpuBlacklistEntry::GetGpuFeatureFlags() const { |
585 return *feature_flags_; | 589 return *feature_flags_; |
586 } | 590 } |
587 | 591 |
588 GpuBlacklist::GpuBlacklist(const std::string& browser_version_string) | 592 GpuBlacklist::GpuBlacklist(const std::string& browser_version_string) |
589 : max_entry_id_(0) { | 593 : max_entry_id_(0), |
594 contains_unknown_fields_(false) { | |
590 browser_version_.reset(Version::GetVersionFromString(browser_version_string)); | 595 browser_version_.reset(Version::GetVersionFromString(browser_version_string)); |
591 DCHECK(browser_version_.get() != NULL); | 596 DCHECK(browser_version_.get() != NULL); |
592 } | 597 } |
593 | 598 |
594 GpuBlacklist::~GpuBlacklist() { | 599 GpuBlacklist::~GpuBlacklist() { |
595 Clear(); | 600 Clear(); |
596 } | 601 } |
597 | 602 |
598 bool GpuBlacklist::LoadGpuBlacklist(const std::string& json_context, | 603 bool GpuBlacklist::LoadGpuBlacklist( |
599 bool current_os_only) { | 604 const std::string& json_context, GpuBlacklist::OsFilter os_filter) { |
600 scoped_ptr<Value> root; | 605 scoped_ptr<Value> root; |
601 root.reset(base::JSONReader::Read(json_context, false)); | 606 root.reset(base::JSONReader::Read(json_context, false)); |
602 if (root.get() == NULL || !root->IsType(Value::TYPE_DICTIONARY)) | 607 if (root.get() == NULL || !root->IsType(Value::TYPE_DICTIONARY)) |
603 return false; | 608 return false; |
604 | 609 |
605 DictionaryValue* root_dictionary = static_cast<DictionaryValue*>(root.get()); | 610 DictionaryValue* root_dictionary = static_cast<DictionaryValue*>(root.get()); |
606 DCHECK(root_dictionary); | 611 DCHECK(root_dictionary); |
607 return LoadGpuBlacklist(*root_dictionary, current_os_only); | 612 return LoadGpuBlacklist(*root_dictionary, os_filter); |
608 } | 613 } |
609 | 614 |
610 bool GpuBlacklist::LoadGpuBlacklist(const DictionaryValue& parsed_json, | 615 bool GpuBlacklist::LoadGpuBlacklist( |
611 bool current_os_only) { | 616 const DictionaryValue& parsed_json, GpuBlacklist::OsFilter os_filter) { |
612 std::vector<GpuBlacklistEntry*> entries; | 617 std::vector<ScopedGpuBlacklistEntry> entries; |
613 | 618 |
614 std::string version_string; | 619 std::string version_string; |
615 parsed_json.GetString("version", &version_string); | 620 parsed_json.GetString("version", &version_string); |
616 version_.reset(Version::GetVersionFromString(version_string)); | 621 version_.reset(Version::GetVersionFromString(version_string)); |
617 if (version_.get() == NULL) | 622 if (version_.get() == NULL) |
618 return false; | 623 return false; |
619 | 624 |
620 ListValue* list = NULL; | 625 ListValue* list = NULL; |
621 if (!parsed_json.GetList("entries", &list)) | 626 if (!parsed_json.GetList("entries", &list)) |
622 return false; | 627 return false; |
623 | 628 |
624 uint32 max_entry_id = 0; | 629 uint32 max_entry_id = 0; |
625 size_t entry_count_expectation = list->GetSize(); | 630 bool error = false; |
vangelis
2011/08/24 19:00:17
Now that the code is so much simpler, you could el
Zhenyao Mo
2011/08/24 22:29:57
Done.
| |
631 bool contains_unknown_fields = false; | |
626 for (size_t i = 0; i < list->GetSize(); ++i) { | 632 for (size_t i = 0; i < list->GetSize(); ++i) { |
627 DictionaryValue* list_item = NULL; | 633 DictionaryValue* list_item = NULL; |
628 bool valid = list->GetDictionary(i, &list_item); | 634 bool valid = list->GetDictionary(i, &list_item); |
629 if (!valid) | 635 if (!valid || list_item == NULL) { |
636 error = true; | |
630 break; | 637 break; |
631 if (list_item == NULL) | 638 } |
632 break; | |
633 // Check browser version compatibility: if the entry is not for the | 639 // Check browser version compatibility: if the entry is not for the |
634 // current browser version, don't process it. | 640 // current browser version, don't process it. |
635 BrowserVersionSupport browser_version_support = | 641 BrowserVersionSupport browser_version_support = |
636 IsEntrySupportedByCurrentBrowserVersion(list_item); | 642 IsEntrySupportedByCurrentBrowserVersion(list_item); |
637 if (browser_version_support == kMalformed) | 643 if (browser_version_support == kMalformed) { |
644 error = true; | |
638 break; | 645 break; |
639 if (browser_version_support == kUnsupported) { | 646 } |
640 entry_count_expectation--; | 647 if (browser_version_support == kUnsupported) |
648 continue; | |
649 DCHECK(browser_version_support == kSupported); | |
650 ScopedGpuBlacklistEntry entry( | |
651 GpuBlacklistEntry::GetGpuBlacklistEntryFromValue(list_item, true)); | |
652 if (entry == NULL) { | |
653 error = true; | |
654 break; | |
655 } | |
656 if (entry->id() > max_entry_id) | |
657 max_entry_id = entry->id(); | |
658 if (entry->contains_unknown_fields()) { | |
659 contains_unknown_fields = true; | |
vangelis
2011/08/24 19:00:17
I forget what we decided but I thought that unknow
Zhenyao Mo
2011/08/24 22:29:57
I think we decided the following:
1) ignore unknow
| |
641 continue; | 660 continue; |
642 } | 661 } |
643 DCHECK(browser_version_support == kSupported); | 662 if (entry->contains_exceptions_with_unknown_fields()) |
644 GpuBlacklistEntry* entry = | 663 contains_unknown_fields = true; |
645 GpuBlacklistEntry::GetGpuBlacklistEntryFromValue(list_item, true); | |
646 if (entry == NULL) | |
647 break; | |
648 if (entry->id() > max_entry_id) | |
649 max_entry_id = entry->id(); | |
650 entries.push_back(entry); | 664 entries.push_back(entry); |
651 } | 665 } |
652 | 666 |
653 if (entries.size() != entry_count_expectation) { | 667 if (error) |
654 for (size_t i = 0; i < entries.size(); ++i) | |
655 delete entries[i]; | |
656 return false; | 668 return false; |
657 } | |
658 | 669 |
659 Clear(); | 670 Clear(); |
660 // Don't apply GPU blacklist for a non-registered OS. | 671 OsType my_os = GetOsType(); |
661 OsType os_filter = GetOsType(); | 672 for (size_t i = 0; i < entries.size(); ++i) { |
662 if (os_filter != kOsUnknown) { | 673 OsType entry_os = entries[i]->GetOsType(); |
663 for (size_t i = 0; i < entries.size(); ++i) { | 674 if (os_filter == GpuBlacklist::kAllOs || |
664 OsType entry_os = entries[i]->GetOsType(); | 675 entry_os == kOsAny || entry_os == my_os) |
665 if (!current_os_only || | 676 blacklist_.push_back(entries[i]); |
666 entry_os == kOsAny || entry_os == os_filter) | |
667 blacklist_.push_back(entries[i]); | |
668 else | |
669 delete entries[i]; | |
670 } | |
671 } | 677 } |
672 max_entry_id_ = max_entry_id; | 678 max_entry_id_ = max_entry_id; |
679 contains_unknown_fields_ = contains_unknown_fields; | |
673 return true; | 680 return true; |
674 } | 681 } |
675 | 682 |
676 GpuFeatureFlags GpuBlacklist::DetermineGpuFeatureFlags( | 683 GpuFeatureFlags GpuBlacklist::DetermineGpuFeatureFlags( |
677 GpuBlacklist::OsType os, | 684 GpuBlacklist::OsType os, |
678 Version* os_version, | 685 Version* os_version, |
679 const GPUInfo& gpu_info) { | 686 const GPUInfo& gpu_info) { |
680 active_entries_.clear(); | 687 active_entries_.clear(); |
681 GpuFeatureFlags flags; | 688 GpuFeatureFlags flags; |
682 | 689 |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
858 if (disable_multisampling) { | 865 if (disable_multisampling) { |
859 DictionaryValue* problem = new DictionaryValue(); | 866 DictionaryValue* problem = new DictionaryValue(); |
860 problem->SetString("description", | 867 problem->SetString("description", |
861 "Multisampling has been disabled, either via about:flags " | 868 "Multisampling has been disabled, either via about:flags " |
862 "or command line"); | 869 "or command line"); |
863 problem->Set("crBugs", new ListValue()); | 870 problem->Set("crBugs", new ListValue()); |
864 problem->Set("webkitBugs", new ListValue()); | 871 problem->Set("webkitBugs", new ListValue()); |
865 problem_list->Append(problem); | 872 problem_list->Append(problem); |
866 } | 873 } |
867 for (size_t i = 0; i < active_entries_.size(); ++i) { | 874 for (size_t i = 0; i < active_entries_.size(); ++i) { |
868 GpuBlacklistEntry* entry = active_entries_[i]; | 875 ScopedGpuBlacklistEntry entry = active_entries_[i]; |
869 DictionaryValue* problem = new DictionaryValue(); | 876 DictionaryValue* problem = new DictionaryValue(); |
870 | 877 |
871 problem->SetString("description", entry->description()); | 878 problem->SetString("description", entry->description()); |
872 | 879 |
873 ListValue* cr_bugs = new ListValue(); | 880 ListValue* cr_bugs = new ListValue(); |
874 for (size_t j = 0; j < entry->cr_bugs().size(); ++j) | 881 for (size_t j = 0; j < entry->cr_bugs().size(); ++j) |
875 cr_bugs->Append(Value::CreateIntegerValue( | 882 cr_bugs->Append(Value::CreateIntegerValue( |
876 entry->cr_bugs()[j])); | 883 entry->cr_bugs()[j])); |
877 problem->Set("crBugs", cr_bugs); | 884 problem->Set("crBugs", cr_bugs); |
878 | 885 |
879 ListValue* webkit_bugs = new ListValue(); | 886 ListValue* webkit_bugs = new ListValue(); |
880 for (size_t j = 0; j < entry->webkit_bugs().size(); ++j) | 887 for (size_t j = 0; j < entry->webkit_bugs().size(); ++j) |
881 webkit_bugs->Append(Value::CreateIntegerValue( | 888 webkit_bugs->Append(Value::CreateIntegerValue( |
882 entry->webkit_bugs()[j])); | 889 entry->webkit_bugs()[j])); |
883 problem->Set("webkitBugs", webkit_bugs); | 890 problem->Set("webkitBugs", webkit_bugs); |
884 | 891 |
885 problem_list->Append(problem); | 892 problem_list->Append(problem); |
886 } | 893 } |
887 status->Set("problems", problem_list); | 894 status->Set("problems", problem_list); |
888 } | 895 } |
889 return status; | 896 return status; |
890 } | 897 } |
891 | 898 |
899 size_t GpuBlacklist::num_entries() const { | |
900 return blacklist_.size(); | |
901 } | |
902 | |
892 uint32 GpuBlacklist::max_entry_id() const { | 903 uint32 GpuBlacklist::max_entry_id() const { |
893 return max_entry_id_; | 904 return max_entry_id_; |
894 } | 905 } |
895 | 906 |
896 bool GpuBlacklist::GetVersion(uint16* major, uint16* minor) const { | 907 bool GpuBlacklist::GetVersion(uint16* major, uint16* minor) const { |
897 DCHECK(major && minor); | 908 DCHECK(major && minor); |
898 *major = 0; | 909 *major = 0; |
899 *minor = 0; | 910 *minor = 0; |
900 if (version_.get() == NULL) | 911 if (version_.get() == NULL) |
901 return false; | 912 return false; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
934 #elif defined(OS_LINUX) | 945 #elif defined(OS_LINUX) |
935 return kOsLinux; | 946 return kOsLinux; |
936 #elif defined(OS_MACOSX) | 947 #elif defined(OS_MACOSX) |
937 return kOsMacosx; | 948 return kOsMacosx; |
938 #else | 949 #else |
939 return kOsUnknown; | 950 return kOsUnknown; |
940 #endif | 951 #endif |
941 } | 952 } |
942 | 953 |
943 void GpuBlacklist::Clear() { | 954 void GpuBlacklist::Clear() { |
944 for (size_t i = 0; i < blacklist_.size(); ++i) | |
945 delete blacklist_[i]; | |
946 blacklist_.clear(); | 955 blacklist_.clear(); |
947 active_entries_.clear(); | 956 active_entries_.clear(); |
957 max_entry_id_ = 0; | |
958 contains_unknown_fields_ = false; | |
948 } | 959 } |
949 | 960 |
950 GpuBlacklist::BrowserVersionSupport | 961 GpuBlacklist::BrowserVersionSupport |
951 GpuBlacklist::IsEntrySupportedByCurrentBrowserVersion( | 962 GpuBlacklist::IsEntrySupportedByCurrentBrowserVersion( |
952 DictionaryValue* value) { | 963 DictionaryValue* value) { |
953 DCHECK(value); | 964 DCHECK(value); |
954 DictionaryValue* browser_version_value = NULL; | 965 DictionaryValue* browser_version_value = NULL; |
955 if (value->GetDictionary("browser_version", &browser_version_value)) { | 966 if (value->GetDictionary("browser_version", &browser_version_value)) { |
956 std::string version_op = "any"; | 967 std::string version_op = "any"; |
957 std::string version_string; | 968 std::string version_string; |
958 std::string version_string2; | 969 std::string version_string2; |
959 browser_version_value->GetString("op", &version_op); | 970 browser_version_value->GetString("op", &version_op); |
960 browser_version_value->GetString("number", &version_string); | 971 browser_version_value->GetString("number", &version_string); |
961 browser_version_value->GetString("number2", &version_string2); | 972 browser_version_value->GetString("number2", &version_string2); |
962 scoped_ptr<VersionInfo> browser_version_info; | 973 scoped_ptr<VersionInfo> browser_version_info; |
963 browser_version_info.reset( | 974 browser_version_info.reset( |
964 new VersionInfo(version_op, version_string, version_string2)); | 975 new VersionInfo(version_op, version_string, version_string2)); |
965 if (!browser_version_info->IsValid()) | 976 if (!browser_version_info->IsValid()) |
966 return kMalformed; | 977 return kMalformed; |
967 if (browser_version_info->Contains(*browser_version_)) | 978 if (browser_version_info->Contains(*browser_version_)) |
968 return kSupported; | 979 return kSupported; |
969 return kUnsupported; | 980 return kUnsupported; |
970 } | 981 } |
971 return kSupported; | 982 return kSupported; |
972 } | 983 } |
OLD | NEW |