gpu_info_collector_unittest.cc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  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. #include "gpu/config/gpu_info_collector.h"
  5. #include <stddef.h>
  6. #include <stdint.h>
  7. #include <memory>
  8. #include <string>
  9. #include <vector>
  10. #include "base/memory/raw_ptr.h"
  11. #include "base/strings/string_split.h"
  12. #include "build/build_config.h"
  13. #include "gpu/config/gpu_info.h"
  14. #include "testing/gmock/include/gmock/gmock.h"
  15. #include "testing/gtest/include/gtest/gtest.h"
  16. #include "ui/gl/gl_context_stub.h"
  17. #include "ui/gl/gl_display.h"
  18. #include "ui/gl/gl_implementation.h"
  19. #include "ui/gl/gl_mock.h"
  20. #include "ui/gl/gl_surface_stub.h"
  21. #include "ui/gl/gl_utils.h"
  22. #include "ui/gl/init/gl_factory.h"
  23. #include "ui/gl/test/gl_surface_test_support.h"
  24. using ::gl::MockGLInterface;
  25. using ::testing::Return;
  26. using ::testing::SetArgPointee;
  27. using ::testing::_;
  28. namespace {
  29. // Allows testing of all configurations on all operating systems.
  30. enum MockedOperatingSystemKind {
  31. kMockedAndroid,
  32. kMockedLinux,
  33. kMockedMacOSX,
  34. kMockedWindows
  35. };
  36. } // anonymous namespace
  37. namespace gpu {
  38. static const MockedOperatingSystemKind kMockedOperatingSystemKinds[] = {
  39. kMockedAndroid,
  40. kMockedLinux,
  41. kMockedMacOSX,
  42. kMockedWindows
  43. };
  44. class GPUInfoCollectorTest
  45. : public testing::Test,
  46. public ::testing::WithParamInterface<MockedOperatingSystemKind> {
  47. public:
  48. GPUInfoCollectorTest() = default;
  49. ~GPUInfoCollectorTest() override = default;
  50. void SetUp() override {
  51. testing::Test::SetUp();
  52. gl::SetGLGetProcAddressProc(gl::MockGLInterface::GetGLProcAddress);
  53. display_ = gl::GLSurfaceTestSupport::InitializeOneOffWithMockBindings();
  54. gl_ = std::make_unique<::testing::StrictMock<::gl::MockGLInterface>>();
  55. ::gl::MockGLInterface::SetGLInterface(gl_.get());
  56. switch (GetParam()) {
  57. case kMockedAndroid: {
  58. test_values_.gpu.vendor_id = 0; // not implemented
  59. test_values_.gpu.device_id = 0; // not implemented
  60. test_values_.gpu.driver_vendor = ""; // not implemented
  61. test_values_.gpu.driver_version = "14.0";
  62. test_values_.pixel_shader_version = "1.00";
  63. test_values_.vertex_shader_version = "1.00";
  64. test_values_.gl_renderer = "Adreno (TM) 320";
  65. test_values_.gl_vendor = "Qualcomm";
  66. test_values_.gl_version = "OpenGL ES 2.0 V@14.0 AU@04.02 (CL@3206)";
  67. test_values_.gl_extensions =
  68. "GL_OES_packed_depth_stencil GL_EXT_texture_format_BGRA8888 "
  69. "GL_EXT_read_format_bgra GL_EXT_multisampled_render_to_texture";
  70. gl_shading_language_version_ = "1.00";
  71. break;
  72. }
  73. case kMockedLinux: {
  74. test_values_.gpu.vendor_id = 0x10de;
  75. test_values_.gpu.device_id = 0x0658;
  76. test_values_.gpu.driver_vendor = "NVIDIA";
  77. test_values_.gpu.driver_version = "195.36.24";
  78. test_values_.pixel_shader_version = "1.50";
  79. test_values_.vertex_shader_version = "1.50";
  80. test_values_.gl_renderer = "Quadro FX 380/PCI/SSE2";
  81. test_values_.gl_vendor = "NVIDIA Corporation";
  82. test_values_.gl_version = "3.2.0 NVIDIA 195.36.24";
  83. test_values_.gl_extensions =
  84. "GL_OES_packed_depth_stencil GL_EXT_texture_format_BGRA8888 "
  85. "GL_EXT_read_format_bgra";
  86. gl_shading_language_version_ = "1.50 NVIDIA via Cg compiler";
  87. break;
  88. }
  89. case kMockedMacOSX: {
  90. test_values_.gpu.vendor_id = 0x10de;
  91. test_values_.gpu.device_id = 0x0640;
  92. test_values_.gpu.driver_vendor = "NVIDIA";
  93. test_values_.gpu.driver_version = "1.6.18";
  94. test_values_.pixel_shader_version = "1.20";
  95. test_values_.vertex_shader_version = "1.20";
  96. test_values_.gl_renderer = "NVIDIA GeForce GT 120 OpenGL Engine";
  97. test_values_.gl_vendor = "NVIDIA Corporation";
  98. test_values_.gl_version = "2.1 NVIDIA-1.6.18";
  99. test_values_.gl_extensions =
  100. "GL_OES_packed_depth_stencil GL_EXT_texture_format_BGRA8888 "
  101. "GL_EXT_read_format_bgra GL_EXT_framebuffer_multisample";
  102. gl_shading_language_version_ = "1.20 ";
  103. break;
  104. }
  105. case kMockedWindows: {
  106. test_values_.gpu.vendor_id = 0x10de;
  107. test_values_.gpu.device_id = 0x0658;
  108. test_values_.gpu.driver_vendor = ""; // not implemented
  109. test_values_.gpu.driver_version = "";
  110. test_values_.pixel_shader_version = "1.40";
  111. test_values_.vertex_shader_version = "1.40";
  112. test_values_.gl_renderer = "Quadro FX 380/PCI/SSE2";
  113. test_values_.gl_vendor = "NVIDIA Corporation";
  114. test_values_.gl_version = "3.1.0";
  115. test_values_.gl_extensions =
  116. "GL_OES_packed_depth_stencil GL_EXT_texture_format_BGRA8888 "
  117. "GL_EXT_read_format_bgra";
  118. gl_shading_language_version_ = "1.40 NVIDIA via Cg compiler";
  119. break;
  120. }
  121. default: {
  122. NOTREACHED();
  123. break;
  124. }
  125. }
  126. // Need to make a context current so that WillUseGLGetStringForExtensions
  127. // can be called
  128. context_ = new gl::GLContextStub;
  129. context_->SetExtensionsString(test_values_.gl_extensions.c_str());
  130. context_->SetGLVersionString(test_values_.gl_version.c_str());
  131. surface_ = new gl::GLSurfaceStub;
  132. context_->MakeCurrent(surface_.get());
  133. EXPECT_CALL(*gl_, GetString(GL_VERSION))
  134. .WillRepeatedly(Return(reinterpret_cast<const GLubyte*>(
  135. test_values_.gl_version.c_str())));
  136. EXPECT_CALL(*gl_, GetString(GL_RENDERER))
  137. .WillRepeatedly(Return(reinterpret_cast<const GLubyte*>(
  138. test_values_.gl_renderer.c_str())));
  139. // Now that that expectation is set up, we can call this helper function.
  140. if (gl::WillUseGLGetStringForExtensions()) {
  141. EXPECT_CALL(*gl_, GetString(GL_EXTENSIONS))
  142. .WillRepeatedly(Return(reinterpret_cast<const GLubyte*>(
  143. test_values_.gl_extensions.c_str())));
  144. } else {
  145. split_extensions_.clear();
  146. split_extensions_ = base::SplitString(
  147. test_values_.gl_extensions, " ",
  148. base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  149. EXPECT_CALL(*gl_, GetIntegerv(GL_NUM_EXTENSIONS, _))
  150. .WillRepeatedly(SetArgPointee<1>(split_extensions_.size()));
  151. for (size_t ii = 0; ii < split_extensions_.size(); ++ii) {
  152. EXPECT_CALL(*gl_, GetStringi(GL_EXTENSIONS, ii))
  153. .WillRepeatedly(Return(reinterpret_cast<const uint8_t*>(
  154. split_extensions_[ii].c_str())));
  155. }
  156. }
  157. EXPECT_CALL(*gl_, GetString(GL_SHADING_LANGUAGE_VERSION))
  158. .WillRepeatedly(Return(reinterpret_cast<const GLubyte*>(
  159. gl_shading_language_version_)));
  160. EXPECT_CALL(*gl_, GetString(GL_VENDOR))
  161. .WillRepeatedly(Return(reinterpret_cast<const GLubyte*>(
  162. test_values_.gl_vendor.c_str())));
  163. EXPECT_CALL(*gl_, GetString(GL_RENDERER))
  164. .WillRepeatedly(Return(reinterpret_cast<const GLubyte*>(
  165. test_values_.gl_renderer.c_str())));
  166. EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_SAMPLES, _))
  167. .WillOnce(SetArgPointee<1>(8))
  168. .RetiresOnSaturation();
  169. }
  170. void TearDown() override {
  171. ::gl::MockGLInterface::SetGLInterface(nullptr);
  172. gl_.reset();
  173. gl::GLSurfaceTestSupport::ShutdownGL(display_);
  174. testing::Test::TearDown();
  175. }
  176. protected:
  177. // Use StrictMock to make 100% sure we know how GL will be called.
  178. std::unique_ptr<::testing::StrictMock<::gl::MockGLInterface>> gl_;
  179. GPUInfo test_values_;
  180. scoped_refptr<gl::GLContextStub> context_;
  181. scoped_refptr<gl::GLSurfaceStub> surface_;
  182. const char* gl_shading_language_version_ = nullptr;
  183. // Persistent storage is needed for the split extension string.
  184. std::vector<std::string> split_extensions_;
  185. raw_ptr<gl::GLDisplay> display_ = nullptr;
  186. };
  187. INSTANTIATE_TEST_SUITE_P(GPUConfig,
  188. GPUInfoCollectorTest,
  189. ::testing::ValuesIn(kMockedOperatingSystemKinds));
  190. // TODO(rlp): Test the vendor and device id collection if deemed necessary as
  191. // it involves several complicated mocks for each platform.
  192. // TODO(kbr): This test still has platform-dependent behavior because
  193. // CollectDriverInfoGL behaves differently per platform. This should
  194. // be fixed.
  195. TEST_P(GPUInfoCollectorTest, CollectGraphicsInfoGL) {
  196. GPUInfo gpu_info;
  197. CollectGraphicsInfoGL(&gpu_info, gl::GetDefaultDisplay());
  198. #if BUILDFLAG(IS_WIN)
  199. if (GetParam() == kMockedWindows) {
  200. EXPECT_EQ(test_values_.gpu.driver_vendor, gpu_info.gpu.driver_vendor);
  201. // Skip testing the driver version on Windows because it's
  202. // obtained from the bot's registry.
  203. }
  204. #elif BUILDFLAG(IS_MAC)
  205. if (GetParam() == kMockedMacOSX) {
  206. EXPECT_EQ(test_values_.gpu.driver_vendor, gpu_info.gpu.driver_vendor);
  207. EXPECT_EQ(test_values_.gpu.driver_version, gpu_info.gpu.driver_version);
  208. }
  209. #elif BUILDFLAG(IS_ANDROID)
  210. if (GetParam() == kMockedAndroid) {
  211. EXPECT_EQ(test_values_.gpu.driver_vendor, gpu_info.gpu.driver_vendor);
  212. EXPECT_EQ(test_values_.gpu.driver_version, gpu_info.gpu.driver_version);
  213. }
  214. #else // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
  215. if (GetParam() == kMockedLinux) {
  216. EXPECT_EQ(test_values_.gpu.driver_vendor, gpu_info.gpu.driver_vendor);
  217. EXPECT_EQ(test_values_.gpu.driver_version, gpu_info.gpu.driver_version);
  218. }
  219. #endif
  220. EXPECT_EQ(test_values_.pixel_shader_version,
  221. gpu_info.pixel_shader_version);
  222. EXPECT_EQ(test_values_.vertex_shader_version,
  223. gpu_info.vertex_shader_version);
  224. EXPECT_EQ(test_values_.gl_version, gpu_info.gl_version);
  225. EXPECT_EQ(test_values_.gl_renderer, gpu_info.gl_renderer);
  226. EXPECT_EQ(test_values_.gl_vendor, gpu_info.gl_vendor);
  227. EXPECT_EQ(test_values_.gl_extensions, gpu_info.gl_extensions);
  228. }
  229. TEST(MultiGPUsTest, IdentifyActiveGPU0) {
  230. GPUInfo::GPUDevice nvidia_gpu;
  231. nvidia_gpu.vendor_id = 0x10de;
  232. nvidia_gpu.device_id = 0x0df8;
  233. GPUInfo::GPUDevice intel_gpu;
  234. intel_gpu.vendor_id = 0x8086;
  235. intel_gpu.device_id = 0x0416;
  236. GPUInfo gpu_info;
  237. gpu_info.gpu = nvidia_gpu;
  238. gpu_info.secondary_gpus.push_back(intel_gpu);
  239. EXPECT_FALSE(gpu_info.gpu.active);
  240. EXPECT_FALSE(gpu_info.secondary_gpus[0].active);
  241. IdentifyActiveGPU(&gpu_info);
  242. EXPECT_FALSE(gpu_info.gpu.active);
  243. EXPECT_FALSE(gpu_info.secondary_gpus[0].active);
  244. gpu_info.gl_vendor = "Intel Open Source Technology Center";
  245. gpu_info.gl_renderer = "Mesa DRI Intel(R) Haswell Mobile";
  246. IdentifyActiveGPU(&gpu_info);
  247. EXPECT_FALSE(gpu_info.gpu.active);
  248. EXPECT_TRUE(gpu_info.secondary_gpus[0].active);
  249. gpu_info.gl_vendor = "NVIDIA Corporation";
  250. gpu_info.gl_renderer = "Quadro 600/PCIe/SSE2";
  251. IdentifyActiveGPU(&gpu_info);
  252. EXPECT_TRUE(gpu_info.gpu.active);
  253. EXPECT_FALSE(gpu_info.secondary_gpus[0].active);
  254. }
  255. TEST(MultiGPUsTest, IdentifyActiveGPU1) {
  256. GPUInfo::GPUDevice nvidia_gpu;
  257. nvidia_gpu.vendor_id = 0x10de;
  258. nvidia_gpu.device_id = 0x0de1;
  259. GPUInfo::GPUDevice intel_gpu;
  260. intel_gpu.vendor_id = 0x8086;
  261. intel_gpu.device_id = 0x040a;
  262. GPUInfo gpu_info;
  263. gpu_info.gpu = intel_gpu;
  264. gpu_info.secondary_gpus.push_back(nvidia_gpu);
  265. EXPECT_FALSE(gpu_info.gpu.active);
  266. EXPECT_FALSE(gpu_info.secondary_gpus[0].active);
  267. IdentifyActiveGPU(&gpu_info);
  268. EXPECT_FALSE(gpu_info.gpu.active);
  269. EXPECT_FALSE(gpu_info.secondary_gpus[0].active);
  270. gpu_info.gl_vendor = "nouveau";
  271. IdentifyActiveGPU(&gpu_info);
  272. EXPECT_FALSE(gpu_info.gpu.active);
  273. EXPECT_TRUE(gpu_info.secondary_gpus[0].active);
  274. }
  275. TEST(MultiGPUsTest, IdentifyActiveGPU2) {
  276. GPUInfo::GPUDevice nvidia_gpu;
  277. nvidia_gpu.vendor_id = 0x10de;
  278. nvidia_gpu.device_id = 0x0de1;
  279. GPUInfo::GPUDevice intel_gpu;
  280. intel_gpu.vendor_id = 0x8086;
  281. intel_gpu.device_id = 0x040a;
  282. GPUInfo gpu_info;
  283. gpu_info.gpu = intel_gpu;
  284. gpu_info.secondary_gpus.push_back(nvidia_gpu);
  285. EXPECT_FALSE(gpu_info.gpu.active);
  286. EXPECT_FALSE(gpu_info.secondary_gpus[0].active);
  287. IdentifyActiveGPU(&gpu_info);
  288. EXPECT_FALSE(gpu_info.gpu.active);
  289. EXPECT_FALSE(gpu_info.secondary_gpus[0].active);
  290. gpu_info.gl_vendor = "Intel";
  291. IdentifyActiveGPU(&gpu_info);
  292. EXPECT_TRUE(gpu_info.gpu.active);
  293. EXPECT_FALSE(gpu_info.secondary_gpus[0].active);
  294. }
  295. TEST(MultiGPUsTest, IdentifyActiveGPU3) {
  296. GPUInfo::GPUDevice nvidia_gpu;
  297. nvidia_gpu.vendor_id = 0x10de;
  298. nvidia_gpu.device_id = 0x0de1;
  299. GPUInfo::GPUDevice intel_gpu;
  300. intel_gpu.vendor_id = 0x8086;
  301. intel_gpu.device_id = 0x040a;
  302. GPUInfo::GPUDevice amd_gpu;
  303. amd_gpu.vendor_id = 0x1002;
  304. amd_gpu.device_id = 0x6779;
  305. GPUInfo gpu_info;
  306. gpu_info.gpu = intel_gpu;
  307. gpu_info.secondary_gpus.push_back(nvidia_gpu);
  308. gpu_info.secondary_gpus.push_back(amd_gpu);
  309. EXPECT_FALSE(gpu_info.gpu.active);
  310. EXPECT_FALSE(gpu_info.secondary_gpus[0].active);
  311. EXPECT_FALSE(gpu_info.secondary_gpus[1].active);
  312. IdentifyActiveGPU(&gpu_info);
  313. EXPECT_FALSE(gpu_info.gpu.active);
  314. EXPECT_FALSE(gpu_info.secondary_gpus[0].active);
  315. EXPECT_FALSE(gpu_info.secondary_gpus[1].active);
  316. gpu_info.gl_vendor = "X.Org";
  317. gpu_info.gl_renderer = "AMD R600";
  318. IdentifyActiveGPU(&gpu_info);
  319. EXPECT_FALSE(gpu_info.gpu.active);
  320. EXPECT_FALSE(gpu_info.secondary_gpus[0].active);
  321. EXPECT_TRUE(gpu_info.secondary_gpus[1].active);
  322. }
  323. TEST(MultiGPUsTest, IdentifyActiveGPU4) {
  324. GPUInfo::GPUDevice nvidia_gpu;
  325. nvidia_gpu.vendor_id = 0x10de;
  326. nvidia_gpu.device_id = 0x0de1;
  327. GPUInfo gpu_info;
  328. gpu_info.gpu = nvidia_gpu;
  329. EXPECT_FALSE(gpu_info.gpu.active);
  330. IdentifyActiveGPU(&gpu_info);
  331. EXPECT_TRUE(gpu_info.gpu.active);
  332. gpu_info.gl_vendor = "nouveau";
  333. IdentifyActiveGPU(&gpu_info);
  334. EXPECT_TRUE(gpu_info.gpu.active);
  335. }
  336. TEST(MultiGPUsTest, IdentifyActiveGPUAvoidFalseMatch) {
  337. // Verify that "Corporation" won't be matched with "ati".
  338. GPUInfo::GPUDevice amd_gpu;
  339. amd_gpu.vendor_id = 0x1002;
  340. amd_gpu.device_id = 0x0df8;
  341. GPUInfo::GPUDevice intel_gpu;
  342. intel_gpu.vendor_id = 0x8086;
  343. intel_gpu.device_id = 0x0416;
  344. GPUInfo gpu_info;
  345. gpu_info.gpu = amd_gpu;
  346. gpu_info.secondary_gpus.push_back(intel_gpu);
  347. gpu_info.gl_vendor = "Google Corporation";
  348. gpu_info.gl_renderer = "Chrome GPU Team";
  349. IdentifyActiveGPU(&gpu_info);
  350. EXPECT_FALSE(gpu_info.gpu.active);
  351. EXPECT_FALSE(gpu_info.secondary_gpus[0].active);
  352. }
  353. } // namespace gpu