Home | History | Annotate | Download | only in config
      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