Get GenericScopedHandle::Set to preserve LastError code
[chromium-blink-merge.git] / gpu / config / gpu_control_list_unittest.cc
blob402998bfce1405bdb081c16756847c85a6513056
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.
5 #include <vector>
7 #include "base/memory/scoped_ptr.h"
8 #include "gpu/config/gpu_control_list.h"
9 #include "gpu/config/gpu_info.h"
10 #include "testing/gtest/include/gtest/gtest.h"
12 const char kOsVersion[] = "10.6.4";
13 const uint32 kIntelVendorId = 0x8086;
14 const uint32 kNvidiaVendorId = 0x10de;
15 const uint32 kAmdVendorId = 0x10de;
17 #define LONG_STRING_CONST(...) #__VA_ARGS__
19 #define EXPECT_EMPTY_SET(feature_set) EXPECT_EQ(0u, feature_set.size())
20 #define EXPECT_SINGLE_FEATURE(feature_set, feature) \
21 EXPECT_TRUE(feature_set.size() == 1 && feature_set.count(feature) == 1)
23 namespace gpu {
25 enum TestFeatureType {
26 TEST_FEATURE_0 = 1,
27 TEST_FEATURE_1 = 1 << 2,
28 TEST_FEATURE_2 = 1 << 3,
31 class GpuControlListTest : public testing::Test {
32 public:
33 GpuControlListTest() { }
35 ~GpuControlListTest() override {}
37 const GPUInfo& gpu_info() const {
38 return gpu_info_;
41 GpuControlList* Create() {
42 GpuControlList* rt = new GpuControlList();
43 rt->AddSupportedFeature("test_feature_0", TEST_FEATURE_0);
44 rt->AddSupportedFeature("test_feature_1", TEST_FEATURE_1);
45 rt->AddSupportedFeature("test_feature_2", TEST_FEATURE_2);
46 return rt;
49 protected:
50 void SetUp() override {
51 gpu_info_.gpu.vendor_id = kNvidiaVendorId;
52 gpu_info_.gpu.device_id = 0x0640;
53 gpu_info_.driver_vendor = "NVIDIA";
54 gpu_info_.driver_version = "1.6.18";
55 gpu_info_.driver_date = "7-14-2009";
56 gpu_info_.machine_model_name = "MacBookPro";
57 gpu_info_.machine_model_version = "7.1";
58 gpu_info_.gl_vendor = "NVIDIA Corporation";
59 gpu_info_.gl_renderer = "NVIDIA GeForce GT 120 OpenGL Engine";
62 void TearDown() override {}
64 private:
65 GPUInfo gpu_info_;
68 TEST_F(GpuControlListTest, DefaultControlListSettings) {
69 scoped_ptr<GpuControlList> control_list(Create());
70 // Default control list settings: all feature are allowed.
71 std::set<int> features = control_list->MakeDecision(
72 GpuControlList::kOsMacosx, kOsVersion, gpu_info());
73 EXPECT_EMPTY_SET(features);
76 TEST_F(GpuControlListTest, EmptyControlList) {
77 // Empty list: all features are allowed.
78 const std::string empty_list_json = LONG_STRING_CONST(
80 "name": "gpu control list",
81 "version": "2.5",
82 "entries": [
86 scoped_ptr<GpuControlList> control_list(Create());
88 EXPECT_TRUE(control_list->LoadList(empty_list_json,
89 GpuControlList::kAllOs));
90 EXPECT_EQ("2.5", control_list->version());
91 std::set<int> features = control_list->MakeDecision(
92 GpuControlList::kOsMacosx, kOsVersion, gpu_info());
93 EXPECT_EMPTY_SET(features);
96 TEST_F(GpuControlListTest, DetailedEntryAndInvalidJson) {
97 // exact setting.
98 const std::string exact_list_json = LONG_STRING_CONST(
100 "name": "gpu control list",
101 "version": "0.1",
102 "entries": [
104 "id": 5,
105 "os": {
106 "type": "macosx",
107 "version": {
108 "op": "=",
109 "value": "10.6.4"
112 "vendor_id": "0x10de",
113 "device_id": ["0x0640"],
114 "driver_version": {
115 "op": "=",
116 "value": "1.6.18"
118 "features": [
119 "test_feature_0"
125 scoped_ptr<GpuControlList> control_list(Create());
127 EXPECT_TRUE(control_list->LoadList(exact_list_json, GpuControlList::kAllOs));
128 std::set<int> features = control_list->MakeDecision(
129 GpuControlList::kOsMacosx, kOsVersion, gpu_info());
130 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
132 // Invalid json input should not change the current control_list settings.
133 const std::string invalid_json = "invalid";
135 EXPECT_FALSE(control_list->LoadList(invalid_json, GpuControlList::kAllOs));
136 features = control_list->MakeDecision(
137 GpuControlList::kOsMacosx, kOsVersion, gpu_info());
138 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
139 std::vector<uint32> entries;
140 control_list->GetDecisionEntries(&entries, false);
141 ASSERT_EQ(1u, entries.size());
142 EXPECT_EQ(5u, entries[0]);
143 EXPECT_EQ(5u, control_list->max_entry_id());
146 TEST_F(GpuControlListTest, VendorOnAllOsEntry) {
147 // ControlList a vendor on all OS.
148 const std::string vendor_json = LONG_STRING_CONST(
150 "name": "gpu control list",
151 "version": "0.1",
152 "entries": [
154 "id": 1,
155 "vendor_id": "0x10de",
156 "features": [
157 "test_feature_0"
163 scoped_ptr<GpuControlList> control_list(Create());
165 // ControlList entries won't be filtered to the current OS only upon loading.
166 EXPECT_TRUE(control_list->LoadList(vendor_json, GpuControlList::kAllOs));
167 std::set<int> features = control_list->MakeDecision(
168 GpuControlList::kOsMacosx, kOsVersion, gpu_info());
169 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
170 features = control_list->MakeDecision(
171 GpuControlList::kOsWin, kOsVersion, gpu_info());
172 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
173 features = control_list->MakeDecision(
174 GpuControlList::kOsLinux, kOsVersion, gpu_info());
175 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
176 #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_MACOSX) || \
177 defined(OS_OPENBSD)
178 // ControlList entries will be filtered to the current OS only upon loading.
179 EXPECT_TRUE(control_list->LoadList(
180 vendor_json, GpuControlList::kCurrentOsOnly));
181 features = control_list->MakeDecision(
182 GpuControlList::kOsMacosx, kOsVersion, gpu_info());
183 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
184 features = control_list->MakeDecision(
185 GpuControlList::kOsWin, kOsVersion, gpu_info());
186 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
187 features = control_list->MakeDecision(
188 GpuControlList::kOsLinux, kOsVersion, gpu_info());
189 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
190 #endif
193 TEST_F(GpuControlListTest, UnknownField) {
194 const std::string unknown_field_json = LONG_STRING_CONST(
196 "name": "gpu control list",
197 "version": "0.1",
198 "entries": [
200 "id": 1,
201 "unknown_field": 0,
202 "features": [
203 "test_feature_1"
207 "id": 2,
208 "features": [
209 "test_feature_0"
215 scoped_ptr<GpuControlList> control_list(Create());
217 EXPECT_FALSE(control_list->LoadList(
218 unknown_field_json, GpuControlList::kAllOs));
221 TEST_F(GpuControlListTest, UnknownExceptionField) {
222 const std::string unknown_exception_field_json = LONG_STRING_CONST(
224 "name": "gpu control list",
225 "version": "0.1",
226 "entries": [
228 "id": 1,
229 "unknown_field": 0,
230 "features": [
231 "test_feature_2"
235 "id": 2,
236 "exceptions": [
238 "unknown_field": 0
241 "features": [
242 "test_feature_1"
246 "id": 3,
247 "features": [
248 "test_feature_0"
254 scoped_ptr<GpuControlList> control_list(Create());
256 EXPECT_FALSE(control_list->LoadList(
257 unknown_exception_field_json, GpuControlList::kAllOs));
260 TEST_F(GpuControlListTest, DisabledEntry) {
261 const std::string disabled_json = LONG_STRING_CONST(
263 "name": "gpu control list",
264 "version": "0.1",
265 "entries": [
267 "id": 1,
268 "disabled": true,
269 "features": [
270 "test_feature_0"
276 scoped_ptr<GpuControlList> control_list(Create());
277 EXPECT_TRUE(control_list->LoadList(disabled_json, GpuControlList::kAllOs));
278 std::set<int> features = control_list->MakeDecision(
279 GpuControlList::kOsWin, kOsVersion, gpu_info());
280 EXPECT_EMPTY_SET(features);
281 std::vector<uint32> flag_entries;
282 control_list->GetDecisionEntries(&flag_entries, false);
283 EXPECT_EQ(0u, flag_entries.size());
284 control_list->GetDecisionEntries(&flag_entries, true);
285 EXPECT_EQ(1u, flag_entries.size());
288 TEST_F(GpuControlListTest, NeedsMoreInfo) {
289 const std::string json = LONG_STRING_CONST(
291 "name": "gpu control list",
292 "version": "0.1",
293 "entries": [
295 "id": 1,
296 "os": {
297 "type": "win"
299 "vendor_id": "0x10de",
300 "driver_version": {
301 "op": "<",
302 "value": "12"
304 "features": [
305 "test_feature_0"
311 GPUInfo gpu_info;
312 gpu_info.gpu.vendor_id = kNvidiaVendorId;
314 scoped_ptr<GpuControlList> control_list(Create());
315 EXPECT_TRUE(control_list->LoadList(json, GpuControlList::kAllOs));
317 std::set<int> features = control_list->MakeDecision(
318 GpuControlList::kOsWin, kOsVersion, gpu_info);
319 EXPECT_EMPTY_SET(features);
320 EXPECT_TRUE(control_list->needs_more_info());
321 std::vector<uint32> decision_entries;
322 control_list->GetDecisionEntries(&decision_entries, false);
323 EXPECT_EQ(0u, decision_entries.size());
325 gpu_info.driver_version = "11";
326 features = control_list->MakeDecision(
327 GpuControlList::kOsWin, kOsVersion, gpu_info);
328 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
329 EXPECT_FALSE(control_list->needs_more_info());
330 control_list->GetDecisionEntries(&decision_entries, false);
331 EXPECT_EQ(1u, decision_entries.size());
334 TEST_F(GpuControlListTest, NeedsMoreInfoForExceptions) {
335 const std::string json = LONG_STRING_CONST(
337 "name": "gpu control list",
338 "version": "0.1",
339 "entries": [
341 "id": 1,
342 "os": {
343 "type": "linux"
345 "vendor_id": "0x8086",
346 "exceptions": [
348 "gl_renderer": ".*mesa.*"
351 "features": [
352 "test_feature_0"
358 GPUInfo gpu_info;
359 gpu_info.gpu.vendor_id = kIntelVendorId;
361 scoped_ptr<GpuControlList> control_list(Create());
362 EXPECT_TRUE(control_list->LoadList(json, GpuControlList::kAllOs));
364 // The case this entry does not apply.
365 std::set<int> features = control_list->MakeDecision(
366 GpuControlList::kOsMacosx, kOsVersion, gpu_info);
367 EXPECT_EMPTY_SET(features);
368 EXPECT_FALSE(control_list->needs_more_info());
370 // The case this entry might apply, but need more info.
371 features = control_list->MakeDecision(
372 GpuControlList::kOsLinux, kOsVersion, gpu_info);
373 // Ignore exceptions if main entry info matches
374 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
375 EXPECT_TRUE(control_list->needs_more_info());
377 // The case we have full info, and the exception applies (so the entry
378 // does not apply).
379 gpu_info.gl_renderer = "mesa";
380 features = control_list->MakeDecision(
381 GpuControlList::kOsLinux, kOsVersion, gpu_info);
382 EXPECT_EMPTY_SET(features);
383 EXPECT_FALSE(control_list->needs_more_info());
385 // The case we have full info, and this entry applies.
386 gpu_info.gl_renderer = "my renderer";
387 features = control_list->MakeDecision(GpuControlList::kOsLinux, kOsVersion,
388 gpu_info);
389 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
390 EXPECT_FALSE(control_list->needs_more_info());
393 TEST_F(GpuControlListTest, IgnorableEntries) {
394 // If an entry will not change the control_list decisions, then it should not
395 // trigger the needs_more_info flag.
396 const std::string json = LONG_STRING_CONST(
398 "name": "gpu control list",
399 "version": "0.1",
400 "entries": [
402 "id": 1,
403 "os": {
404 "type": "linux"
406 "vendor_id": "0x8086",
407 "features": [
408 "test_feature_0"
412 "id": 2,
413 "os": {
414 "type": "linux"
416 "vendor_id": "0x8086",
417 "driver_version": {
418 "op": "<",
419 "value": "10.7"
421 "features": [
422 "test_feature_0"
428 GPUInfo gpu_info;
429 gpu_info.gpu.vendor_id = kIntelVendorId;
431 scoped_ptr<GpuControlList> control_list(Create());
432 EXPECT_TRUE(control_list->LoadList(json, GpuControlList::kAllOs));
433 std::set<int> features = control_list->MakeDecision(
434 GpuControlList::kOsLinux, kOsVersion, gpu_info);
435 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
436 EXPECT_FALSE(control_list->needs_more_info());
439 TEST_F(GpuControlListTest, ExceptionWithoutVendorId) {
440 const std::string json = LONG_STRING_CONST(
442 "name": "gpu control list",
443 "version": "0.1",
444 "entries": [
446 "id": 1,
447 "os": {
448 "type": "linux"
450 "vendor_id": "0x8086",
451 "exceptions": [
453 "device_id": ["0x2a06"],
454 "driver_version": {
455 "op": ">=",
456 "value": "8.1"
460 "device_id": ["0x2a02"],
461 "driver_version": {
462 "op": ">=",
463 "value": "9.1"
467 "features": [
468 "test_feature_0"
474 GPUInfo gpu_info;
475 gpu_info.gpu.vendor_id = kIntelVendorId;
476 gpu_info.gpu.device_id = 0x2a02;
477 gpu_info.driver_version = "9.1";
479 scoped_ptr<GpuControlList> control_list(Create());
480 EXPECT_TRUE(control_list->LoadList(json, GpuControlList::kAllOs));
482 std::set<int> features = control_list->MakeDecision(
483 GpuControlList::kOsLinux, kOsVersion, gpu_info);
484 EXPECT_EMPTY_SET(features);
486 gpu_info.driver_version = "9.0";
487 features = control_list->MakeDecision(
488 GpuControlList::kOsLinux, kOsVersion, gpu_info);
489 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
492 TEST_F(GpuControlListTest, AMDSwitchable) {
493 GPUInfo gpu_info;
494 gpu_info.amd_switchable = true;
495 gpu_info.gpu.vendor_id = kAmdVendorId;
496 gpu_info.gpu.device_id = 0x6760;
497 GPUInfo::GPUDevice integrated_gpu;
498 integrated_gpu.vendor_id = kIntelVendorId;
499 integrated_gpu.device_id = 0x0116;
500 gpu_info.secondary_gpus.push_back(integrated_gpu);
502 { // amd_switchable_discrete entry
503 const std::string json= LONG_STRING_CONST(
505 "name": "gpu control list",
506 "version": "0.1",
507 "entries": [
509 "id": 1,
510 "os": {
511 "type": "win"
513 "multi_gpu_style": "amd_switchable_discrete",
514 "features": [
515 "test_feature_0"
522 scoped_ptr<GpuControlList> control_list(Create());
523 EXPECT_TRUE(control_list->LoadList(json, GpuControlList::kAllOs));
525 // Integrated GPU is active
526 gpu_info.gpu.active = false;
527 gpu_info.secondary_gpus[0].active = true;
528 std::set<int> features = control_list->MakeDecision(
529 GpuControlList::kOsWin, kOsVersion, gpu_info);
530 EXPECT_EMPTY_SET(features);
532 // Discrete GPU is active
533 gpu_info.gpu.active = true;
534 gpu_info.secondary_gpus[0].active = false;
535 features = control_list->MakeDecision(
536 GpuControlList::kOsWin, kOsVersion, gpu_info);
537 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
540 { // amd_switchable_integrated entry
541 const std::string json= LONG_STRING_CONST(
543 "name": "gpu control list",
544 "version": "0.1",
545 "entries": [
547 "id": 1,
548 "os": {
549 "type": "win"
551 "multi_gpu_style": "amd_switchable_integrated",
552 "features": [
553 "test_feature_0"
560 scoped_ptr<GpuControlList> control_list(Create());
561 EXPECT_TRUE(control_list->LoadList(json, GpuControlList::kAllOs));
563 // Discrete GPU is active
564 gpu_info.gpu.active = true;
565 gpu_info.secondary_gpus[0].active = false;
566 std::set<int> features = control_list->MakeDecision(
567 GpuControlList::kOsWin, kOsVersion, gpu_info);
568 EXPECT_EMPTY_SET(features);
570 // Integrated GPU is active
571 gpu_info.gpu.active = false;
572 gpu_info.secondary_gpus[0].active = true;
573 features = control_list->MakeDecision(
574 GpuControlList::kOsWin, kOsVersion, gpu_info);
575 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
577 // For non AMD switchable
578 gpu_info.amd_switchable = false;
579 features = control_list->MakeDecision(
580 GpuControlList::kOsWin, kOsVersion, gpu_info);
581 EXPECT_EMPTY_SET(features);
585 TEST_F(GpuControlListTest, DisabledExtensionTest) {
586 // exact setting.
587 const std::string exact_list_json = LONG_STRING_CONST(
589 "name": "gpu control list",
590 "version": "0.1",
591 "entries": [
593 "id": 1,
594 "os": {
595 "type": "win"
597 "disabled_extensions": [
598 "test_extension2",
599 "test_extension1"
603 "id": 2,
604 "os": {
605 "type": "win"
607 "disabled_extensions": [
608 "test_extension3",
609 "test_extension2"
615 scoped_ptr<GpuControlList> control_list(Create());
617 EXPECT_TRUE(control_list->LoadList(exact_list_json, GpuControlList::kAllOs));
618 GPUInfo gpu_info;
619 control_list->MakeDecision(GpuControlList::kOsWin, kOsVersion, gpu_info);
621 std::vector<std::string> disabled_extensions =
622 control_list->GetDisabledExtensions();
624 ASSERT_EQ(3u, disabled_extensions.size());
625 ASSERT_STREQ("test_extension1", disabled_extensions[0].c_str());
626 ASSERT_STREQ("test_extension2", disabled_extensions[1].c_str());
627 ASSERT_STREQ("test_extension3", disabled_extensions[2].c_str());
630 TEST_F(GpuControlListTest, DisabledInProcessGPUTest) {
631 const std::string exact_list_json = LONG_STRING_CONST(
633 "name": "gpu control list",
634 "version": "0.1",
635 "entries": [
637 "id": 1,
638 "os": {
639 "type": "win"
641 "in_process_gpu": true,
642 "features": [
643 "test_feature_0"
649 scoped_ptr<GpuControlList> control_list(Create());
651 EXPECT_TRUE(control_list->LoadList(exact_list_json, GpuControlList::kAllOs));
652 GPUInfo gpu_info;
654 gpu_info.in_process_gpu = true;
655 std::set<int> features = control_list->MakeDecision(
656 GpuControlList::kOsWin, kOsVersion, gpu_info);
657 EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
659 gpu_info.in_process_gpu = false;
660 features = control_list->MakeDecision(
661 GpuControlList::kOsWin, kOsVersion, gpu_info);
662 EXPECT_EMPTY_SET(features);
665 } // namespace gpu