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