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.
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)
25 enum TestFeatureType
{
27 TEST_FEATURE_1
= 1 << 2,
28 TEST_FEATURE_2
= 1 << 3,
31 class GpuControlListTest
: public testing::Test
{
33 GpuControlListTest() { }
35 ~GpuControlListTest() override
{}
37 const GPUInfo
& gpu_info() const {
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
);
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";
60 gpu_info_
.performance_stats
.graphics
= 5.0;
61 gpu_info_
.performance_stats
.gaming
= 5.0;
62 gpu_info_
.performance_stats
.overall
= 5.0;
65 void TearDown() override
{}
71 TEST_F(GpuControlListTest
, DefaultControlListSettings
) {
72 scoped_ptr
<GpuControlList
> control_list(Create());
73 // Default control list settings: all feature are allowed.
74 std::set
<int> features
= control_list
->MakeDecision(
75 GpuControlList::kOsMacosx
, kOsVersion
, gpu_info());
76 EXPECT_EMPTY_SET(features
);
79 TEST_F(GpuControlListTest
, EmptyControlList
) {
80 // Empty list: all features are allowed.
81 const std::string empty_list_json
= LONG_STRING_CONST(
83 "name": "gpu control list",
89 scoped_ptr
<GpuControlList
> control_list(Create());
91 EXPECT_TRUE(control_list
->LoadList(empty_list_json
,
92 GpuControlList::kAllOs
));
93 EXPECT_EQ("2.5", control_list
->version());
94 std::set
<int> features
= control_list
->MakeDecision(
95 GpuControlList::kOsMacosx
, kOsVersion
, gpu_info());
96 EXPECT_EMPTY_SET(features
);
99 TEST_F(GpuControlListTest
, DetailedEntryAndInvalidJson
) {
101 const std::string exact_list_json
= LONG_STRING_CONST(
103 "name": "gpu control list",
115 "vendor_id": "0x10de",
116 "device_id": ["0x0640"],
128 scoped_ptr
<GpuControlList
> control_list(Create());
130 EXPECT_TRUE(control_list
->LoadList(exact_list_json
, GpuControlList::kAllOs
));
131 std::set
<int> features
= control_list
->MakeDecision(
132 GpuControlList::kOsMacosx
, kOsVersion
, gpu_info());
133 EXPECT_SINGLE_FEATURE(features
, TEST_FEATURE_0
);
135 // Invalid json input should not change the current control_list settings.
136 const std::string invalid_json
= "invalid";
138 EXPECT_FALSE(control_list
->LoadList(invalid_json
, GpuControlList::kAllOs
));
139 features
= control_list
->MakeDecision(
140 GpuControlList::kOsMacosx
, kOsVersion
, gpu_info());
141 EXPECT_SINGLE_FEATURE(features
, TEST_FEATURE_0
);
142 std::vector
<uint32
> entries
;
143 control_list
->GetDecisionEntries(&entries
, false);
144 ASSERT_EQ(1u, entries
.size());
145 EXPECT_EQ(5u, entries
[0]);
146 EXPECT_EQ(5u, control_list
->max_entry_id());
149 TEST_F(GpuControlListTest
, VendorOnAllOsEntry
) {
150 // ControlList a vendor on all OS.
151 const std::string vendor_json
= LONG_STRING_CONST(
153 "name": "gpu control list",
158 "vendor_id": "0x10de",
166 scoped_ptr
<GpuControlList
> control_list(Create());
168 // ControlList entries won't be filtered to the current OS only upon loading.
169 EXPECT_TRUE(control_list
->LoadList(vendor_json
, GpuControlList::kAllOs
));
170 std::set
<int> features
= control_list
->MakeDecision(
171 GpuControlList::kOsMacosx
, kOsVersion
, gpu_info());
172 EXPECT_SINGLE_FEATURE(features
, TEST_FEATURE_0
);
173 features
= control_list
->MakeDecision(
174 GpuControlList::kOsWin
, kOsVersion
, gpu_info());
175 EXPECT_SINGLE_FEATURE(features
, TEST_FEATURE_0
);
176 features
= control_list
->MakeDecision(
177 GpuControlList::kOsLinux
, kOsVersion
, gpu_info());
178 EXPECT_SINGLE_FEATURE(features
, TEST_FEATURE_0
);
179 #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_MACOSX) || \
181 // ControlList entries will be filtered to the current OS only upon loading.
182 EXPECT_TRUE(control_list
->LoadList(
183 vendor_json
, GpuControlList::kCurrentOsOnly
));
184 features
= control_list
->MakeDecision(
185 GpuControlList::kOsMacosx
, kOsVersion
, gpu_info());
186 EXPECT_SINGLE_FEATURE(features
, TEST_FEATURE_0
);
187 features
= control_list
->MakeDecision(
188 GpuControlList::kOsWin
, kOsVersion
, gpu_info());
189 EXPECT_SINGLE_FEATURE(features
, TEST_FEATURE_0
);
190 features
= control_list
->MakeDecision(
191 GpuControlList::kOsLinux
, kOsVersion
, gpu_info());
192 EXPECT_SINGLE_FEATURE(features
, TEST_FEATURE_0
);
196 TEST_F(GpuControlListTest
, UnknownField
) {
197 const std::string unknown_field_json
= LONG_STRING_CONST(
199 "name": "gpu control list",
218 scoped_ptr
<GpuControlList
> control_list(Create());
220 EXPECT_FALSE(control_list
->LoadList(
221 unknown_field_json
, GpuControlList::kAllOs
));
224 TEST_F(GpuControlListTest
, UnknownExceptionField
) {
225 const std::string unknown_exception_field_json
= LONG_STRING_CONST(
227 "name": "gpu control list",
257 scoped_ptr
<GpuControlList
> control_list(Create());
259 EXPECT_FALSE(control_list
->LoadList(
260 unknown_exception_field_json
, GpuControlList::kAllOs
));
263 TEST_F(GpuControlListTest
, DisabledEntry
) {
264 const std::string disabled_json
= LONG_STRING_CONST(
266 "name": "gpu control list",
279 scoped_ptr
<GpuControlList
> control_list(Create());
280 EXPECT_TRUE(control_list
->LoadList(disabled_json
, GpuControlList::kAllOs
));
281 std::set
<int> features
= control_list
->MakeDecision(
282 GpuControlList::kOsWin
, kOsVersion
, gpu_info());
283 EXPECT_EMPTY_SET(features
);
284 std::vector
<uint32
> flag_entries
;
285 control_list
->GetDecisionEntries(&flag_entries
, false);
286 EXPECT_EQ(0u, flag_entries
.size());
287 control_list
->GetDecisionEntries(&flag_entries
, true);
288 EXPECT_EQ(1u, flag_entries
.size());
291 TEST_F(GpuControlListTest
, NeedsMoreInfo
) {
292 const std::string json
= LONG_STRING_CONST(
294 "name": "gpu control list",
302 "vendor_id": "0x10de",
315 gpu_info
.gpu
.vendor_id
= kNvidiaVendorId
;
317 scoped_ptr
<GpuControlList
> control_list(Create());
318 EXPECT_TRUE(control_list
->LoadList(json
, GpuControlList::kAllOs
));
320 std::set
<int> features
= control_list
->MakeDecision(
321 GpuControlList::kOsWin
, kOsVersion
, gpu_info
);
322 EXPECT_EMPTY_SET(features
);
323 EXPECT_TRUE(control_list
->needs_more_info());
324 std::vector
<uint32
> decision_entries
;
325 control_list
->GetDecisionEntries(&decision_entries
, false);
326 EXPECT_EQ(0u, decision_entries
.size());
328 gpu_info
.driver_version
= "11";
329 features
= control_list
->MakeDecision(
330 GpuControlList::kOsWin
, kOsVersion
, gpu_info
);
331 EXPECT_SINGLE_FEATURE(features
, TEST_FEATURE_0
);
332 EXPECT_FALSE(control_list
->needs_more_info());
333 control_list
->GetDecisionEntries(&decision_entries
, false);
334 EXPECT_EQ(1u, decision_entries
.size());
337 TEST_F(GpuControlListTest
, NeedsMoreInfoForExceptions
) {
338 const std::string json
= LONG_STRING_CONST(
340 "name": "gpu control list",
348 "vendor_id": "0x8086",
351 "gl_renderer": ".*mesa.*"
362 gpu_info
.gpu
.vendor_id
= kIntelVendorId
;
364 scoped_ptr
<GpuControlList
> control_list(Create());
365 EXPECT_TRUE(control_list
->LoadList(json
, GpuControlList::kAllOs
));
367 // The case this entry does not apply.
368 std::set
<int> features
= control_list
->MakeDecision(
369 GpuControlList::kOsMacosx
, kOsVersion
, gpu_info
);
370 EXPECT_EMPTY_SET(features
);
371 EXPECT_FALSE(control_list
->needs_more_info());
373 // The case this entry might apply, but need more info.
374 features
= control_list
->MakeDecision(
375 GpuControlList::kOsLinux
, kOsVersion
, gpu_info
);
376 EXPECT_EMPTY_SET(features
);
377 EXPECT_TRUE(control_list
->needs_more_info());
379 // The case we have full info, and the exception applies (so the entry
381 gpu_info
.gl_renderer
= "mesa";
382 features
= control_list
->MakeDecision(
383 GpuControlList::kOsLinux
, kOsVersion
, gpu_info
);
384 EXPECT_EMPTY_SET(features
);
385 EXPECT_FALSE(control_list
->needs_more_info());
387 // The case we have full info, and this entry applies.
388 gpu_info
.gl_renderer
= "my renderer";
389 features
= control_list
->MakeDecision(GpuControlList::kOsLinux
, kOsVersion
,
391 EXPECT_SINGLE_FEATURE(features
, TEST_FEATURE_0
);
392 EXPECT_FALSE(control_list
->needs_more_info());
395 TEST_F(GpuControlListTest
, IgnorableEntries
) {
396 // If an entry will not change the control_list decisions, then it should not
397 // trigger the needs_more_info flag.
398 const std::string json
= LONG_STRING_CONST(
400 "name": "gpu control list",
408 "vendor_id": "0x8086",
418 "vendor_id": "0x8086",
431 gpu_info
.gpu
.vendor_id
= kIntelVendorId
;
433 scoped_ptr
<GpuControlList
> control_list(Create());
434 EXPECT_TRUE(control_list
->LoadList(json
, GpuControlList::kAllOs
));
435 std::set
<int> features
= control_list
->MakeDecision(
436 GpuControlList::kOsLinux
, kOsVersion
, gpu_info
);
437 EXPECT_SINGLE_FEATURE(features
, TEST_FEATURE_0
);
438 EXPECT_FALSE(control_list
->needs_more_info());
441 TEST_F(GpuControlListTest
, ExceptionWithoutVendorId
) {
442 const std::string json
= LONG_STRING_CONST(
444 "name": "gpu control list",
452 "vendor_id": "0x8086",
455 "device_id": ["0x2a06"],
462 "device_id": ["0x2a02"],
477 gpu_info
.gpu
.vendor_id
= kIntelVendorId
;
478 gpu_info
.gpu
.device_id
= 0x2a02;
479 gpu_info
.driver_version
= "9.1";
481 scoped_ptr
<GpuControlList
> control_list(Create());
482 EXPECT_TRUE(control_list
->LoadList(json
, GpuControlList::kAllOs
));
484 std::set
<int> features
= control_list
->MakeDecision(
485 GpuControlList::kOsLinux
, kOsVersion
, gpu_info
);
486 EXPECT_EMPTY_SET(features
);
488 gpu_info
.driver_version
= "9.0";
489 features
= control_list
->MakeDecision(
490 GpuControlList::kOsLinux
, kOsVersion
, gpu_info
);
491 EXPECT_SINGLE_FEATURE(features
, TEST_FEATURE_0
);
494 TEST_F(GpuControlListTest
, AMDSwitchable
) {
496 gpu_info
.amd_switchable
= true;
497 gpu_info
.gpu
.vendor_id
= kAmdVendorId
;
498 gpu_info
.gpu
.device_id
= 0x6760;
499 GPUInfo::GPUDevice integrated_gpu
;
500 integrated_gpu
.vendor_id
= kIntelVendorId
;
501 integrated_gpu
.device_id
= 0x0116;
502 gpu_info
.secondary_gpus
.push_back(integrated_gpu
);
504 { // amd_switchable_discrete entry
505 const std::string json
= LONG_STRING_CONST(
507 "name": "gpu control list",
515 "multi_gpu_style": "amd_switchable_discrete",
524 scoped_ptr
<GpuControlList
> control_list(Create());
525 EXPECT_TRUE(control_list
->LoadList(json
, GpuControlList::kAllOs
));
527 // Integrated GPU is active
528 gpu_info
.gpu
.active
= false;
529 gpu_info
.secondary_gpus
[0].active
= true;
530 std::set
<int> features
= control_list
->MakeDecision(
531 GpuControlList::kOsWin
, kOsVersion
, gpu_info
);
532 EXPECT_EMPTY_SET(features
);
534 // Discrete GPU is active
535 gpu_info
.gpu
.active
= true;
536 gpu_info
.secondary_gpus
[0].active
= false;
537 features
= control_list
->MakeDecision(
538 GpuControlList::kOsWin
, kOsVersion
, gpu_info
);
539 EXPECT_SINGLE_FEATURE(features
, TEST_FEATURE_0
);
542 { // amd_switchable_integrated entry
543 const std::string json
= LONG_STRING_CONST(
545 "name": "gpu control list",
553 "multi_gpu_style": "amd_switchable_integrated",
562 scoped_ptr
<GpuControlList
> control_list(Create());
563 EXPECT_TRUE(control_list
->LoadList(json
, GpuControlList::kAllOs
));
565 // Discrete GPU is active
566 gpu_info
.gpu
.active
= true;
567 gpu_info
.secondary_gpus
[0].active
= false;
568 std::set
<int> features
= control_list
->MakeDecision(
569 GpuControlList::kOsWin
, kOsVersion
, gpu_info
);
570 EXPECT_EMPTY_SET(features
);
572 // Integrated GPU is active
573 gpu_info
.gpu
.active
= false;
574 gpu_info
.secondary_gpus
[0].active
= true;
575 features
= control_list
->MakeDecision(
576 GpuControlList::kOsWin
, kOsVersion
, gpu_info
);
577 EXPECT_SINGLE_FEATURE(features
, TEST_FEATURE_0
);
579 // For non AMD switchable
580 gpu_info
.amd_switchable
= false;
581 features
= control_list
->MakeDecision(
582 GpuControlList::kOsWin
, kOsVersion
, gpu_info
);
583 EXPECT_EMPTY_SET(features
);