Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(233)

Side by Side Diff: content/browser/gpu/gpu_blacklist.cc

Issue 7633038: Relax software rendering list parsing. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698