• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
needs_more_info()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.
enable_control_list_logging(const std::string & control_list_logging_name)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
description()315     const std::string& description() const { return description_; }
316 
317     // Returns a list of Chromium and Webkit bugs applicable to this entry
cr_bugs()318     const std::vector<int>& cr_bugs() const { return cr_bugs_; }
webkit_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