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_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(); |
Ken Russell (switch to Gerrit)
2011/08/25 18:03:31
This is the leak. The ScopedGpuBlacklistEntry cons
| |
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_unknown_features_(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_features_ = 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 contains_unknown_fields = false; |
626 for (size_t i = 0; i < list->GetSize(); ++i) { | 631 for (size_t i = 0; i < list->GetSize(); ++i) { |
627 DictionaryValue* list_item = NULL; | 632 DictionaryValue* list_item = NULL; |
628 bool valid = list->GetDictionary(i, &list_item); | 633 bool valid = list->GetDictionary(i, &list_item); |
629 if (!valid) | 634 if (!valid || list_item == NULL) |
630 break; | 635 return false; |
631 if (list_item == NULL) | |
632 break; | |
633 // Check browser version compatibility: if the entry is not for the | 636 // Check browser version compatibility: if the entry is not for the |
634 // current browser version, don't process it. | 637 // current browser version, don't process it. |
635 BrowserVersionSupport browser_version_support = | 638 BrowserVersionSupport browser_version_support = |
636 IsEntrySupportedByCurrentBrowserVersion(list_item); | 639 IsEntrySupportedByCurrentBrowserVersion(list_item); |
637 if (browser_version_support == kMalformed) | 640 if (browser_version_support == kMalformed) |
638 break; | 641 return false; |
639 if (browser_version_support == kUnsupported) { | 642 if (browser_version_support == kUnsupported) |
640 entry_count_expectation--; | 643 continue; |
644 DCHECK(browser_version_support == kSupported); | |
645 ScopedGpuBlacklistEntry entry( | |
646 GpuBlacklistEntry::GetGpuBlacklistEntryFromValue(list_item, true)); | |
647 if (entry == NULL) | |
648 return false; | |
649 if (entry->id() > max_entry_id) | |
650 max_entry_id = entry->id(); | |
651 // If an unknown field is encountered, skip the entry; if an unknown | |
652 // feature is encountered, ignore the feature, but keep the entry. | |
653 if (entry->contains_unknown_fields()) { | |
654 contains_unknown_fields = true; | |
641 continue; | 655 continue; |
642 } | 656 } |
643 DCHECK(browser_version_support == kSupported); | 657 if (entry->contains_unknown_features()) |
644 GpuBlacklistEntry* entry = | 658 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); | 659 entries.push_back(entry); |
651 } | 660 } |
652 | 661 |
653 if (entries.size() != entry_count_expectation) { | |
654 for (size_t i = 0; i < entries.size(); ++i) | |
655 delete entries[i]; | |
656 return false; | |
657 } | |
658 | |
659 Clear(); | 662 Clear(); |
660 // Don't apply GPU blacklist for a non-registered OS. | 663 OsType my_os = GetOsType(); |
661 OsType os_filter = GetOsType(); | 664 for (size_t i = 0; i < entries.size(); ++i) { |
662 if (os_filter != kOsUnknown) { | 665 OsType entry_os = entries[i]->GetOsType(); |
663 for (size_t i = 0; i < entries.size(); ++i) { | 666 if (os_filter == GpuBlacklist::kAllOs || |
664 OsType entry_os = entries[i]->GetOsType(); | 667 entry_os == kOsAny || entry_os == my_os) |
665 if (!current_os_only || | 668 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 } | 669 } |
672 max_entry_id_ = max_entry_id; | 670 max_entry_id_ = max_entry_id; |
671 contains_unknown_fields_ = contains_unknown_fields; | |
673 return true; | 672 return true; |
674 } | 673 } |
675 | 674 |
676 GpuFeatureFlags GpuBlacklist::DetermineGpuFeatureFlags( | 675 GpuFeatureFlags GpuBlacklist::DetermineGpuFeatureFlags( |
677 GpuBlacklist::OsType os, | 676 GpuBlacklist::OsType os, |
678 Version* os_version, | 677 Version* os_version, |
679 const GPUInfo& gpu_info) { | 678 const GPUInfo& gpu_info) { |
680 active_entries_.clear(); | 679 active_entries_.clear(); |
681 GpuFeatureFlags flags; | 680 GpuFeatureFlags flags; |
682 | 681 |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
858 if (disable_multisampling) { | 857 if (disable_multisampling) { |
859 DictionaryValue* problem = new DictionaryValue(); | 858 DictionaryValue* problem = new DictionaryValue(); |
860 problem->SetString("description", | 859 problem->SetString("description", |
861 "Multisampling has been disabled, either via about:flags " | 860 "Multisampling has been disabled, either via about:flags " |
862 "or command line"); | 861 "or command line"); |
863 problem->Set("crBugs", new ListValue()); | 862 problem->Set("crBugs", new ListValue()); |
864 problem->Set("webkitBugs", new ListValue()); | 863 problem->Set("webkitBugs", new ListValue()); |
865 problem_list->Append(problem); | 864 problem_list->Append(problem); |
866 } | 865 } |
867 for (size_t i = 0; i < active_entries_.size(); ++i) { | 866 for (size_t i = 0; i < active_entries_.size(); ++i) { |
868 GpuBlacklistEntry* entry = active_entries_[i]; | 867 ScopedGpuBlacklistEntry entry = active_entries_[i]; |
869 DictionaryValue* problem = new DictionaryValue(); | 868 DictionaryValue* problem = new DictionaryValue(); |
870 | 869 |
871 problem->SetString("description", entry->description()); | 870 problem->SetString("description", entry->description()); |
872 | 871 |
873 ListValue* cr_bugs = new ListValue(); | 872 ListValue* cr_bugs = new ListValue(); |
874 for (size_t j = 0; j < entry->cr_bugs().size(); ++j) | 873 for (size_t j = 0; j < entry->cr_bugs().size(); ++j) |
875 cr_bugs->Append(Value::CreateIntegerValue( | 874 cr_bugs->Append(Value::CreateIntegerValue( |
876 entry->cr_bugs()[j])); | 875 entry->cr_bugs()[j])); |
877 problem->Set("crBugs", cr_bugs); | 876 problem->Set("crBugs", cr_bugs); |
878 | 877 |
879 ListValue* webkit_bugs = new ListValue(); | 878 ListValue* webkit_bugs = new ListValue(); |
880 for (size_t j = 0; j < entry->webkit_bugs().size(); ++j) | 879 for (size_t j = 0; j < entry->webkit_bugs().size(); ++j) |
881 webkit_bugs->Append(Value::CreateIntegerValue( | 880 webkit_bugs->Append(Value::CreateIntegerValue( |
882 entry->webkit_bugs()[j])); | 881 entry->webkit_bugs()[j])); |
883 problem->Set("webkitBugs", webkit_bugs); | 882 problem->Set("webkitBugs", webkit_bugs); |
884 | 883 |
885 problem_list->Append(problem); | 884 problem_list->Append(problem); |
886 } | 885 } |
887 status->Set("problems", problem_list); | 886 status->Set("problems", problem_list); |
888 } | 887 } |
889 return status; | 888 return status; |
890 } | 889 } |
891 | 890 |
891 size_t GpuBlacklist::num_entries() const { | |
892 return blacklist_.size(); | |
893 } | |
894 | |
892 uint32 GpuBlacklist::max_entry_id() const { | 895 uint32 GpuBlacklist::max_entry_id() const { |
893 return max_entry_id_; | 896 return max_entry_id_; |
894 } | 897 } |
895 | 898 |
896 bool GpuBlacklist::GetVersion(uint16* major, uint16* minor) const { | 899 bool GpuBlacklist::GetVersion(uint16* major, uint16* minor) const { |
897 DCHECK(major && minor); | 900 DCHECK(major && minor); |
898 *major = 0; | 901 *major = 0; |
899 *minor = 0; | 902 *minor = 0; |
900 if (version_.get() == NULL) | 903 if (version_.get() == NULL) |
901 return false; | 904 return false; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
934 #elif defined(OS_LINUX) | 937 #elif defined(OS_LINUX) |
935 return kOsLinux; | 938 return kOsLinux; |
936 #elif defined(OS_MACOSX) | 939 #elif defined(OS_MACOSX) |
937 return kOsMacosx; | 940 return kOsMacosx; |
938 #else | 941 #else |
939 return kOsUnknown; | 942 return kOsUnknown; |
940 #endif | 943 #endif |
941 } | 944 } |
942 | 945 |
943 void GpuBlacklist::Clear() { | 946 void GpuBlacklist::Clear() { |
944 for (size_t i = 0; i < blacklist_.size(); ++i) | |
945 delete blacklist_[i]; | |
946 blacklist_.clear(); | 947 blacklist_.clear(); |
947 active_entries_.clear(); | 948 active_entries_.clear(); |
949 max_entry_id_ = 0; | |
950 contains_unknown_fields_ = false; | |
948 } | 951 } |
949 | 952 |
950 GpuBlacklist::BrowserVersionSupport | 953 GpuBlacklist::BrowserVersionSupport |
951 GpuBlacklist::IsEntrySupportedByCurrentBrowserVersion( | 954 GpuBlacklist::IsEntrySupportedByCurrentBrowserVersion( |
952 DictionaryValue* value) { | 955 DictionaryValue* value) { |
953 DCHECK(value); | 956 DCHECK(value); |
954 DictionaryValue* browser_version_value = NULL; | 957 DictionaryValue* browser_version_value = NULL; |
955 if (value->GetDictionary("browser_version", &browser_version_value)) { | 958 if (value->GetDictionary("browser_version", &browser_version_value)) { |
956 std::string version_op = "any"; | 959 std::string version_op = "any"; |
957 std::string version_string; | 960 std::string version_string; |
958 std::string version_string2; | 961 std::string version_string2; |
959 browser_version_value->GetString("op", &version_op); | 962 browser_version_value->GetString("op", &version_op); |
960 browser_version_value->GetString("number", &version_string); | 963 browser_version_value->GetString("number", &version_string); |
961 browser_version_value->GetString("number2", &version_string2); | 964 browser_version_value->GetString("number2", &version_string2); |
962 scoped_ptr<VersionInfo> browser_version_info; | 965 scoped_ptr<VersionInfo> browser_version_info; |
963 browser_version_info.reset( | 966 browser_version_info.reset( |
964 new VersionInfo(version_op, version_string, version_string2)); | 967 new VersionInfo(version_op, version_string, version_string2)); |
965 if (!browser_version_info->IsValid()) | 968 if (!browser_version_info->IsValid()) |
966 return kMalformed; | 969 return kMalformed; |
967 if (browser_version_info->Contains(*browser_version_)) | 970 if (browser_version_info->Contains(*browser_version_)) |
968 return kSupported; | 971 return kSupported; |
969 return kUnsupported; | 972 return kUnsupported; |
970 } | 973 } |
971 return kSupported; | 974 return kSupported; |
972 } | 975 } |
OLD | NEW |