1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef GPU_CONFIG_GPU_CONTROL_LIST_H_ 6 #define GPU_CONFIG_GPU_CONTROL_LIST_H_ 7 8 #include <set> 9 #include <string> 10 #include <vector> 11 12 #include "base/basictypes.h" 13 #include "base/containers/hash_tables.h" 14 #include "base/gtest_prod_util.h" 15 #include "base/memory/ref_counted.h" 16 #include "base/memory/scoped_ptr.h" 17 #include "base/values.h" 18 #include "build/build_config.h" 19 #include "gpu/gpu_export.h" 20 21 namespace gpu { 22 struct GPUInfo; 23 24 class GPU_EXPORT GpuControlList { 25 public: 26 enum OsType { 27 kOsLinux, 28 kOsMacosx, 29 kOsWin, 30 kOsChromeOS, 31 kOsAndroid, 32 kOsAny, 33 kOsUnknown 34 }; 35 36 enum OsFilter { 37 // In loading, ignore all entries that belong to other OS. 38 kCurrentOsOnly, 39 // In loading, keep all entries. This is for testing only. 40 kAllOs 41 }; 42 43 GpuControlList(); 44 virtual ~GpuControlList(); 45 46 // Loads control list information from a json file. 47 // If failed, the current GpuControlList is un-touched. 48 bool LoadList(const std::string& json_context, OsFilter os_filter); 49 bool LoadList(const std::string& browser_version_string, 50 const std::string& json_context, OsFilter os_filter); 51 52 // Collects system information and combines them with gpu_info and control 53 // list information to decide which entries are applied to the current 54 // system and returns the union of features specified in each entry. 55 // If os is kOsAny, use the current OS; if os_version is empty, use the 56 // current OS version. 57 std::set<int> MakeDecision( 58 OsType os, std::string os_version, const GPUInfo& gpu_info); 59 60 // Collects the active entries from the last MakeDecision() call. 61 // If disabled set to true, return entries that are disabled; otherwise, 62 // return enabled entries. 63 void GetDecisionEntries(std::vector<uint32>* entry_ids, 64 bool disabled) const; 65 66 // Returns the description and bugs from active entries from the last 67 // MakeDecision() call. 68 // 69 // Each problems has: 70 // { 71 // "description": "Your GPU is too old", 72 // "crBugs": [1234], 73 // "webkitBugs": [] 74 // } 75 void GetReasons(base::ListValue* problem_list) const; 76 77 // Return the largest entry id. This is used for histogramming. 78 uint32 max_entry_id() const; 79 80 // Returns the version of the control list. 81 std::string version() const; 82 83 // Check if we need more gpu info to make the decisions. 84 // This is computed from the last MakeDecision() call. 85 // If yes, we should create a gl context and do a full gpu info collection. 86 bool needs_more_info() const { return needs_more_info_; } 87 88 // Check if any entries contain unknown fields. This is only for tests. 89 bool contains_unknown_fields() const { return contains_unknown_fields_; } 90 91 // Returns the number of entries. This is only for tests. 92 size_t num_entries() const; 93 94 // Register a feature to FeatureMap - used to construct a GpuControlList. 95 void AddSupportedFeature(const std::string& feature_name, int feature_id); 96 // Register whether "all" is recognized as all features. 97 void set_supports_feature_type_all(bool supported); 98 99 private: 100 friend class GpuControlListEntryTest; 101 friend class MachineModelInfoTest; 102 friend class NumberInfoTest; 103 friend class OsInfoTest; 104 friend class StringInfoTest; 105 friend class VersionInfoTest; 106 107 enum BrowserVersionSupport { 108 kSupported, 109 kUnsupported, 110 kMalformed 111 }; 112 113 enum NumericOp { 114 kBetween, // <= * <= 115 kEQ, // = 116 kLT, // < 117 kLE, // <= 118 kGT, // > 119 kGE, // >= 120 kAny, 121 kUnknown // Indicates the data is invalid. 122 }; 123 124 class GPU_EXPORT VersionInfo { 125 public: 126 // If version_style is empty, it defaults to kNumerical. 127 VersionInfo(const std::string& version_op, 128 const std::string& version_style, 129 const std::string& version_string, 130 const std::string& version_string2); 131 ~VersionInfo(); 132 133 // Determines if a given version is included in the VersionInfo range. 134 // "splitter" divides version string into segments. 135 bool Contains(const std::string& version, char splitter) const; 136 // Same as above, using '.' as splitter. 137 bool Contains(const std::string& version) const; 138 139 // Determine if the version_style is lexical. 140 bool IsLexical() const; 141 142 // Determines if the VersionInfo contains valid information. 143 bool IsValid() const; 144 145 private: 146 enum VersionStyle { 147 kVersionStyleNumerical, 148 kVersionStyleLexical, 149 kVersionStyleUnknown 150 }; 151 152 static VersionStyle StringToVersionStyle(const std::string& version_style); 153 154 // Compare two version strings. 155 // Return 1 if version > version_ref, 156 // 0 if version = version_ref, 157 // -1 if version < version_ref. 158 // Note that we only compare as many segments as both versions contain. 159 // For example: Compare("10.3.1", "10.3") returns 0, 160 // Compare("10.3", "10.3.1") returns 0. 161 // If "version_style" is Lexical, the first segment is compared 162 // numerically, all other segments are compared lexically. 163 // Lexical is used for AMD Linux driver versions only. 164 static int Compare(const std::vector<std::string>& version, 165 const std::vector<std::string>& version_ref, 166 VersionStyle version_style); 167 168 NumericOp op_; 169 VersionStyle version_style_; 170 std::vector<std::string> version_; 171 std::vector<std::string> version2_; 172 }; 173 174 class GPU_EXPORT OsInfo { 175 public: 176 OsInfo(const std::string& os, 177 const std::string& version_op, 178 const std::string& version_string, 179 const std::string& version_string2); 180 ~OsInfo(); 181 182 // Determines if a given os/version is included in the OsInfo set. 183 bool Contains(OsType type, const std::string& version) const; 184 185 // Determines if the VersionInfo contains valid information. 186 bool IsValid() const; 187 188 OsType type() const; 189 190 // Maps string to OsType; returns kOsUnknown if it's not a valid os. 191 static OsType StringToOsType(const std::string& os); 192 193 private: 194 OsType type_; 195 scoped_ptr<VersionInfo> version_info_; 196 }; 197 198 class GPU_EXPORT StringInfo { 199 public: 200 StringInfo(const std::string& string_op, const std::string& string_value); 201 202 // Determines if a given string is included in the StringInfo. 203 bool Contains(const std::string& value) const; 204 205 // Determines if the StringInfo contains valid information. 206 bool IsValid() const; 207 208 private: 209 enum Op { 210 kContains, 211 kBeginWith, 212 kEndWith, 213 kEQ, // = 214 kUnknown // Indicates StringInfo data is invalid. 215 }; 216 217 // Maps string to Op; returns kUnknown if it's not a valid Op. 218 static Op StringToOp(const std::string& string_op); 219 220 Op op_; 221 std::string value_; 222 }; 223 224 class GPU_EXPORT FloatInfo { 225 public: 226 FloatInfo(const std::string& float_op, 227 const std::string& float_value, 228 const std::string& float_value2); 229 230 // Determines if a given float is included in the FloatInfo. 231 bool Contains(float value) const; 232 233 // Determines if the FloatInfo contains valid information. 234 bool IsValid() const; 235 236 private: 237 NumericOp op_; 238 float value_; 239 float value2_; 240 }; 241 242 class GPU_EXPORT IntInfo { 243 public: 244 IntInfo(const std::string& int_op, 245 const std::string& int_value, 246 const std::string& int_value2); 247 248 // Determines if a given int is included in the IntInfo. 249 bool Contains(int value) const; 250 251 // Determines if the IntInfo contains valid information. 252 bool IsValid() const; 253 254 private: 255 NumericOp op_; 256 int value_; 257 int value2_; 258 }; 259 260 class GPU_EXPORT MachineModelInfo { 261 public: 262 MachineModelInfo(const std::string& name_op, 263 const std::string& name_value, 264 const std::string& version_op, 265 const std::string& version_string, 266 const std::string& version_string2); 267 ~MachineModelInfo(); 268 269 // Determines if a given name/version is included in the MachineModelInfo. 270 bool Contains(const std::string& name, const std::string& version) const; 271 272 // Determines if the MachineModelInfo contains valid information. 273 bool IsValid() const; 274 275 private: 276 scoped_ptr<StringInfo> name_info_; 277 scoped_ptr<VersionInfo> version_info_; 278 }; 279 280 class GpuControlListEntry; 281 typedef scoped_refptr<GpuControlListEntry> ScopedGpuControlListEntry; 282 283 typedef base::hash_map<std::string, int> FeatureMap; 284 285 class GPU_EXPORT GpuControlListEntry 286 : public base::RefCounted<GpuControlListEntry> { 287 public: 288 // Constructs GpuControlListEntry from DictionaryValue loaded from json. 289 // Top-level entry must have an id number. Others are exceptions. 290 static ScopedGpuControlListEntry GetEntryFromValue( 291 const base::DictionaryValue* value, bool top_level, 292 const FeatureMap& feature_map, 293 bool supports_feature_type_all); 294 295 // Determines if a given os/gc/machine_model/driver is included in the 296 // Entry set. 297 bool Contains(OsType os_type, const std::string& os_version, 298 const GPUInfo& gpu_info) const; 299 300 // Determines whether we needs more gpu info to make the blacklisting 301 // decision. It should only be checked if Contains() returns true. 302 bool NeedsMoreInfo(const GPUInfo& gpu_info) const; 303 304 // Returns the OsType. 305 OsType GetOsType() const; 306 307 // Returns the entry's unique id. 0 is reserved. 308 uint32 id() const; 309 310 // Returns whether the entry is disabled. 311 bool disabled() const; 312 313 // Returns the description of the entry 314 const std::string& description() const { return description_; } 315 316 // Returns a list of Chromium and Webkit bugs applicable to this entry 317 const std::vector<int>& cr_bugs() const { return cr_bugs_; } 318 const std::vector<int>& webkit_bugs() const { return webkit_bugs_; } 319 320 // Returns the blacklisted features in this entry. 321 const std::set<int>& features() const; 322 323 // Returns true if an unknown field is encountered. 324 bool contains_unknown_fields() const { 325 return contains_unknown_fields_; 326 } 327 // Returns true if an unknown blacklist feature is encountered. 328 bool contains_unknown_features() const { 329 return contains_unknown_features_; 330 } 331 332 private: 333 friend class base::RefCounted<GpuControlListEntry>; 334 335 enum MultiGpuStyle { 336 kMultiGpuStyleOptimus, 337 kMultiGpuStyleAMDSwitchable, 338 kMultiGpuStyleNone 339 }; 340 341 enum MultiGpuCategory { 342 kMultiGpuCategoryPrimary, 343 kMultiGpuCategorySecondary, 344 kMultiGpuCategoryAny, 345 kMultiGpuCategoryNone 346 }; 347 348 GpuControlListEntry(); 349 ~GpuControlListEntry(); 350 351 bool SetId(uint32 id); 352 353 void SetDisabled(bool disabled); 354 355 bool SetOsInfo(const std::string& os, 356 const std::string& version_op, 357 const std::string& version_string, 358 const std::string& version_string2); 359 360 bool SetVendorId(const std::string& vendor_id_string); 361 362 bool AddDeviceId(const std::string& device_id_string); 363 364 bool SetMultiGpuStyle(const std::string& multi_gpu_style_string); 365 366 bool SetMultiGpuCategory(const std::string& multi_gpu_category_string); 367 368 bool SetDriverVendorInfo(const std::string& vendor_op, 369 const std::string& vendor_value); 370 371 bool SetDriverVersionInfo(const std::string& version_op, 372 const std::string& version_style, 373 const std::string& version_string, 374 const std::string& version_string2); 375 376 bool SetDriverDateInfo(const std::string& date_op, 377 const std::string& date_string, 378 const std::string& date_string2); 379 380 bool SetGLVendorInfo(const std::string& vendor_op, 381 const std::string& vendor_value); 382 383 bool SetGLRendererInfo(const std::string& renderer_op, 384 const std::string& renderer_value); 385 386 bool SetGLExtensionsInfo(const std::string& extensions_op, 387 const std::string& extensions_value); 388 389 bool SetGLResetNotificationStrategyInfo(const std::string& op, 390 const std::string& int_string, 391 const std::string& int_string2); 392 393 bool SetCpuBrand(const std::string& cpu_op, 394 const std::string& cpu_value); 395 396 bool SetPerfGraphicsInfo(const std::string& op, 397 const std::string& float_string, 398 const std::string& float_string2); 399 400 bool SetPerfGamingInfo(const std::string& op, 401 const std::string& float_string, 402 const std::string& float_string2); 403 404 bool SetPerfOverallInfo(const std::string& op, 405 const std::string& float_string, 406 const std::string& float_string2); 407 408 bool SetMachineModelInfo(const std::string& name_op, 409 const std::string& name_value, 410 const std::string& version_op, 411 const std::string& version_string, 412 const std::string& version_string2); 413 414 bool SetGpuCountInfo(const std::string& op, 415 const std::string& int_string, 416 const std::string& int_string2); 417 418 bool SetFeatures(const std::vector<std::string>& features, 419 const FeatureMap& feature_map, 420 bool supports_feature_type_all); 421 422 void AddException(ScopedGpuControlListEntry exception); 423 424 static MultiGpuStyle StringToMultiGpuStyle(const std::string& style); 425 426 static MultiGpuCategory StringToMultiGpuCategory( 427 const std::string& category); 428 429 // map a feature_name to feature_id. If the string is not a registered 430 // feature name, return false. 431 static bool StringToFeature(const std::string& feature_name, 432 int* feature_id, 433 const FeatureMap& feature_map); 434 435 uint32 id_; 436 bool disabled_; 437 std::string description_; 438 std::vector<int> cr_bugs_; 439 std::vector<int> webkit_bugs_; 440 scoped_ptr<OsInfo> os_info_; 441 uint32 vendor_id_; 442 std::vector<uint32> device_id_list_; 443 MultiGpuStyle multi_gpu_style_; 444 MultiGpuCategory multi_gpu_category_; 445 scoped_ptr<StringInfo> driver_vendor_info_; 446 scoped_ptr<VersionInfo> driver_version_info_; 447 scoped_ptr<VersionInfo> driver_date_info_; 448 scoped_ptr<StringInfo> gl_vendor_info_; 449 scoped_ptr<StringInfo> gl_renderer_info_; 450 scoped_ptr<StringInfo> gl_extensions_info_; 451 scoped_ptr<IntInfo> gl_reset_notification_strategy_info_; 452 scoped_ptr<StringInfo> cpu_brand_; 453 scoped_ptr<FloatInfo> perf_graphics_info_; 454 scoped_ptr<FloatInfo> perf_gaming_info_; 455 scoped_ptr<FloatInfo> perf_overall_info_; 456 scoped_ptr<MachineModelInfo> machine_model_info_; 457 scoped_ptr<IntInfo> gpu_count_info_; 458 std::set<int> features_; 459 std::vector<ScopedGpuControlListEntry> exceptions_; 460 bool contains_unknown_fields_; 461 bool contains_unknown_features_; 462 }; 463 464 // Gets the current OS type. 465 static OsType GetOsType(); 466 467 bool LoadList(const base::DictionaryValue& parsed_json, OsFilter os_filter); 468 469 void Clear(); 470 471 // Check if the entry is supported by the current version of browser. 472 // By default, if there is no browser version information in the entry, 473 // return kSupported; 474 BrowserVersionSupport IsEntrySupportedByCurrentBrowserVersion( 475 const base::DictionaryValue* value); 476 477 static NumericOp StringToNumericOp(const std::string& op); 478 479 std::string version_; 480 std::vector<ScopedGpuControlListEntry> entries_; 481 482 std::string browser_version_; 483 484 // This records all the blacklist entries that are appliable to the current 485 // user machine. It is updated everytime MakeDecision() is called and is 486 // used later by GetDecisionEntries(). 487 std::vector<ScopedGpuControlListEntry> active_entries_; 488 489 uint32 max_entry_id_; 490 491 bool contains_unknown_fields_; 492 493 bool needs_more_info_; 494 495 // The features a GpuControlList recognizes and handles. 496 FeatureMap feature_map_; 497 bool supports_feature_type_all_; 498 }; 499 500 } // namespace gpu 501 502 #endif // GPU_CONFIG_GPU_CONTROL_LIST_H_ 503 504