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 <stdint.h>
6 
7 #include <memory>
8 #include <vector>
9 
10 #include "gpu/config/gpu_control_list.h"
11 #include "gpu/config/gpu_control_list_testing_data.h"
12 #include "gpu/config/gpu_info.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 
15 const char kOsVersion[] = "10.6.4";
16 const uint32_t kIntelVendorId = 0x8086;
17 const uint32_t kNvidiaVendorId = 0x10de;
18 
19 #define LONG_STRING_CONST(...) #__VA_ARGS__
20 
21 #define EXPECT_EMPTY_SET(feature_set) EXPECT_EQ(0u, feature_set.size())
22 #define EXPECT_SINGLE_FEATURE(feature_set, feature) \
23     EXPECT_TRUE(feature_set.size() == 1 && feature_set.count(feature) == 1)
24 
25 namespace gpu {
26 
27 class GpuControlListTest : public testing::Test {
28  public:
29   typedef GpuControlList::Entry Entry;
30 
31   GpuControlListTest() = default;
32   ~GpuControlListTest() override = default;
33 
gpu_info() const34   const GPUInfo& gpu_info() const {
35     return gpu_info_;
36   }
37 
Create(size_t entry_count,const Entry * entries)38   std::unique_ptr<GpuControlList> Create(size_t entry_count,
39                                          const Entry* entries) {
40     GpuControlListData data(entry_count, entries);
41     std::unique_ptr<GpuControlList> rt(new GpuControlList(data));
42     rt->AddSupportedFeature("test_feature_0", TEST_FEATURE_0);
43     rt->AddSupportedFeature("test_feature_1", TEST_FEATURE_1);
44     rt->AddSupportedFeature("test_feature_2", TEST_FEATURE_2);
45     return rt;
46   }
47 
48  protected:
SetUp()49   void SetUp() override {
50     gpu_info_.gpu.vendor_id = kNvidiaVendorId;
51     gpu_info_.gpu.device_id = 0x0640;
52     gpu_info_.gpu.driver_vendor = "NVIDIA";
53     gpu_info_.gpu.driver_version = "1.6.18";
54     gpu_info_.machine_model_name = "MacBookPro";
55     gpu_info_.machine_model_version = "7.1";
56     gpu_info_.gl_vendor = "NVIDIA Corporation";
57     gpu_info_.gl_renderer = "NVIDIA GeForce GT 120 OpenGL Engine";
58   }
59 
TearDown()60   void TearDown() override {}
61 
62  private:
63   GPUInfo gpu_info_;
64 };
65 
TEST_F(GpuControlListTest,NeedsMoreInfo)66 TEST_F(GpuControlListTest, NeedsMoreInfo) {
67   const Entry kEntries[1] = {
68       kGpuControlListTestingEntries[kGpuControlListTest_NeedsMoreInfo]};
69   std::unique_ptr<GpuControlList> control_list = Create(1, kEntries);
70 
71   GPUInfo gpu_info;
72   gpu_info.gpu.vendor_id = kNvidiaVendorId;
73 
74   std::set<int> features = control_list->MakeDecision(
75       GpuControlList::kOsWin, kOsVersion, gpu_info);
76   EXPECT_EMPTY_SET(features);
77   EXPECT_TRUE(control_list->needs_more_info());
78   std::vector<uint32_t> decision_entries = control_list->GetActiveEntries();
79   EXPECT_EQ(0u, decision_entries.size());
80 
81   gpu_info.gpu.driver_version = "11";
82   features = control_list->MakeDecision(
83       GpuControlList::kOsWin, kOsVersion, gpu_info);
84   EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
85   EXPECT_FALSE(control_list->needs_more_info());
86   decision_entries = control_list->GetActiveEntries();
87   EXPECT_EQ(1u, decision_entries.size());
88   EXPECT_EQ(0u, decision_entries[0]);
89   std::vector<uint32_t> entry_ids =
90       control_list->GetEntryIDsFromIndices(decision_entries);
91   EXPECT_EQ(1u, entry_ids.size());
92   EXPECT_EQ(static_cast<uint32_t>(kGpuControlListTest_NeedsMoreInfo + 1),
93             entry_ids[0]);
94 }
95 
TEST_F(GpuControlListTest,NeedsMoreInfoForExceptions)96 TEST_F(GpuControlListTest, NeedsMoreInfoForExceptions) {
97   const Entry kEntries[1] = {
98       kGpuControlListTestingEntries
99           [kGpuControlListTest_NeedsMoreInfoForExceptions]};
100   std::unique_ptr<GpuControlList> control_list = Create(1, kEntries);
101 
102   GPUInfo gpu_info;
103   gpu_info.gpu.vendor_id = kIntelVendorId;
104 
105   // The case this entry does not apply.
106   std::set<int> features = control_list->MakeDecision(
107       GpuControlList::kOsMacosx, kOsVersion, gpu_info);
108   EXPECT_EMPTY_SET(features);
109   EXPECT_FALSE(control_list->needs_more_info());
110 
111   // The case this entry might apply, but need more info.
112   features = control_list->MakeDecision(
113       GpuControlList::kOsLinux, kOsVersion, gpu_info);
114   // Ignore exceptions if main entry info matches
115   EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
116   EXPECT_TRUE(control_list->needs_more_info());
117 
118   // The case we have full info, and the exception applies (so the entry
119   // does not apply).
120   gpu_info.gl_renderer = "mesa";
121   features = control_list->MakeDecision(
122       GpuControlList::kOsLinux, kOsVersion, gpu_info);
123   EXPECT_EMPTY_SET(features);
124   EXPECT_FALSE(control_list->needs_more_info());
125 
126   // The case we have full info, and this entry applies.
127   gpu_info.gl_renderer = "my renderer";
128   features = control_list->MakeDecision(GpuControlList::kOsLinux, kOsVersion,
129       gpu_info);
130   EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
131   EXPECT_FALSE(control_list->needs_more_info());
132 }
133 
TEST_F(GpuControlListTest,IgnorableEntries)134 TEST_F(GpuControlListTest, IgnorableEntries) {
135   // If an entry will not change the control_list decisions, then it should not
136   // trigger the needs_more_info flag.
137   const Entry kEntries[2] = {
138       kGpuControlListTestingEntries[kGpuControlListTest_IgnorableEntries_0],
139       kGpuControlListTestingEntries[kGpuControlListTest_IgnorableEntries_1]};
140   std::unique_ptr<GpuControlList> control_list = Create(2, kEntries);
141 
142   GPUInfo gpu_info;
143   gpu_info.gpu.vendor_id = kIntelVendorId;
144 
145   std::set<int> features = control_list->MakeDecision(
146       GpuControlList::kOsLinux, kOsVersion, gpu_info);
147   EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
148   EXPECT_FALSE(control_list->needs_more_info());
149 }
150 
TEST_F(GpuControlListTest,DisabledExtensionTest)151 TEST_F(GpuControlListTest, DisabledExtensionTest) {
152   // exact setting.
153   const Entry kEntries[2] = {kGpuControlListTestingEntries
154                                  [kGpuControlListTest_DisabledExtensionTest_0],
155                              kGpuControlListTestingEntries
156                                  [kGpuControlListTest_DisabledExtensionTest_1]};
157   std::unique_ptr<GpuControlList> control_list = Create(2, kEntries);
158 
159   GPUInfo gpu_info;
160   control_list->MakeDecision(GpuControlList::kOsWin, kOsVersion, gpu_info);
161 
162   std::vector<std::string> disabled_extensions =
163       control_list->GetDisabledExtensions();
164 
165   ASSERT_EQ(3u, disabled_extensions.size());
166   ASSERT_STREQ("test_extension1", disabled_extensions[0].c_str());
167   ASSERT_STREQ("test_extension2", disabled_extensions[1].c_str());
168   ASSERT_STREQ("test_extension3", disabled_extensions[2].c_str());
169 }
170 
TEST_F(GpuControlListTest,LinuxKernelVersion)171 TEST_F(GpuControlListTest, LinuxKernelVersion) {
172   const Entry kEntries[1] = {
173       kGpuControlListTestingEntries[kGpuControlListTest_LinuxKernelVersion]};
174   std::unique_ptr<GpuControlList> control_list = Create(1, kEntries);
175 
176   GPUInfo gpu_info;
177   gpu_info.gpu.vendor_id = 0x8086;
178 
179   std::set<int> features = control_list->MakeDecision(
180       GpuControlList::kOsLinux, "3.13.0-63-generic", gpu_info);
181   EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
182 
183   features = control_list->MakeDecision(GpuControlList::kOsLinux,
184                                         "3.19.2-1-generic", gpu_info);
185   EXPECT_EMPTY_SET(features);
186 }
187 
TEST_F(GpuControlListTest,TestGroup)188 TEST_F(GpuControlListTest, TestGroup) {
189   const Entry kEntries[3] = {
190       kGpuControlListTestingEntries[kGpuControlListTest_LinuxKernelVersion],
191       kGpuControlListTestingEntries[kGpuControlListTest_TestGroup_0],
192       kGpuControlListTestingEntries[kGpuControlListTest_TestGroup_1]};
193   std::unique_ptr<GpuControlList> control_list = Create(3, kEntries);
194   GPUInfo gpu_info;
195 
196   // Default test group.
197   std::set<int> features = control_list->MakeDecision(
198       GpuControlList::kOsLinux, "3.13.2-1-generic", gpu_info);
199   EXPECT_EMPTY_SET(features);
200 
201   // Test group 0, the default test group
202   features = control_list->MakeDecision(GpuControlList::kOsLinux,
203                                         "3.13.2-1-generic", gpu_info, 0);
204   EXPECT_EMPTY_SET(features);
205 
206   // Test group 1.
207   features = control_list->MakeDecision(GpuControlList::kOsLinux,
208                                         "3.13.2-1-generic", gpu_info, 1);
209   EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
210 
211   // Test group 2.
212   features = control_list->MakeDecision(GpuControlList::kOsLinux,
213                                         "3.13.2-1-generic", gpu_info, 2);
214   EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_1);
215 }
216 
217 }  // namespace gpu
218