1 // Copyright 2017 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "host-common/opengl/NativeGpuInfo.h"
16
17 #include "aemu/base/files/PathUtils.h"
18 #include "aemu/base/files/ScopedFd.h"
19 #include "aemu/base/misc/FileUtils.h"
20 #include "aemu/base/system/System.h"
21
22 #include <string>
23
24 using android::base::PathUtils;
25 using android::base::ScopedFd;
26
27 static const int kGPUInfoQueryTimeoutMs = 5000;
28
29 // static std::string load_gpu_info() {
30 // // Execute the command to get GPU info.
31 // return System::get()
32 // ->runCommandWithResult({"lspci", "-mvnn"}, kGPUInfoQueryTimeoutMs)
33 // .valueOr({});
34 // }
35
parse_last_hexbrackets(const std::string & str)36 static std::string parse_last_hexbrackets(const std::string& str) {
37 size_t closebrace_p = str.rfind("]");
38 size_t openbrace_p = str.rfind("[", closebrace_p - 1);
39 return str.substr(openbrace_p + 1, closebrace_p - openbrace_p - 1);
40 }
41
parse_gpu_info_list_linux(const std::string & contents,GpuInfoList * gpulist)42 void parse_gpu_info_list_linux(const std::string& contents,
43 GpuInfoList* gpulist) {
44 size_t line_loc = contents.find("\n");
45 if (line_loc == std::string::npos) {
46 line_loc = contents.size();
47 }
48 size_t p = 0;
49 std::string key;
50 std::string val;
51 bool lookfor = false;
52
53 // Linux - Only support one GPU for now.
54 // On Linux, the only command that seems not to take
55 // forever is lspci.
56 // We just look for "VGA" in lspci, then
57 // attempt to grab vendor and device information.
58 // Second, we use glx to look for the version string,
59 // in case there is a renderer such as Mesa
60 // to look out for.
61 while (line_loc != std::string::npos) {
62 key = contents.substr(p, line_loc - p);
63 if (!lookfor && (key.find("VGA") != std::string::npos)) {
64 lookfor = true;
65 gpulist->addGpu();
66 gpulist->currGpu().os = "L";
67 } else if (lookfor && (key.find("Vendor") != std::string::npos)) {
68 gpulist->currGpu().make = parse_last_hexbrackets(key);
69 } else if (lookfor && (key.find("Device") != std::string::npos)) {
70 gpulist->currGpu().device_id = parse_last_hexbrackets(key);
71 lookfor = false;
72 } else if (key.find("OpenGL version string") != std::string::npos) {
73 gpulist->currGpu().renderer = key;
74 } else {
75 }
76 if (line_loc == contents.size()) {
77 break;
78 }
79 p = line_loc + 1;
80 line_loc = contents.find("\n", p);
81 if (line_loc == std::string::npos) {
82 line_loc = contents.size();
83 }
84 }
85 }
86
getGpuInfoListNative(GpuInfoList * gpulist)87 void getGpuInfoListNative(GpuInfoList* gpulist) {
88 (void)gpulist;
89 // Load it in a traditional way - by parsing output of external process.
90
91 // TODO: Don't do GPU info detection on Linux for now---lspci can be
92 // inaccurate as to what GPU the user is actually using.
93 #ifdef ANDROID_DEBUG
94 // Workaround for b/77586363, clang -O0 introduces some unexpected behavior
95 // when it comes to the else. See the bug for details
96 // load_gpu_info();
97 #else
98 // (void)load_gpu_info; // Make Werror happy
99 #endif
100 // std::string gpu_info = load_gpu_info();
101 // parse_gpu_info_list_linux(gpu_info, gpulist);
102
103 // Unfortunately, even to obtain a driver version on Linux one has to either
104 // create a full rendering context (very slow, 150+ms) or hardcode specific
105 // ways to get it for each existing GPU driver (just insane).
106 //
107 // That's why this function doesn't populate driver version and renderer.
108 //
109 // If you ever need start from something to get them from OpenGL, here's
110 // a very simple example:
111 // http://web.mit.edu/jhawk/mnt/spo/3d/src/Mesa-3.0/samples/oglinfo.c
112 //
113 }
114
115 // Linux: do not blacklist Vulkan
isVulkanSafeToUseNative()116 bool isVulkanSafeToUseNative() {
117 return true;
118 }
119