OLD | NEW |
| (Empty) |
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 #include <vector> | |
6 | |
7 #include "base/memory/scoped_ptr.h" | |
8 #include "content/browser/gpu/gpu_control_list.h" | |
9 #include "content/public/common/gpu_info.h" | |
10 #include "testing/gtest/include/gtest/gtest.h" | |
11 | |
12 const char kOsVersion[] = "10.6.4"; | |
13 const uint32 kIntelVendorId = 0x8086; | |
14 const uint32 kIntelDeviceId = 0x0166; // 3rd Gen Core Graphics | |
15 const uint32 kNvidiaVendorId = 0x10de; | |
16 const uint32 kNvidiaDeviceId = 0x0fd5; // GeForce GT 650M | |
17 | |
18 #define LONG_STRING_CONST(...) #__VA_ARGS__ | |
19 | |
20 #define EXPECT_EMPTY_SET(feature_set) EXPECT_EQ(0u, feature_set.size()) | |
21 #define EXPECT_SINGLE_FEATURE(feature_set, feature) \ | |
22 EXPECT_TRUE(feature_set.size() == 1 && feature_set.count(feature) == 1) | |
23 | |
24 namespace content { | |
25 | |
26 enum TestFeatureType { | |
27 TEST_FEATURE_0 = 1, | |
28 TEST_FEATURE_1 = 1 << 2, | |
29 TEST_FEATURE_2 = 1 << 3, | |
30 }; | |
31 | |
32 class GpuControlListTest : public testing::Test { | |
33 public: | |
34 GpuControlListTest() { } | |
35 | |
36 virtual ~GpuControlListTest() { } | |
37 | |
38 const GPUInfo& gpu_info() const { | |
39 return gpu_info_; | |
40 } | |
41 | |
42 GpuControlList* Create() { | |
43 GpuControlList* rt = new GpuControlList(); | |
44 rt->AddSupportedFeature("test_feature_0", TEST_FEATURE_0); | |
45 rt->AddSupportedFeature("test_feature_1", TEST_FEATURE_1); | |
46 rt->AddSupportedFeature("test_feature_2", TEST_FEATURE_2); | |
47 return rt; | |
48 } | |
49 | |
50 protected: | |
51 virtual void SetUp() { | |
52 gpu_info_.gpu.vendor_id = kNvidiaVendorId; | |
53 gpu_info_.gpu.device_id = 0x0640; | |
54 gpu_info_.driver_vendor = "NVIDIA"; | |
55 gpu_info_.driver_version = "1.6.18"; | |
56 gpu_info_.driver_date = "7-14-2009"; | |
57 gpu_info_.machine_model = "MacBookPro 7.1"; | |
58 gpu_info_.gl_vendor = "NVIDIA Corporation"; | |
59 gpu_info_.gl_renderer = "NVIDIA GeForce GT 120 OpenGL Engine"; | |
60 gpu_info_.performance_stats.graphics = 5.0; | |
61 gpu_info_.performance_stats.gaming = 5.0; | |
62 gpu_info_.performance_stats.overall = 5.0; | |
63 } | |
64 | |
65 virtual void TearDown() { | |
66 } | |
67 | |
68 private: | |
69 GPUInfo gpu_info_; | |
70 }; | |
71 | |
72 TEST_F(GpuControlListTest, DefaultControlListSettings) { | |
73 scoped_ptr<GpuControlList> control_list(Create()); | |
74 // Default control list settings: all feature are allowed. | |
75 std::set<int> features = control_list->MakeDecision( | |
76 GpuControlList::kOsMacosx, kOsVersion, gpu_info()); | |
77 EXPECT_EMPTY_SET(features); | |
78 } | |
79 | |
80 TEST_F(GpuControlListTest, EmptyControlList) { | |
81 // Empty list: all features are allowed. | |
82 const std::string empty_list_json = LONG_STRING_CONST( | |
83 { | |
84 "name": "gpu control list", | |
85 "version": "2.5", | |
86 "entries": [ | |
87 ] | |
88 } | |
89 ); | |
90 scoped_ptr<GpuControlList> control_list(Create()); | |
91 | |
92 EXPECT_TRUE(control_list->LoadList(empty_list_json, | |
93 GpuControlList::kAllOs)); | |
94 EXPECT_EQ("2.5", control_list->version()); | |
95 std::set<int> features = control_list->MakeDecision( | |
96 GpuControlList::kOsMacosx, kOsVersion, gpu_info()); | |
97 EXPECT_EMPTY_SET(features); | |
98 } | |
99 | |
100 TEST_F(GpuControlListTest, DetailedEntryAndInvalidJson) { | |
101 // exact setting. | |
102 const std::string exact_list_json = LONG_STRING_CONST( | |
103 { | |
104 "name": "gpu control list", | |
105 "version": "0.1", | |
106 "entries": [ | |
107 { | |
108 "id": 5, | |
109 "os": { | |
110 "type": "macosx", | |
111 "version": { | |
112 "op": "=", | |
113 "number": "10.6.4" | |
114 } | |
115 }, | |
116 "vendor_id": "0x10de", | |
117 "device_id": ["0x0640"], | |
118 "driver_version": { | |
119 "op": "=", | |
120 "number": "1.6.18" | |
121 }, | |
122 "features": [ | |
123 "test_feature_0" | |
124 ] | |
125 } | |
126 ] | |
127 } | |
128 ); | |
129 scoped_ptr<GpuControlList> control_list(Create()); | |
130 | |
131 EXPECT_TRUE(control_list->LoadList(exact_list_json, GpuControlList::kAllOs)); | |
132 std::set<int> features = control_list->MakeDecision( | |
133 GpuControlList::kOsMacosx, kOsVersion, gpu_info()); | |
134 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); | |
135 | |
136 // Invalid json input should not change the current control_list settings. | |
137 const std::string invalid_json = "invalid"; | |
138 | |
139 EXPECT_FALSE(control_list->LoadList(invalid_json, GpuControlList::kAllOs)); | |
140 features = control_list->MakeDecision( | |
141 GpuControlList::kOsMacosx, kOsVersion, gpu_info()); | |
142 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); | |
143 std::vector<uint32> entries; | |
144 control_list->GetDecisionEntries(&entries, false); | |
145 ASSERT_EQ(1u, entries.size()); | |
146 EXPECT_EQ(5u, entries[0]); | |
147 EXPECT_EQ(5u, control_list->max_entry_id()); | |
148 } | |
149 | |
150 TEST_F(GpuControlListTest, VendorOnAllOsEntry) { | |
151 // ControlList a vendor on all OS. | |
152 const std::string vendor_json = LONG_STRING_CONST( | |
153 { | |
154 "name": "gpu control list", | |
155 "version": "0.1", | |
156 "entries": [ | |
157 { | |
158 "id": 1, | |
159 "vendor_id": "0x10de", | |
160 "features": [ | |
161 "test_feature_0" | |
162 ] | |
163 } | |
164 ] | |
165 } | |
166 ); | |
167 scoped_ptr<GpuControlList> control_list(Create()); | |
168 | |
169 // ControlList entries won't be filtered to the current OS only upon loading. | |
170 EXPECT_TRUE(control_list->LoadList(vendor_json, GpuControlList::kAllOs)); | |
171 std::set<int> features = control_list->MakeDecision( | |
172 GpuControlList::kOsMacosx, kOsVersion, gpu_info()); | |
173 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); | |
174 features = control_list->MakeDecision( | |
175 GpuControlList::kOsWin, kOsVersion, gpu_info()); | |
176 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); | |
177 features = control_list->MakeDecision( | |
178 GpuControlList::kOsLinux, kOsVersion, gpu_info()); | |
179 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); | |
180 #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_MACOSX) || \ | |
181 defined(OS_OPENBSD) | |
182 // ControlList entries will be filtered to the current OS only upon loading. | |
183 EXPECT_TRUE(control_list->LoadList( | |
184 vendor_json, GpuControlList::kCurrentOsOnly)); | |
185 features = control_list->MakeDecision( | |
186 GpuControlList::kOsMacosx, kOsVersion, gpu_info()); | |
187 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); | |
188 features = control_list->MakeDecision( | |
189 GpuControlList::kOsWin, kOsVersion, gpu_info()); | |
190 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); | |
191 features = control_list->MakeDecision( | |
192 GpuControlList::kOsLinux, kOsVersion, gpu_info()); | |
193 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); | |
194 #endif | |
195 } | |
196 | |
197 TEST_F(GpuControlListTest, ChromeVersionEntry) { | |
198 const std::string browser_version_json = LONG_STRING_CONST( | |
199 { | |
200 "name": "gpu control list", | |
201 "version": "0.1", | |
202 "entries": [ | |
203 { | |
204 "id": 1, | |
205 "browser_version": { | |
206 "op": ">=", | |
207 "number": "10" | |
208 }, | |
209 "features": [ | |
210 "test_feature_0" | |
211 ] | |
212 } | |
213 ] | |
214 } | |
215 ); | |
216 scoped_ptr<GpuControlList> control_list9(Create()); | |
217 EXPECT_TRUE(control_list9->LoadList( | |
218 "9.0", browser_version_json, GpuControlList::kAllOs)); | |
219 std::set<int> features = control_list9->MakeDecision( | |
220 GpuControlList::kOsWin, kOsVersion, gpu_info()); | |
221 EXPECT_EMPTY_SET(features); | |
222 | |
223 scoped_ptr<GpuControlList> control_list10(Create()); | |
224 EXPECT_TRUE(control_list10->LoadList( | |
225 "10.0", browser_version_json, GpuControlList::kAllOs)); | |
226 features = control_list10->MakeDecision( | |
227 GpuControlList::kOsWin, kOsVersion, gpu_info()); | |
228 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); | |
229 } | |
230 | |
231 TEST_F(GpuControlListTest, UnknownField) { | |
232 const std::string unknown_field_json = LONG_STRING_CONST( | |
233 { | |
234 "name": "gpu control list", | |
235 "version": "0.1", | |
236 "entries": [ | |
237 { | |
238 "id": 1, | |
239 "unknown_field": 0, | |
240 "features": [ | |
241 "test_feature_1" | |
242 ] | |
243 }, | |
244 { | |
245 "id": 2, | |
246 "features": [ | |
247 "test_feature_0" | |
248 ] | |
249 } | |
250 ] | |
251 } | |
252 ); | |
253 scoped_ptr<GpuControlList> control_list(Create()); | |
254 | |
255 EXPECT_TRUE(control_list->LoadList( | |
256 unknown_field_json, GpuControlList::kAllOs)); | |
257 EXPECT_EQ(1u, control_list->num_entries()); | |
258 EXPECT_TRUE(control_list->contains_unknown_fields()); | |
259 std::set<int> features = control_list->MakeDecision( | |
260 GpuControlList::kOsWin, kOsVersion, gpu_info()); | |
261 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); | |
262 } | |
263 | |
264 TEST_F(GpuControlListTest, UnknownExceptionField) { | |
265 const std::string unknown_exception_field_json = LONG_STRING_CONST( | |
266 { | |
267 "name": "gpu control list", | |
268 "version": "0.1", | |
269 "entries": [ | |
270 { | |
271 "id": 1, | |
272 "unknown_field": 0, | |
273 "features": [ | |
274 "test_feature_2" | |
275 ] | |
276 }, | |
277 { | |
278 "id": 2, | |
279 "exceptions": [ | |
280 { | |
281 "unknown_field": 0 | |
282 } | |
283 ], | |
284 "features": [ | |
285 "test_feature_1" | |
286 ] | |
287 }, | |
288 { | |
289 "id": 3, | |
290 "features": [ | |
291 "test_feature_0" | |
292 ] | |
293 } | |
294 ] | |
295 } | |
296 ); | |
297 scoped_ptr<GpuControlList> control_list(Create()); | |
298 | |
299 EXPECT_TRUE(control_list->LoadList( | |
300 unknown_exception_field_json, GpuControlList::kAllOs)); | |
301 EXPECT_EQ(1u, control_list->num_entries()); | |
302 EXPECT_TRUE(control_list->contains_unknown_fields()); | |
303 std::set<int> features = control_list->MakeDecision( | |
304 GpuControlList::kOsWin, kOsVersion, gpu_info()); | |
305 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); | |
306 } | |
307 | |
308 TEST_F(GpuControlListTest, DisabledEntry) { | |
309 const std::string disabled_json = LONG_STRING_CONST( | |
310 { | |
311 "name": "gpu control list", | |
312 "version": "0.1", | |
313 "entries": [ | |
314 { | |
315 "id": 1, | |
316 "disabled": true, | |
317 "features": [ | |
318 "test_feature_0" | |
319 ] | |
320 } | |
321 ] | |
322 } | |
323 ); | |
324 scoped_ptr<GpuControlList> control_list(Create()); | |
325 EXPECT_TRUE(control_list->LoadList(disabled_json, GpuControlList::kAllOs)); | |
326 std::set<int> features = control_list->MakeDecision( | |
327 GpuControlList::kOsWin, kOsVersion, gpu_info()); | |
328 EXPECT_EMPTY_SET(features); | |
329 std::vector<uint32> flag_entries; | |
330 control_list->GetDecisionEntries(&flag_entries, false); | |
331 EXPECT_EQ(0u, flag_entries.size()); | |
332 control_list->GetDecisionEntries(&flag_entries, true); | |
333 EXPECT_EQ(1u, flag_entries.size()); | |
334 } | |
335 | |
336 TEST_F(GpuControlListTest, NeedsMoreInfoForExceptions) { | |
337 const std::string json = LONG_STRING_CONST( | |
338 { | |
339 "name": "gpu control list", | |
340 "version": "0.1", | |
341 "entries": [ | |
342 { | |
343 "id": 1, | |
344 "os": { | |
345 "type": "linux" | |
346 }, | |
347 "vendor_id": "0x8086", | |
348 "exceptions": [ | |
349 { | |
350 "gl_renderer": { | |
351 "op": "contains", | |
352 "value": "mesa" | |
353 } | |
354 } | |
355 ], | |
356 "features": [ | |
357 "test_feature_0" | |
358 ] | |
359 } | |
360 ] | |
361 } | |
362 ); | |
363 GPUInfo gpu_info; | |
364 gpu_info.gpu.vendor_id = kIntelVendorId; | |
365 | |
366 scoped_ptr<GpuControlList> control_list(Create()); | |
367 EXPECT_TRUE(control_list->LoadList(json, GpuControlList::kAllOs)); | |
368 | |
369 // The case this entry does not apply. | |
370 std::set<int> features = control_list->MakeDecision( | |
371 GpuControlList::kOsMacosx, kOsVersion, gpu_info); | |
372 EXPECT_EMPTY_SET(features); | |
373 EXPECT_FALSE(control_list->needs_more_info()); | |
374 | |
375 // The case this entry might apply, but need more info. | |
376 features = control_list->MakeDecision( | |
377 GpuControlList::kOsLinux, kOsVersion, gpu_info); | |
378 EXPECT_EMPTY_SET(features); | |
379 EXPECT_TRUE(control_list->needs_more_info()); | |
380 | |
381 // The case we have full info, and the exception applies (so the entry | |
382 // does not apply). | |
383 gpu_info.gl_renderer = "mesa"; | |
384 features = control_list->MakeDecision( | |
385 GpuControlList::kOsLinux, kOsVersion, gpu_info); | |
386 EXPECT_EMPTY_SET(features); | |
387 EXPECT_FALSE(control_list->needs_more_info()); | |
388 | |
389 // The case we have full info, and this entry applies. | |
390 gpu_info.gl_renderer = "my renderer"; | |
391 features = control_list->MakeDecision(GpuControlList::kOsLinux, kOsVersion, | |
392 gpu_info); | |
393 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); | |
394 EXPECT_FALSE(control_list->needs_more_info()); | |
395 } | |
396 | |
397 TEST_F(GpuControlListTest, IgnorableEntries) { | |
398 // If an entry will not change the control_list decisions, then it should not | |
399 // trigger the needs_more_info flag. | |
400 const std::string json = LONG_STRING_CONST( | |
401 { | |
402 "name": "gpu control list", | |
403 "version": "0.1", | |
404 "entries": [ | |
405 { | |
406 "id": 1, | |
407 "os": { | |
408 "type": "linux" | |
409 }, | |
410 "vendor_id": "0x8086", | |
411 "features": [ | |
412 "test_feature_0" | |
413 ] | |
414 }, | |
415 { | |
416 "id": 2, | |
417 "os": { | |
418 "type": "linux" | |
419 }, | |
420 "vendor_id": "0x8086", | |
421 "driver_version": { | |
422 "op": "<", | |
423 "number": "10.7" | |
424 }, | |
425 "features": [ | |
426 "test_feature_0" | |
427 ] | |
428 } | |
429 ] | |
430 } | |
431 ); | |
432 GPUInfo gpu_info; | |
433 gpu_info.gpu.vendor_id = kIntelVendorId; | |
434 | |
435 scoped_ptr<GpuControlList> control_list(Create()); | |
436 EXPECT_TRUE(control_list->LoadList(json, GpuControlList::kAllOs)); | |
437 std::set<int> features = control_list->MakeDecision( | |
438 GpuControlList::kOsLinux, kOsVersion, gpu_info); | |
439 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0); | |
440 EXPECT_FALSE(control_list->needs_more_info()); | |
441 } | |
442 | |
443 } // namespace content | |
444 | |
OLD | NEW |