1 // Copyright (c) 2012 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 "gpu/config/gpu_test_config.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include "base/logging.h"
11 #include "base/system/sys_info.h"
12 #include "build/build_config.h"
13 #include "gpu/config/gpu_info.h"
14 #include "gpu/config/gpu_info_collector.h"
15 #include "gpu/config/gpu_test_expectations_parser.h"
16
17 #if defined(OS_WIN)
18 #include "base/win/windows_version.h"
19 #endif
20
21 namespace gpu {
22
23 namespace {
24
GetCurrentOS()25 GPUTestConfig::OS GetCurrentOS() {
26 #if defined(OS_CHROMEOS)
27 return GPUTestConfig::kOsChromeOS;
28 #elif defined(OS_LINUX) || defined(OS_BSD)
29 return GPUTestConfig::kOsLinux;
30 #elif defined(OS_WIN)
31 int32_t major_version = 0;
32 int32_t minor_version = 0;
33 int32_t bugfix_version = 0;
34 base::SysInfo::OperatingSystemVersionNumbers(
35 &major_version, &minor_version, &bugfix_version);
36 if (major_version == 5)
37 return GPUTestConfig::kOsWinXP;
38 if (major_version == 6 && minor_version == 0)
39 return GPUTestConfig::kOsWinVista;
40 if (major_version == 6 && minor_version == 1)
41 return GPUTestConfig::kOsWin7;
42 if (major_version == 6 && (minor_version == 2 || minor_version == 3))
43 return GPUTestConfig::kOsWin8;
44 if (major_version == 10)
45 return GPUTestConfig::kOsWin10;
46 return GPUTestConfig::kOsUnknown;
47 #elif defined(OS_MACOSX)
48 int32_t major_version = 0;
49 int32_t minor_version = 0;
50 int32_t bugfix_version = 0;
51 base::SysInfo::OperatingSystemVersionNumbers(
52 &major_version, &minor_version, &bugfix_version);
53 if (major_version == 10) {
54 switch (minor_version) {
55 case 5:
56 return GPUTestConfig::kOsMacLeopard;
57 case 6:
58 return GPUTestConfig::kOsMacSnowLeopard;
59 case 7:
60 return GPUTestConfig::kOsMacLion;
61 case 8:
62 return GPUTestConfig::kOsMacMountainLion;
63 case 9:
64 return GPUTestConfig::kOsMacMavericks;
65 case 10:
66 return GPUTestConfig::kOsMacYosemite;
67 case 11:
68 return GPUTestConfig::kOsMacElCapitan;
69 case 12:
70 return GPUTestConfig::kOsMacSierra;
71 case 13:
72 return GPUTestConfig::kOsMacHighSierra;
73 case 14:
74 return GPUTestConfig::kOsMacMojave;
75 case 15:
76 return GPUTestConfig::kOsMacCatalina;
77 }
78 }
79 return GPUTestConfig::kOsUnknown;
80 #elif defined(OS_ANDROID)
81 return GPUTestConfig::kOsAndroid;
82 #elif defined(OS_FUCHSIA)
83 return GPUTestConfig::kOsFuchsia;
84 #else
85 #error "unknown os"
86 #endif
87 }
88
89 } // namespace anonymous
90
GPUTestConfig()91 GPUTestConfig::GPUTestConfig()
92 : os_(kOsUnknown),
93 gpu_device_id_(0),
94 build_type_(kBuildTypeUnknown),
95 api_(kAPIUnknown) {}
96
97 GPUTestConfig::GPUTestConfig(const GPUTestConfig& other) = default;
98
99 GPUTestConfig::~GPUTestConfig() = default;
100
set_os(int32_t os)101 void GPUTestConfig::set_os(int32_t os) {
102 DCHECK_EQ(0, os & ~(kOsAndroid | kOsWin | kOsMac | kOsLinux | kOsChromeOS |
103 kOsFuchsia));
104 os_ = os;
105 }
106
AddGPUVendor(uint32_t gpu_vendor)107 void GPUTestConfig::AddGPUVendor(uint32_t gpu_vendor) {
108 DCHECK_NE(0u, gpu_vendor);
109 for (size_t i = 0; i < gpu_vendor_.size(); ++i)
110 DCHECK_NE(gpu_vendor_[i], gpu_vendor);
111 gpu_vendor_.push_back(gpu_vendor);
112 }
113
set_gpu_device_id(uint32_t id)114 void GPUTestConfig::set_gpu_device_id(uint32_t id) {
115 gpu_device_id_ = id;
116 }
117
set_build_type(int32_t build_type)118 void GPUTestConfig::set_build_type(int32_t build_type) {
119 DCHECK_EQ(0, build_type & ~(kBuildTypeRelease | kBuildTypeDebug));
120 build_type_ = build_type;
121 }
122
set_api(int32_t api)123 void GPUTestConfig::set_api(int32_t api) {
124 DCHECK_EQ(0, api & ~(kAPID3D9 | kAPID3D11 | kAPIGLDesktop | kAPIGLES));
125 api_ = api;
126 }
127
IsValid() const128 bool GPUTestConfig::IsValid() const {
129 if (gpu_device_id_ != 0 && (gpu_vendor_.size() != 1 || gpu_vendor_[0] == 0))
130 return false;
131 return true;
132 }
133
OverlapsWith(const GPUTestConfig & config) const134 bool GPUTestConfig::OverlapsWith(const GPUTestConfig& config) const {
135 DCHECK(IsValid());
136 DCHECK(config.IsValid());
137 if (config.os_ != kOsUnknown && os_ != kOsUnknown &&
138 (os_ & config.os_) == 0)
139 return false;
140 if (config.gpu_vendor_.size() > 0 && gpu_vendor_.size() > 0) {
141 bool shared = false;
142 for (size_t i = 0; i < config.gpu_vendor_.size() && !shared; ++i) {
143 for (size_t j = 0; j < gpu_vendor_.size(); ++j) {
144 if (config.gpu_vendor_[i] == gpu_vendor_[j]) {
145 shared = true;
146 break;
147 }
148 }
149 }
150 if (!shared)
151 return false;
152 }
153 if (config.gpu_device_id_ != 0 && gpu_device_id_ != 0 &&
154 gpu_device_id_ != config.gpu_device_id_)
155 return false;
156 if (config.build_type_ != kBuildTypeUnknown &&
157 build_type_ != kBuildTypeUnknown &&
158 (build_type_ & config.build_type_) == 0)
159 return false;
160 if (config.api() != kAPIUnknown && api_ != kAPIUnknown && api_ != config.api_)
161 return false;
162 return true;
163 }
164
ClearGPUVendor()165 void GPUTestConfig::ClearGPUVendor() {
166 gpu_vendor_.clear();
167 }
168
169 GPUTestBotConfig::~GPUTestBotConfig() = default;
170
AddGPUVendor(uint32_t gpu_vendor)171 void GPUTestBotConfig::AddGPUVendor(uint32_t gpu_vendor) {
172 DCHECK_EQ(0u, GPUTestConfig::gpu_vendor().size());
173 GPUTestConfig::AddGPUVendor(gpu_vendor);
174 }
175
SetGPUInfo(const GPUInfo & gpu_info)176 bool GPUTestBotConfig::SetGPUInfo(const GPUInfo& gpu_info) {
177 if (gpu_info.gpu.device_id == 0 || gpu_info.gpu.vendor_id == 0)
178 return false;
179 ClearGPUVendor();
180 AddGPUVendor(gpu_info.gpu.vendor_id);
181 set_gpu_device_id(gpu_info.gpu.device_id);
182 return true;
183 }
184
IsValid() const185 bool GPUTestBotConfig::IsValid() const {
186 switch (os()) {
187 case kOsWinXP:
188 case kOsWinVista:
189 case kOsWin7:
190 case kOsWin8:
191 case kOsWin10:
192 case kOsMacLeopard:
193 case kOsMacSnowLeopard:
194 case kOsMacLion:
195 case kOsMacMountainLion:
196 case kOsMacMavericks:
197 case kOsMacYosemite:
198 case kOsMacElCapitan:
199 case kOsMacSierra:
200 case kOsMacHighSierra:
201 case kOsMacMojave:
202 case kOsMacCatalina:
203 case kOsLinux:
204 case kOsChromeOS:
205 case kOsAndroid:
206 case kOsFuchsia:
207 break;
208 default:
209 return false;
210 }
211 if (gpu_vendor().size() != 1 || gpu_vendor()[0] == 0)
212 return false;
213 if (gpu_device_id() == 0)
214 return false;
215 switch (build_type()) {
216 case kBuildTypeRelease:
217 case kBuildTypeDebug:
218 break;
219 default:
220 return false;
221 }
222 return true;
223 }
224
Matches(const GPUTestConfig & config) const225 bool GPUTestBotConfig::Matches(const GPUTestConfig& config) const {
226 DCHECK(IsValid());
227 DCHECK(config.IsValid());
228 if (config.os() != kOsUnknown && (os() & config.os()) == 0)
229 return false;
230 if (config.gpu_vendor().size() > 0) {
231 bool contained = false;
232 for (size_t i = 0; i < config.gpu_vendor().size(); ++i) {
233 if (config.gpu_vendor()[i] == gpu_vendor()[0]) {
234 contained = true;
235 break;
236 }
237 }
238 if (!contained)
239 return false;
240 }
241 if (config.gpu_device_id() != 0 &&
242 gpu_device_id() != config.gpu_device_id())
243 return false;
244 if (config.build_type() != kBuildTypeUnknown &&
245 (build_type() & config.build_type()) == 0)
246 return false;
247 if (config.api() != 0 && (api() & config.api()) == 0)
248 return false;
249 return true;
250 }
251
Matches(const std::string & config_data) const252 bool GPUTestBotConfig::Matches(const std::string& config_data) const {
253 GPUTestExpectationsParser parser;
254 GPUTestConfig config;
255
256 if (!parser.ParseConfig(config_data, &config))
257 return false;
258 return Matches(config);
259 }
260
LoadCurrentConfig(const GPUInfo * gpu_info)261 bool GPUTestBotConfig::LoadCurrentConfig(const GPUInfo* gpu_info) {
262 bool rt;
263 if (!gpu_info) {
264 #if defined(OS_ANDROID)
265 // TODO(zmo): Implement this.
266 rt = false;
267 #else
268 GPUInfo my_gpu_info;
269 if (!CollectBasicGraphicsInfo(&my_gpu_info)) {
270 LOG(ERROR) << "Fail to identify GPU";
271 rt = false;
272 } else {
273 rt = SetGPUInfo(my_gpu_info);
274 }
275 #endif // OS_ANDROID
276 } else {
277 rt = SetGPUInfo(*gpu_info);
278 }
279 set_os(GetCurrentOS());
280 if (os() == kOsUnknown) {
281 LOG(ERROR) << "Unknown OS";
282 rt = false;
283 }
284 #if defined(NDEBUG)
285 set_build_type(kBuildTypeRelease);
286 #else
287 set_build_type(kBuildTypeDebug);
288 #endif
289 return rt;
290 }
291
292 // static
CurrentConfigMatches(const std::string & config_data)293 bool GPUTestBotConfig::CurrentConfigMatches(const std::string& config_data) {
294 GPUTestBotConfig my_config;
295 if (!my_config.LoadCurrentConfig(nullptr))
296 return false;
297 return my_config.Matches(config_data);
298 }
299
300 // static
CurrentConfigMatches(const std::vector<std::string> & configs)301 bool GPUTestBotConfig::CurrentConfigMatches(
302 const std::vector<std::string>& configs) {
303 GPUTestBotConfig my_config;
304 if (!my_config.LoadCurrentConfig(nullptr))
305 return false;
306 for (size_t i = 0 ; i < configs.size(); ++i) {
307 if (my_config.Matches(configs[i]))
308 return true;
309 }
310 return false;
311 }
312
313 // static
GpuBlacklistedOnBot()314 bool GPUTestBotConfig::GpuBlacklistedOnBot() {
315 return false;
316 }
317
318 } // namespace gpu
319