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 "base/logging.h"
8#include "base/sys_info.h"
9#include "gpu/config/gpu_info.h"
10#include "gpu/config/gpu_info_collector.h"
11#include "gpu/config/gpu_test_expectations_parser.h"
12
13namespace gpu {
14
15namespace {
16
17GPUTestConfig::OS GetCurrentOS() {
18#if defined(OS_CHROMEOS)
19  return GPUTestConfig::kOsChromeOS;
20#elif defined(OS_LINUX) || defined(OS_OPENBSD)
21  return GPUTestConfig::kOsLinux;
22#elif defined(OS_WIN)
23  int32 major_version = 0;
24  int32 minor_version = 0;
25  int32 bugfix_version = 0;
26  base::SysInfo::OperatingSystemVersionNumbers(
27      &major_version, &minor_version, &bugfix_version);
28  if (major_version == 5)
29    return GPUTestConfig::kOsWinXP;
30  if (major_version == 6 && minor_version == 0)
31    return GPUTestConfig::kOsWinVista;
32  if (major_version == 6 && minor_version == 1)
33    return GPUTestConfig::kOsWin7;
34  if (major_version == 6 && minor_version == 2)
35    return GPUTestConfig::kOsWin8;
36#elif defined(OS_MACOSX)
37  int32 major_version = 0;
38  int32 minor_version = 0;
39  int32 bugfix_version = 0;
40  base::SysInfo::OperatingSystemVersionNumbers(
41      &major_version, &minor_version, &bugfix_version);
42  if (major_version == 10) {
43    switch (minor_version) {
44      case 5:
45        return GPUTestConfig::kOsMacLeopard;
46      case 6:
47        return GPUTestConfig::kOsMacSnowLeopard;
48      case 7:
49        return GPUTestConfig::kOsMacLion;
50      case 8:
51        return GPUTestConfig::kOsMacMountainLion;
52    }
53  }
54#elif defined(OS_ANDROID)
55  return GPUTestConfig::kOsAndroid;
56#endif
57  return GPUTestConfig::kOsUnknown;
58}
59
60}  // namespace anonymous
61
62GPUTestConfig::GPUTestConfig()
63    : validate_gpu_info_(true),
64      os_(kOsUnknown),
65      gpu_device_id_(0),
66      build_type_(kBuildTypeUnknown) {
67}
68
69GPUTestConfig::~GPUTestConfig() {
70}
71
72void GPUTestConfig::set_os(int32 os) {
73  DCHECK_EQ(0, os & ~(kOsAndroid | kOsWin | kOsMac | kOsLinux | kOsChromeOS));
74  os_ = os;
75}
76
77void GPUTestConfig::AddGPUVendor(uint32 gpu_vendor) {
78  DCHECK_NE(0u, gpu_vendor);
79  for (size_t i = 0; i < gpu_vendor_.size(); ++i)
80    DCHECK_NE(gpu_vendor_[i], gpu_vendor);
81  gpu_vendor_.push_back(gpu_vendor);
82}
83
84void GPUTestConfig::set_gpu_device_id(uint32 id) {
85  gpu_device_id_ = id;
86}
87
88void GPUTestConfig::set_build_type(int32 build_type) {
89  DCHECK_EQ(0, build_type & ~(kBuildTypeRelease | kBuildTypeDebug));
90  build_type_ = build_type;
91}
92
93bool GPUTestConfig::IsValid() const {
94  if (!validate_gpu_info_)
95    return true;
96  if (gpu_device_id_ != 0 && (gpu_vendor_.size() != 1 || gpu_vendor_[0] == 0))
97    return false;
98  return true;
99}
100
101bool GPUTestConfig::OverlapsWith(const GPUTestConfig& config) const {
102  DCHECK(IsValid());
103  DCHECK(config.IsValid());
104  if (config.os_ != kOsUnknown && os_ != kOsUnknown &&
105      (os_ & config.os_) == 0)
106    return false;
107  if (config.gpu_vendor_.size() > 0 && gpu_vendor_.size() > 0) {
108    bool shared = false;
109    for (size_t i = 0; i < config.gpu_vendor_.size() && !shared; ++i) {
110      for (size_t j = 0; j < gpu_vendor_.size(); ++j) {
111        if (config.gpu_vendor_[i] == gpu_vendor_[j]) {
112          shared = true;
113          break;
114        }
115      }
116    }
117    if (!shared)
118      return false;
119  }
120  if (config.gpu_device_id_ != 0 && gpu_device_id_ != 0 &&
121      gpu_device_id_ != config.gpu_device_id_)
122    return false;
123  if (config.build_type_ != kBuildTypeUnknown &&
124      build_type_ != kBuildTypeUnknown &&
125      (build_type_ & config.build_type_) == 0)
126    return false;
127  return true;
128}
129
130void GPUTestConfig::DisableGPUInfoValidation() {
131  validate_gpu_info_ = false;
132}
133
134void GPUTestConfig::ClearGPUVendor() {
135  gpu_vendor_.clear();
136}
137
138GPUTestBotConfig::~GPUTestBotConfig() {
139}
140
141void GPUTestBotConfig::AddGPUVendor(uint32 gpu_vendor) {
142  DCHECK_EQ(0u, GPUTestConfig::gpu_vendor().size());
143  GPUTestConfig::AddGPUVendor(gpu_vendor);
144}
145
146bool GPUTestBotConfig::SetGPUInfo(const GPUInfo& gpu_info) {
147  DCHECK(validate_gpu_info_);
148  if (gpu_info.gpu.device_id == 0 || gpu_info.gpu.vendor_id == 0)
149    return false;
150  ClearGPUVendor();
151  AddGPUVendor(gpu_info.gpu.vendor_id);
152  set_gpu_device_id(gpu_info.gpu.device_id);
153  return true;
154}
155
156bool GPUTestBotConfig::IsValid() const {
157  switch (os()) {
158    case kOsWinXP:
159    case kOsWinVista:
160    case kOsWin7:
161    case kOsWin8:
162    case kOsMacLeopard:
163    case kOsMacSnowLeopard:
164    case kOsMacLion:
165    case kOsMacMountainLion:
166    case kOsLinux:
167    case kOsChromeOS:
168    case kOsAndroid:
169      break;
170    default:
171      return false;
172  }
173  if (validate_gpu_info_) {
174    if (gpu_vendor().size() != 1 || gpu_vendor()[0] == 0)
175      return false;
176    if (gpu_device_id() == 0)
177      return false;
178  }
179  switch (build_type()) {
180    case kBuildTypeRelease:
181    case kBuildTypeDebug:
182      break;
183    default:
184      return false;
185  }
186  return true;
187}
188
189bool GPUTestBotConfig::Matches(const GPUTestConfig& config) const {
190  DCHECK(IsValid());
191  DCHECK(config.IsValid());
192  if (config.os() != kOsUnknown && (os() & config.os()) == 0)
193    return false;
194  if (config.gpu_vendor().size() > 0) {
195    bool contained = false;
196    for (size_t i = 0; i < config.gpu_vendor().size(); ++i) {
197      if (config.gpu_vendor()[i] == gpu_vendor()[0]) {
198        contained = true;
199        break;
200      }
201    }
202    if (!contained)
203      return false;
204  }
205  if (config.gpu_device_id() != 0 &&
206      gpu_device_id() != config.gpu_device_id())
207    return false;
208  if (config.build_type() != kBuildTypeUnknown &&
209      (build_type() & config.build_type()) == 0)
210    return false;
211  return true;
212}
213
214bool GPUTestBotConfig::Matches(const std::string& config_data) const {
215  GPUTestExpectationsParser parser;
216  GPUTestConfig config;
217
218  if (!parser.ParseConfig(config_data, &config))
219    return false;
220  return Matches(config);
221}
222
223bool GPUTestBotConfig::LoadCurrentConfig(const GPUInfo* gpu_info) {
224  bool rt;
225  if (gpu_info == NULL) {
226    GPUInfo my_gpu_info;
227    GpuIDResult result;
228    result = CollectGpuID(&my_gpu_info.gpu.vendor_id,
229                          &my_gpu_info.gpu.device_id);
230    if (result == kGpuIDNotSupported) {
231      DisableGPUInfoValidation();
232      rt = true;
233    } else {
234      rt = SetGPUInfo(my_gpu_info);
235    }
236  } else {
237    rt = SetGPUInfo(*gpu_info);
238  }
239  set_os(GetCurrentOS());
240  if (os() == kOsUnknown)
241    rt = false;
242#if defined(NDEBUG)
243  set_build_type(kBuildTypeRelease);
244#else
245  set_build_type(kBuildTypeDebug);
246#endif
247  return rt;
248}
249
250// static
251bool GPUTestBotConfig::CurrentConfigMatches(const std::string& config_data) {
252  GPUTestBotConfig my_config;
253  if (!my_config.LoadCurrentConfig(NULL))
254    return false;
255  return my_config.Matches(config_data);
256}
257
258// static
259bool GPUTestBotConfig::CurrentConfigMatches(
260    const std::vector<std::string>& configs) {
261  GPUTestBotConfig my_config;
262  if (!my_config.LoadCurrentConfig(NULL))
263    return false;
264  for (size_t i = 0 ; i < configs.size(); ++i) {
265    if (my_config.Matches(configs[i]))
266      return true;
267  }
268  return false;
269}
270
271}  // namespace gpu
272
273