OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CONTENT_BROWSER_GPU_GPU_BLACKLIST_H_ | 5 #ifndef CONTENT_BROWSER_GPU_GPU_BLACKLIST_H_ |
6 #define CONTENT_BROWSER_GPU_GPU_BLACKLIST_H_ | 6 #define CONTENT_BROWSER_GPU_GPU_BLACKLIST_H_ |
7 | 7 |
8 #include <string> | 8 #include <string> |
9 #include <vector> | |
10 | 9 |
11 #include "base/basictypes.h" | 10 #include "content/browser/gpu/gpu_control_list.h" |
12 #include "base/gtest_prod_util.h" | |
13 #include "base/memory/ref_counted.h" | |
14 #include "base/memory/scoped_ptr.h" | |
15 #include "base/values.h" | |
16 #include "build/build_config.h" | |
17 #include "content/common/content_export.h" | |
18 #include "content/public/common/gpu_feature_type.h" | |
19 #include "content/public/common/gpu_switching_option.h" | |
20 | 11 |
21 namespace content { | 12 namespace content { |
22 struct GPUInfo; | |
23 | 13 |
24 class CONTENT_EXPORT GpuBlacklist { | 14 class CONTENT_EXPORT GpuBlacklist : public GpuControlList { |
25 public: | 15 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 struct Decision { | |
44 GpuFeatureType blacklisted_features; | |
45 GpuSwitchingOption gpu_switching; | |
46 | |
47 Decision() | |
48 : blacklisted_features(GPU_FEATURE_TYPE_UNKNOWN), | |
49 gpu_switching(GPU_SWITCHING_OPTION_UNKNOWN) { | |
50 } | |
51 }; | |
52 | |
53 GpuBlacklist(); | |
54 virtual ~GpuBlacklist(); | 16 virtual ~GpuBlacklist(); |
55 | 17 |
56 // Loads blacklist information from a json file. | 18 static GpuBlacklist* Create(); |
57 // If failed, the current GpuBlacklist is un-touched. | |
58 bool LoadGpuBlacklist(const std::string& json_context, OsFilter os_filter); | |
59 bool LoadGpuBlacklist(const std::string& browser_version_string, | |
60 const std::string& json_context, | |
61 OsFilter os_filter); | |
62 | |
63 // Collects system information and combines them with gpu_info and blacklist | |
64 // information to make the blacklist decision. | |
65 // If os is kOsAny, use the current OS; if os_version is empty, use the | |
66 // current OS version. | |
67 Decision MakeBlacklistDecision( | |
68 OsType os, std::string os_version, const GPUInfo& gpu_info); | |
69 | |
70 // Collects the active entries from the last MakeBlacklistDecision() call. | |
71 // If disabled set to true, return entries that are disabled; otherwise, | |
72 // return enabled entries. | |
73 void GetDecisionEntries(std::vector<uint32>* entry_ids, | |
74 bool disabled) const; | |
75 | |
76 // Returns the description and bugs from active entries from the last | |
77 // MakeBlacklistDecision() call. | |
78 // | |
79 // Each problems has: | |
80 // { | |
81 // "description": "Your GPU is too old", | |
82 // "crBugs": [1234], | |
83 // "webkitBugs": [] | |
84 // } | |
85 void GetBlacklistReasons(base::ListValue* problem_list) const; | |
86 | |
87 // Return the largest entry id. This is used for histogramming. | |
88 uint32 max_entry_id() const; | |
89 | |
90 // Returns the version of the current blacklist. | |
91 std::string GetVersion() const; | |
92 | |
93 // Check if we needs more gpu info to make the blacklisting decisions. | |
94 // This is computed from the last MakeBlacklistDecision() call. | |
95 // If yes, we should create a gl context and do a full gpu info collection. | |
96 bool needs_more_info() const { return needs_more_info_; } | |
97 | 19 |
98 private: | 20 private: |
99 friend class GpuBlacklistTest; | 21 GpuBlacklist(); |
100 FRIEND_TEST_ALL_PREFIXES(GpuBlacklistTest, ChromeVersionEntry); | |
101 FRIEND_TEST_ALL_PREFIXES(GpuBlacklistTest, CurrentBlacklistValidation); | |
102 FRIEND_TEST_ALL_PREFIXES(GpuBlacklistTest, DualGpuModel); | |
103 FRIEND_TEST_ALL_PREFIXES(GpuBlacklistTest, UnknownExceptionField); | |
104 FRIEND_TEST_ALL_PREFIXES(GpuBlacklistTest, UnknownFeature); | |
105 FRIEND_TEST_ALL_PREFIXES(GpuBlacklistTest, UnknownField); | |
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 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 as segments as version_ref contains. | |
159 // If version_ref is xxx.yyy, it's considered as xxx.yyy.* | |
160 // For example: Compare("10.3.1", "10.3") returns 0, | |
161 // Compare("10.3", "10.3.1") returns -1. | |
162 // If "version_style" is Lexical, the first segment is compared | |
163 // numerically, all other segments are compared lexically. | |
164 // Lexical is used for AMD Linux driver versions only. | |
165 static int Compare(const std::vector<std::string>& version, | |
166 const std::vector<std::string>& version_ref, | |
167 VersionStyle version_style); | |
168 | |
169 NumericOp op_; | |
170 VersionStyle version_style_; | |
171 std::vector<std::string> version_; | |
172 std::vector<std::string> version2_; | |
173 }; | |
174 | |
175 class OsInfo { | |
176 public: | |
177 OsInfo(const std::string& os, | |
178 const std::string& version_op, | |
179 const std::string& version_string, | |
180 const std::string& version_string2); | |
181 ~OsInfo(); | |
182 | |
183 // Determines if a given os/version is included in the OsInfo set. | |
184 bool Contains(OsType type, const std::string& version) const; | |
185 | |
186 // Determines if the VersionInfo contains valid information. | |
187 bool IsValid() const; | |
188 | |
189 OsType type() const; | |
190 | |
191 // Maps string to OsType; returns kOsUnknown if it's not a valid os. | |
192 static OsType StringToOsType(const std::string& os); | |
193 | |
194 private: | |
195 OsType type_; | |
196 scoped_ptr<VersionInfo> version_info_; | |
197 }; | |
198 | |
199 class StringInfo { | |
200 public: | |
201 StringInfo(const std::string& string_op, const std::string& string_value); | |
202 | |
203 // Determines if a given string is included in the StringInfo. | |
204 bool Contains(const std::string& value) const; | |
205 | |
206 // Determines if the StringInfo contains valid information. | |
207 bool IsValid() const; | |
208 | |
209 private: | |
210 enum Op { | |
211 kContains, | |
212 kBeginWith, | |
213 kEndWith, | |
214 kEQ, // = | |
215 kUnknown // Indicates StringInfo data is invalid. | |
216 }; | |
217 | |
218 // Maps string to Op; returns kUnknown if it's not a valid Op. | |
219 static Op StringToOp(const std::string& string_op); | |
220 | |
221 Op op_; | |
222 std::string value_; | |
223 }; | |
224 | |
225 class FloatInfo { | |
226 public: | |
227 FloatInfo(const std::string& float_op, | |
228 const std::string& float_value, | |
229 const std::string& float_value2); | |
230 | |
231 // Determines if a given float is included in the FloatInfo. | |
232 bool Contains(float value) const; | |
233 | |
234 // Determines if the FloatInfo contains valid information. | |
235 bool IsValid() const; | |
236 | |
237 private: | |
238 NumericOp op_; | |
239 float value_; | |
240 float value2_; | |
241 }; | |
242 | |
243 class IntInfo { | |
244 public: | |
245 IntInfo(const std::string& int_op, | |
246 const std::string& int_value, | |
247 const std::string& int_value2); | |
248 | |
249 // Determines if a given int is included in the IntInfo. | |
250 bool Contains(int value) const; | |
251 | |
252 // Determines if the IntInfo contains valid information. | |
253 bool IsValid() const; | |
254 | |
255 private: | |
256 NumericOp op_; | |
257 int value_; | |
258 int value2_; | |
259 }; | |
260 | |
261 class MachineModelInfo { | |
262 public: | |
263 MachineModelInfo(const std::string& name_op, | |
264 const std::string& name_value, | |
265 const std::string& version_op, | |
266 const std::string& version_string, | |
267 const std::string& version_string2); | |
268 ~MachineModelInfo(); | |
269 | |
270 // Determines if a given name/version is included in the MachineModelInfo. | |
271 bool Contains(const std::string& name, const std::string& version) const; | |
272 | |
273 // Determines if the MachineModelInfo contains valid information. | |
274 bool IsValid() const; | |
275 | |
276 private: | |
277 scoped_ptr<StringInfo> name_info_; | |
278 scoped_ptr<VersionInfo> version_info_; | |
279 }; | |
280 | |
281 class GpuBlacklistEntry; | |
282 typedef scoped_refptr<GpuBlacklistEntry> ScopedGpuBlacklistEntry; | |
283 | |
284 class GpuBlacklistEntry : public base::RefCounted<GpuBlacklistEntry> { | |
285 public: | |
286 // Constructs GpuBlacklistEntry from DictionaryValue loaded from json. | |
287 // Top-level entry must have an id number. Others are exceptions. | |
288 static ScopedGpuBlacklistEntry GetGpuBlacklistEntryFromValue( | |
289 const base::DictionaryValue* value, bool top_level); | |
290 | |
291 // Determines if a given os/gc/machine_model/driver is included in the | |
292 // Entry set. | |
293 bool Contains(OsType os_type, const std::string& os_version, | |
294 const GPUInfo& gpu_info) const; | |
295 | |
296 // Determines whether we needs more gpu info to make the blacklisting | |
297 // decision. It should only be checked if Contains() returns true. | |
298 bool NeedsMoreInfo(const GPUInfo& gpu_info) const; | |
299 | |
300 // Returns the OsType. | |
301 OsType GetOsType() const; | |
302 | |
303 // Returns the entry's unique id. 0 is reserved. | |
304 uint32 id() const; | |
305 | |
306 // Returns whether the entry is disabled. | |
307 bool disabled() const; | |
308 | |
309 // Returns the description of the entry | |
310 const std::string& description() const { return description_; } | |
311 | |
312 // Returns a list of Chromium and Webkit bugs applicable to this entry | |
313 const std::vector<int>& cr_bugs() const { return cr_bugs_; } | |
314 const std::vector<int>& webkit_bugs() const { return webkit_bugs_; } | |
315 | |
316 // Returns the GpuFeatureType. | |
317 GpuFeatureType GetGpuFeatureType() const; | |
318 | |
319 // Returns the GpuSwitchingOption. | |
320 GpuSwitchingOption GetGpuSwitchingOption() const; | |
321 | |
322 // Returns true if an unknown field is encountered. | |
323 bool contains_unknown_fields() const { | |
324 return contains_unknown_fields_; | |
325 } | |
326 // Returns true if an unknown blacklist feature is encountered. | |
327 bool contains_unknown_features() const { | |
328 return contains_unknown_features_; | |
329 } | |
330 | |
331 private: | |
332 friend class base::RefCounted<GpuBlacklistEntry>; | |
333 | |
334 enum MultiGpuStyle { | |
335 kMultiGpuStyleOptimus, | |
336 kMultiGpuStyleAMDSwitchable, | |
337 kMultiGpuStyleNone | |
338 }; | |
339 | |
340 enum MultiGpuCategory { | |
341 kMultiGpuCategoryPrimary, | |
342 kMultiGpuCategorySecondary, | |
343 kMultiGpuCategoryAny, | |
344 kMultiGpuCategoryNone | |
345 }; | |
346 | |
347 GpuBlacklistEntry(); | |
348 ~GpuBlacklistEntry(); | |
349 | |
350 bool SetId(uint32 id); | |
351 | |
352 void SetDisabled(bool disabled); | |
353 | |
354 bool SetOsInfo(const std::string& os, | |
355 const std::string& version_op, | |
356 const std::string& version_string, | |
357 const std::string& version_string2); | |
358 | |
359 bool SetVendorId(const std::string& vendor_id_string); | |
360 | |
361 bool AddDeviceId(const std::string& device_id_string); | |
362 | |
363 bool SetMultiGpuStyle(const std::string& multi_gpu_style_string); | |
364 | |
365 bool SetMultiGpuCategory(const std::string& multi_gpu_category_string); | |
366 | |
367 bool SetDriverVendorInfo(const std::string& vendor_op, | |
368 const std::string& vendor_value); | |
369 | |
370 bool SetDriverVersionInfo(const std::string& version_op, | |
371 const std::string& version_style, | |
372 const std::string& version_string, | |
373 const std::string& version_string2); | |
374 | |
375 bool SetDriverDateInfo(const std::string& date_op, | |
376 const std::string& date_string, | |
377 const std::string& date_string2); | |
378 | |
379 bool SetGLVendorInfo(const std::string& vendor_op, | |
380 const std::string& vendor_value); | |
381 | |
382 bool SetGLRendererInfo(const std::string& renderer_op, | |
383 const std::string& renderer_value); | |
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 SetBlacklistedFeatures( | |
411 const std::vector<std::string>& blacklisted_features); | |
412 | |
413 bool SetGpuSwitchingOption(const std::string& switching_string); | |
414 | |
415 void AddException(ScopedGpuBlacklistEntry exception); | |
416 | |
417 static MultiGpuStyle StringToMultiGpuStyle(const std::string& style); | |
418 | |
419 static MultiGpuCategory StringToMultiGpuCategory( | |
420 const std::string& category); | |
421 | |
422 uint32 id_; | |
423 bool disabled_; | |
424 std::string description_; | |
425 std::vector<int> cr_bugs_; | |
426 std::vector<int> webkit_bugs_; | |
427 scoped_ptr<OsInfo> os_info_; | |
428 uint32 vendor_id_; | |
429 std::vector<uint32> device_id_list_; | |
430 MultiGpuStyle multi_gpu_style_; | |
431 MultiGpuCategory multi_gpu_category_; | |
432 scoped_ptr<StringInfo> driver_vendor_info_; | |
433 scoped_ptr<VersionInfo> driver_version_info_; | |
434 scoped_ptr<VersionInfo> driver_date_info_; | |
435 scoped_ptr<StringInfo> gl_vendor_info_; | |
436 scoped_ptr<StringInfo> gl_renderer_info_; | |
437 scoped_ptr<StringInfo> cpu_brand_; | |
438 scoped_ptr<FloatInfo> perf_graphics_info_; | |
439 scoped_ptr<FloatInfo> perf_gaming_info_; | |
440 scoped_ptr<FloatInfo> perf_overall_info_; | |
441 scoped_ptr<MachineModelInfo> machine_model_info_; | |
442 scoped_ptr<IntInfo> gpu_count_info_; | |
443 Decision decision_; | |
444 std::vector<ScopedGpuBlacklistEntry> exceptions_; | |
445 bool contains_unknown_fields_; | |
446 bool contains_unknown_features_; | |
447 }; | |
448 | |
449 // Gets the current OS type. | |
450 static OsType GetOsType(); | |
451 | |
452 bool LoadGpuBlacklist(const base::DictionaryValue& parsed_json, | |
453 OsFilter os_filter); | |
454 | |
455 void Clear(); | |
456 | |
457 // Check if the entry is supported by the current version of browser. | |
458 // By default, if there is no browser version information in the entry, | |
459 // return kSupported; | |
460 BrowserVersionSupport IsEntrySupportedByCurrentBrowserVersion( | |
461 const base::DictionaryValue* value); | |
462 | |
463 // Returns the number of entries. This is only for tests. | |
464 size_t num_entries() const; | |
465 | |
466 // Check if any entries contain unknown fields. This is only for tests. | |
467 bool contains_unknown_fields() const { return contains_unknown_fields_; } | |
468 | |
469 static NumericOp StringToNumericOp(const std::string& op); | |
470 | |
471 std::string version_; | |
472 std::vector<ScopedGpuBlacklistEntry> blacklist_; | |
473 | |
474 std::string browser_version_; | |
475 | |
476 // This records all the blacklist entries that are appliable to the current | |
477 // user machine. It is updated everytime MakeBlacklistDecision() is | |
478 // called and is used later by GetDecisionEntries(). | |
479 std::vector<ScopedGpuBlacklistEntry> active_entries_; | |
480 | |
481 uint32 max_entry_id_; | |
482 | |
483 bool contains_unknown_fields_; | |
484 | |
485 bool needs_more_info_; | |
486 | 22 |
487 DISALLOW_COPY_AND_ASSIGN(GpuBlacklist); | 23 DISALLOW_COPY_AND_ASSIGN(GpuBlacklist); |
488 }; | 24 }; |
489 | 25 |
490 } // namespace content | 26 } // namespace content |
491 | 27 |
492 #endif // CONTENT_BROWSER_GPU_GPU_BLACKLIST_H_ | 28 #endif // CONTENT_BROWSER_GPU_GPU_BLACKLIST_H_ |
OLD | NEW |