• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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