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   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