1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker * Copyright 2017 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker *
4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker *
8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker *
10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker */
16*38e8c45fSAndroid Build Coastguard Worker
17*38e8c45fSAndroid Build Coastguard Worker #define ATRACE_TAG ATRACE_TAG_GRAPHICS
18*38e8c45fSAndroid Build Coastguard Worker
19*38e8c45fSAndroid Build Coastguard Worker //#define LOG_NDEBUG 1
20*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "GraphicsEnv"
21*38e8c45fSAndroid Build Coastguard Worker
22*38e8c45fSAndroid Build Coastguard Worker #include <graphicsenv/GraphicsEnv.h>
23*38e8c45fSAndroid Build Coastguard Worker
24*38e8c45fSAndroid Build Coastguard Worker #include <dlfcn.h>
25*38e8c45fSAndroid Build Coastguard Worker #include <unistd.h>
26*38e8c45fSAndroid Build Coastguard Worker
27*38e8c45fSAndroid Build Coastguard Worker #include <android-base/file.h>
28*38e8c45fSAndroid Build Coastguard Worker #include <android-base/properties.h>
29*38e8c45fSAndroid Build Coastguard Worker #include <android-base/strings.h>
30*38e8c45fSAndroid Build Coastguard Worker #include <android/dlext.h>
31*38e8c45fSAndroid Build Coastguard Worker #include <binder/IServiceManager.h>
32*38e8c45fSAndroid Build Coastguard Worker #include <graphicsenv/IGpuService.h>
33*38e8c45fSAndroid Build Coastguard Worker #include <log/log.h>
34*38e8c45fSAndroid Build Coastguard Worker #include <nativeloader/dlext_namespaces.h>
35*38e8c45fSAndroid Build Coastguard Worker #include <sys/prctl.h>
36*38e8c45fSAndroid Build Coastguard Worker #include <utils/Trace.h>
37*38e8c45fSAndroid Build Coastguard Worker
38*38e8c45fSAndroid Build Coastguard Worker #include <memory>
39*38e8c45fSAndroid Build Coastguard Worker #include <string>
40*38e8c45fSAndroid Build Coastguard Worker #include <thread>
41*38e8c45fSAndroid Build Coastguard Worker
42*38e8c45fSAndroid Build Coastguard Worker // TODO(b/159240322): Extend this to x86 ABI.
43*38e8c45fSAndroid Build Coastguard Worker #if defined(__LP64__)
44*38e8c45fSAndroid Build Coastguard Worker #define UPDATABLE_DRIVER_ABI "arm64-v8a"
45*38e8c45fSAndroid Build Coastguard Worker #else
46*38e8c45fSAndroid Build Coastguard Worker #define UPDATABLE_DRIVER_ABI "armeabi-v7a"
47*38e8c45fSAndroid Build Coastguard Worker #endif // defined(__LP64__)
48*38e8c45fSAndroid Build Coastguard Worker
49*38e8c45fSAndroid Build Coastguard Worker // TODO(ianelliott@): Get the following from an ANGLE header:
50*38e8c45fSAndroid Build Coastguard Worker #define CURRENT_ANGLE_API_VERSION 2 // Current API verion we are targetting
51*38e8c45fSAndroid Build Coastguard Worker // Version-2 API:
52*38e8c45fSAndroid Build Coastguard Worker typedef bool (*fpANGLEGetFeatureSupportUtilAPIVersion)(unsigned int* versionToUse);
53*38e8c45fSAndroid Build Coastguard Worker typedef bool (*fpANGLEAndroidParseRulesString)(const char* rulesString, void** rulesHandle,
54*38e8c45fSAndroid Build Coastguard Worker int* rulesVersion);
55*38e8c45fSAndroid Build Coastguard Worker typedef bool (*fpANGLEGetSystemInfo)(void** handle);
56*38e8c45fSAndroid Build Coastguard Worker typedef bool (*fpANGLEAddDeviceInfoToSystemInfo)(const char* deviceMfr, const char* deviceModel,
57*38e8c45fSAndroid Build Coastguard Worker void* handle);
58*38e8c45fSAndroid Build Coastguard Worker typedef bool (*fpANGLEShouldBeUsedForApplication)(void* rulesHandle, int rulesVersion,
59*38e8c45fSAndroid Build Coastguard Worker void* systemInfoHandle, const char* appName);
60*38e8c45fSAndroid Build Coastguard Worker typedef bool (*fpANGLEFreeRulesHandle)(void* handle);
61*38e8c45fSAndroid Build Coastguard Worker typedef bool (*fpANGLEFreeSystemInfoHandle)(void* handle);
62*38e8c45fSAndroid Build Coastguard Worker
63*38e8c45fSAndroid Build Coastguard Worker namespace {
isVndkEnabled()64*38e8c45fSAndroid Build Coastguard Worker static bool isVndkEnabled() {
65*38e8c45fSAndroid Build Coastguard Worker #ifdef __BIONIC__
66*38e8c45fSAndroid Build Coastguard Worker static bool isVndkEnabled = android::base::GetProperty("ro.vndk.version", "") != "";
67*38e8c45fSAndroid Build Coastguard Worker return isVndkEnabled;
68*38e8c45fSAndroid Build Coastguard Worker #endif
69*38e8c45fSAndroid Build Coastguard Worker return false;
70*38e8c45fSAndroid Build Coastguard Worker }
71*38e8c45fSAndroid Build Coastguard Worker } // namespace
72*38e8c45fSAndroid Build Coastguard Worker
73*38e8c45fSAndroid Build Coastguard Worker namespace android {
74*38e8c45fSAndroid Build Coastguard Worker
75*38e8c45fSAndroid Build Coastguard Worker enum NativeLibrary {
76*38e8c45fSAndroid Build Coastguard Worker LLNDK = 0,
77*38e8c45fSAndroid Build Coastguard Worker VNDKSP = 1,
78*38e8c45fSAndroid Build Coastguard Worker };
79*38e8c45fSAndroid Build Coastguard Worker
80*38e8c45fSAndroid Build Coastguard Worker static constexpr const char* kNativeLibrariesSystemConfigPath[] =
81*38e8c45fSAndroid Build Coastguard Worker {"/apex/com.android.vndk.v{}/etc/llndk.libraries.{}.txt",
82*38e8c45fSAndroid Build Coastguard Worker "/apex/com.android.vndk.v{}/etc/vndksp.libraries.{}.txt"};
83*38e8c45fSAndroid Build Coastguard Worker
84*38e8c45fSAndroid Build Coastguard Worker static const char* kLlndkLibrariesTxtPath = "/system/etc/llndk.libraries.txt";
85*38e8c45fSAndroid Build Coastguard Worker
86*38e8c45fSAndroid Build Coastguard Worker // List of libraries that were previously available via VNDK-SP,
87*38e8c45fSAndroid Build Coastguard Worker // and are now available via SPHAL.
88*38e8c45fSAndroid Build Coastguard Worker // On modern devices that lack the VNDK APEX, the device no longer
89*38e8c45fSAndroid Build Coastguard Worker // contains a helpful list of these libraries on the filesystem as above.
90*38e8c45fSAndroid Build Coastguard Worker // See system/sepolicy/vendor/file_contexts
91*38e8c45fSAndroid Build Coastguard Worker static const char* kFormerlyVndkspLibrariesList =
92*38e8c45fSAndroid Build Coastguard Worker "android.hardware.common-V2-ndk.so:"
93*38e8c45fSAndroid Build Coastguard Worker "android.hardware.common.fmq-V1-ndk.so:"
94*38e8c45fSAndroid Build Coastguard Worker "android.hardware.graphics.allocator-V2-ndk.so:"
95*38e8c45fSAndroid Build Coastguard Worker "android.hardware.graphics.common-V6-ndk.so:"
96*38e8c45fSAndroid Build Coastguard Worker "[email protected]:"
97*38e8c45fSAndroid Build Coastguard Worker "[email protected]:"
98*38e8c45fSAndroid Build Coastguard Worker "[email protected]:"
99*38e8c45fSAndroid Build Coastguard Worker "android.hardware.graphics.composer3-V1-ndk.so:"
100*38e8c45fSAndroid Build Coastguard Worker "[email protected]:"
101*38e8c45fSAndroid Build Coastguard Worker "[email protected]:"
102*38e8c45fSAndroid Build Coastguard Worker "[email protected]:"
103*38e8c45fSAndroid Build Coastguard Worker "[email protected]:"
104*38e8c45fSAndroid Build Coastguard Worker "[email protected]:"
105*38e8c45fSAndroid Build Coastguard Worker "[email protected]:"
106*38e8c45fSAndroid Build Coastguard Worker "[email protected]:"
107*38e8c45fSAndroid Build Coastguard Worker "[email protected]:"
108*38e8c45fSAndroid Build Coastguard Worker "[email protected]:"
109*38e8c45fSAndroid Build Coastguard Worker "libRSCpuRef.so:"
110*38e8c45fSAndroid Build Coastguard Worker "libRSDriver.so:"
111*38e8c45fSAndroid Build Coastguard Worker "libRS_internal.so:"
112*38e8c45fSAndroid Build Coastguard Worker "libbacktrace.so:"
113*38e8c45fSAndroid Build Coastguard Worker "libbase.so:"
114*38e8c45fSAndroid Build Coastguard Worker "libbcinfo.so:"
115*38e8c45fSAndroid Build Coastguard Worker "libblas.so:"
116*38e8c45fSAndroid Build Coastguard Worker "libc++.so:"
117*38e8c45fSAndroid Build Coastguard Worker "libcompiler_rt.so:"
118*38e8c45fSAndroid Build Coastguard Worker "libcutils.so:"
119*38e8c45fSAndroid Build Coastguard Worker "libdmabufheap.so:"
120*38e8c45fSAndroid Build Coastguard Worker "libft2.so:"
121*38e8c45fSAndroid Build Coastguard Worker "libgralloctypes.so:"
122*38e8c45fSAndroid Build Coastguard Worker "libhardware.so:"
123*38e8c45fSAndroid Build Coastguard Worker "libhidlbase.so:"
124*38e8c45fSAndroid Build Coastguard Worker "libhidlmemory.so:"
125*38e8c45fSAndroid Build Coastguard Worker "libion.so:"
126*38e8c45fSAndroid Build Coastguard Worker "libjsoncpp.so:"
127*38e8c45fSAndroid Build Coastguard Worker "liblzma.so:"
128*38e8c45fSAndroid Build Coastguard Worker "libpng.so:"
129*38e8c45fSAndroid Build Coastguard Worker "libprocessgroup.so:"
130*38e8c45fSAndroid Build Coastguard Worker "libunwindstack.so:"
131*38e8c45fSAndroid Build Coastguard Worker "libutils.so:"
132*38e8c45fSAndroid Build Coastguard Worker "libutilscallstack.so:"
133*38e8c45fSAndroid Build Coastguard Worker "libz.so";
134*38e8c45fSAndroid Build Coastguard Worker
vndkVersionStr()135*38e8c45fSAndroid Build Coastguard Worker static std::string vndkVersionStr() {
136*38e8c45fSAndroid Build Coastguard Worker #ifdef __BIONIC__
137*38e8c45fSAndroid Build Coastguard Worker return base::GetProperty("ro.vndk.version", "");
138*38e8c45fSAndroid Build Coastguard Worker #endif
139*38e8c45fSAndroid Build Coastguard Worker return "";
140*38e8c45fSAndroid Build Coastguard Worker }
141*38e8c45fSAndroid Build Coastguard Worker
insertVndkVersionStr(std::string * fileName)142*38e8c45fSAndroid Build Coastguard Worker static void insertVndkVersionStr(std::string* fileName) {
143*38e8c45fSAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(!fileName, "fileName should never be nullptr");
144*38e8c45fSAndroid Build Coastguard Worker std::string version = vndkVersionStr();
145*38e8c45fSAndroid Build Coastguard Worker size_t pos = fileName->find("{}");
146*38e8c45fSAndroid Build Coastguard Worker while (pos != std::string::npos) {
147*38e8c45fSAndroid Build Coastguard Worker fileName->replace(pos, 2, version);
148*38e8c45fSAndroid Build Coastguard Worker pos = fileName->find("{}", pos + version.size());
149*38e8c45fSAndroid Build Coastguard Worker }
150*38e8c45fSAndroid Build Coastguard Worker }
151*38e8c45fSAndroid Build Coastguard Worker
readConfig(const std::string & configFile,std::vector<std::string> * soNames)152*38e8c45fSAndroid Build Coastguard Worker static bool readConfig(const std::string& configFile, std::vector<std::string>* soNames) {
153*38e8c45fSAndroid Build Coastguard Worker // Read list of public native libraries from the config file.
154*38e8c45fSAndroid Build Coastguard Worker std::string fileContent;
155*38e8c45fSAndroid Build Coastguard Worker if (!base::ReadFileToString(configFile, &fileContent)) {
156*38e8c45fSAndroid Build Coastguard Worker return false;
157*38e8c45fSAndroid Build Coastguard Worker }
158*38e8c45fSAndroid Build Coastguard Worker
159*38e8c45fSAndroid Build Coastguard Worker std::vector<std::string> lines = base::Split(fileContent, "\n");
160*38e8c45fSAndroid Build Coastguard Worker
161*38e8c45fSAndroid Build Coastguard Worker for (auto& line : lines) {
162*38e8c45fSAndroid Build Coastguard Worker auto trimmedLine = base::Trim(line);
163*38e8c45fSAndroid Build Coastguard Worker if (!trimmedLine.empty()) {
164*38e8c45fSAndroid Build Coastguard Worker soNames->push_back(trimmedLine);
165*38e8c45fSAndroid Build Coastguard Worker }
166*38e8c45fSAndroid Build Coastguard Worker }
167*38e8c45fSAndroid Build Coastguard Worker
168*38e8c45fSAndroid Build Coastguard Worker return true;
169*38e8c45fSAndroid Build Coastguard Worker }
170*38e8c45fSAndroid Build Coastguard Worker
getSystemNativeLibraries(NativeLibrary type)171*38e8c45fSAndroid Build Coastguard Worker static const std::string getSystemNativeLibraries(NativeLibrary type) {
172*38e8c45fSAndroid Build Coastguard Worker std::string nativeLibrariesSystemConfig = "";
173*38e8c45fSAndroid Build Coastguard Worker
174*38e8c45fSAndroid Build Coastguard Worker if (!isVndkEnabled()) {
175*38e8c45fSAndroid Build Coastguard Worker if (type == NativeLibrary::VNDKSP) {
176*38e8c45fSAndroid Build Coastguard Worker return kFormerlyVndkspLibrariesList;
177*38e8c45fSAndroid Build Coastguard Worker } else {
178*38e8c45fSAndroid Build Coastguard Worker nativeLibrariesSystemConfig = kLlndkLibrariesTxtPath;
179*38e8c45fSAndroid Build Coastguard Worker }
180*38e8c45fSAndroid Build Coastguard Worker } else {
181*38e8c45fSAndroid Build Coastguard Worker nativeLibrariesSystemConfig = kNativeLibrariesSystemConfigPath[type];
182*38e8c45fSAndroid Build Coastguard Worker insertVndkVersionStr(&nativeLibrariesSystemConfig);
183*38e8c45fSAndroid Build Coastguard Worker }
184*38e8c45fSAndroid Build Coastguard Worker
185*38e8c45fSAndroid Build Coastguard Worker std::vector<std::string> soNames;
186*38e8c45fSAndroid Build Coastguard Worker if (!readConfig(nativeLibrariesSystemConfig, &soNames)) {
187*38e8c45fSAndroid Build Coastguard Worker ALOGE("Failed to retrieve library names from %s", nativeLibrariesSystemConfig.c_str());
188*38e8c45fSAndroid Build Coastguard Worker return "";
189*38e8c45fSAndroid Build Coastguard Worker }
190*38e8c45fSAndroid Build Coastguard Worker
191*38e8c45fSAndroid Build Coastguard Worker return base::Join(soNames, ':');
192*38e8c45fSAndroid Build Coastguard Worker }
193*38e8c45fSAndroid Build Coastguard Worker
getGpuService()194*38e8c45fSAndroid Build Coastguard Worker static sp<IGpuService> getGpuService() {
195*38e8c45fSAndroid Build Coastguard Worker static const sp<IBinder> binder = defaultServiceManager()->checkService(String16("gpu"));
196*38e8c45fSAndroid Build Coastguard Worker if (!binder) {
197*38e8c45fSAndroid Build Coastguard Worker ALOGE("Failed to get gpu service");
198*38e8c45fSAndroid Build Coastguard Worker return nullptr;
199*38e8c45fSAndroid Build Coastguard Worker }
200*38e8c45fSAndroid Build Coastguard Worker
201*38e8c45fSAndroid Build Coastguard Worker return interface_cast<IGpuService>(binder);
202*38e8c45fSAndroid Build Coastguard Worker }
203*38e8c45fSAndroid Build Coastguard Worker
getInstance()204*38e8c45fSAndroid Build Coastguard Worker /*static*/ GraphicsEnv& GraphicsEnv::getInstance() {
205*38e8c45fSAndroid Build Coastguard Worker static GraphicsEnv env;
206*38e8c45fSAndroid Build Coastguard Worker return env;
207*38e8c45fSAndroid Build Coastguard Worker }
208*38e8c45fSAndroid Build Coastguard Worker
isDebuggable()209*38e8c45fSAndroid Build Coastguard Worker bool GraphicsEnv::isDebuggable() {
210*38e8c45fSAndroid Build Coastguard Worker // This flag determines if the application is marked debuggable
211*38e8c45fSAndroid Build Coastguard Worker bool appDebuggable = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) > 0;
212*38e8c45fSAndroid Build Coastguard Worker
213*38e8c45fSAndroid Build Coastguard Worker // This flag is set only in `debuggable` builds of the platform
214*38e8c45fSAndroid Build Coastguard Worker #if defined(ANDROID_DEBUGGABLE)
215*38e8c45fSAndroid Build Coastguard Worker bool platformDebuggable = true;
216*38e8c45fSAndroid Build Coastguard Worker #else
217*38e8c45fSAndroid Build Coastguard Worker bool platformDebuggable = false;
218*38e8c45fSAndroid Build Coastguard Worker #endif
219*38e8c45fSAndroid Build Coastguard Worker
220*38e8c45fSAndroid Build Coastguard Worker ALOGV("GraphicsEnv::isDebuggable returning appDebuggable=%s || platformDebuggable=%s",
221*38e8c45fSAndroid Build Coastguard Worker appDebuggable ? "true" : "false", platformDebuggable ? "true" : "false");
222*38e8c45fSAndroid Build Coastguard Worker
223*38e8c45fSAndroid Build Coastguard Worker return appDebuggable || platformDebuggable;
224*38e8c45fSAndroid Build Coastguard Worker }
225*38e8c45fSAndroid Build Coastguard Worker
226*38e8c45fSAndroid Build Coastguard Worker /**
227*38e8c45fSAndroid Build Coastguard Worker * APIs for updatable graphics drivers
228*38e8c45fSAndroid Build Coastguard Worker */
229*38e8c45fSAndroid Build Coastguard Worker
setDriverPathAndSphalLibraries(const std::string & path,const std::string & sphalLibraries)230*38e8c45fSAndroid Build Coastguard Worker void GraphicsEnv::setDriverPathAndSphalLibraries(const std::string& path,
231*38e8c45fSAndroid Build Coastguard Worker const std::string& sphalLibraries) {
232*38e8c45fSAndroid Build Coastguard Worker if (!mDriverPath.empty() || !mSphalLibraries.empty()) {
233*38e8c45fSAndroid Build Coastguard Worker ALOGV("ignoring attempt to change driver path from '%s' to '%s' or change sphal libraries "
234*38e8c45fSAndroid Build Coastguard Worker "from '%s' to '%s'",
235*38e8c45fSAndroid Build Coastguard Worker mDriverPath.c_str(), path.c_str(), mSphalLibraries.c_str(), sphalLibraries.c_str());
236*38e8c45fSAndroid Build Coastguard Worker return;
237*38e8c45fSAndroid Build Coastguard Worker }
238*38e8c45fSAndroid Build Coastguard Worker ALOGV("setting driver path to '%s' and sphal libraries to '%s'", path.c_str(),
239*38e8c45fSAndroid Build Coastguard Worker sphalLibraries.c_str());
240*38e8c45fSAndroid Build Coastguard Worker mDriverPath = path;
241*38e8c45fSAndroid Build Coastguard Worker mSphalLibraries = sphalLibraries;
242*38e8c45fSAndroid Build Coastguard Worker }
243*38e8c45fSAndroid Build Coastguard Worker
244*38e8c45fSAndroid Build Coastguard Worker // Return true if all the required libraries from vndk and sphal namespace are
245*38e8c45fSAndroid Build Coastguard Worker // linked to the driver namespace correctly.
linkDriverNamespaceLocked(android_namespace_t * destNamespace,android_namespace_t * vndkNamespace,const std::string & sharedSphalLibraries)246*38e8c45fSAndroid Build Coastguard Worker bool GraphicsEnv::linkDriverNamespaceLocked(android_namespace_t* destNamespace,
247*38e8c45fSAndroid Build Coastguard Worker android_namespace_t* vndkNamespace,
248*38e8c45fSAndroid Build Coastguard Worker const std::string& sharedSphalLibraries) {
249*38e8c45fSAndroid Build Coastguard Worker const std::string llndkLibraries = getSystemNativeLibraries(NativeLibrary::LLNDK);
250*38e8c45fSAndroid Build Coastguard Worker if (llndkLibraries.empty()) {
251*38e8c45fSAndroid Build Coastguard Worker return false;
252*38e8c45fSAndroid Build Coastguard Worker }
253*38e8c45fSAndroid Build Coastguard Worker if (!android_link_namespaces(destNamespace, nullptr, llndkLibraries.c_str())) {
254*38e8c45fSAndroid Build Coastguard Worker ALOGE("Failed to link default namespace[%s]", dlerror());
255*38e8c45fSAndroid Build Coastguard Worker return false;
256*38e8c45fSAndroid Build Coastguard Worker }
257*38e8c45fSAndroid Build Coastguard Worker
258*38e8c45fSAndroid Build Coastguard Worker const std::string vndkspLibraries = getSystemNativeLibraries(NativeLibrary::VNDKSP);
259*38e8c45fSAndroid Build Coastguard Worker if (vndkspLibraries.empty()) {
260*38e8c45fSAndroid Build Coastguard Worker return false;
261*38e8c45fSAndroid Build Coastguard Worker }
262*38e8c45fSAndroid Build Coastguard Worker if (!android_link_namespaces(destNamespace, vndkNamespace, vndkspLibraries.c_str())) {
263*38e8c45fSAndroid Build Coastguard Worker ALOGE("Failed to link vndk namespace[%s]", dlerror());
264*38e8c45fSAndroid Build Coastguard Worker return false;
265*38e8c45fSAndroid Build Coastguard Worker }
266*38e8c45fSAndroid Build Coastguard Worker
267*38e8c45fSAndroid Build Coastguard Worker if (sharedSphalLibraries.empty()) {
268*38e8c45fSAndroid Build Coastguard Worker return true;
269*38e8c45fSAndroid Build Coastguard Worker }
270*38e8c45fSAndroid Build Coastguard Worker
271*38e8c45fSAndroid Build Coastguard Worker // Make additional libraries in sphal to be accessible
272*38e8c45fSAndroid Build Coastguard Worker auto sphalNamespace = android_get_exported_namespace("sphal");
273*38e8c45fSAndroid Build Coastguard Worker if (!sphalNamespace) {
274*38e8c45fSAndroid Build Coastguard Worker ALOGE("Depend on these libraries[%s] in sphal, but failed to get sphal namespace",
275*38e8c45fSAndroid Build Coastguard Worker sharedSphalLibraries.c_str());
276*38e8c45fSAndroid Build Coastguard Worker return false;
277*38e8c45fSAndroid Build Coastguard Worker }
278*38e8c45fSAndroid Build Coastguard Worker
279*38e8c45fSAndroid Build Coastguard Worker if (!android_link_namespaces(destNamespace, sphalNamespace, sharedSphalLibraries.c_str())) {
280*38e8c45fSAndroid Build Coastguard Worker ALOGE("Failed to link sphal namespace[%s]", dlerror());
281*38e8c45fSAndroid Build Coastguard Worker return false;
282*38e8c45fSAndroid Build Coastguard Worker }
283*38e8c45fSAndroid Build Coastguard Worker
284*38e8c45fSAndroid Build Coastguard Worker return true;
285*38e8c45fSAndroid Build Coastguard Worker }
286*38e8c45fSAndroid Build Coastguard Worker
getDriverNamespace()287*38e8c45fSAndroid Build Coastguard Worker android_namespace_t* GraphicsEnv::getDriverNamespace() {
288*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mNamespaceMutex);
289*38e8c45fSAndroid Build Coastguard Worker
290*38e8c45fSAndroid Build Coastguard Worker if (mDriverNamespace) {
291*38e8c45fSAndroid Build Coastguard Worker return mDriverNamespace;
292*38e8c45fSAndroid Build Coastguard Worker }
293*38e8c45fSAndroid Build Coastguard Worker
294*38e8c45fSAndroid Build Coastguard Worker if (mDriverPath.empty()) {
295*38e8c45fSAndroid Build Coastguard Worker // For an application process, driver path is empty means this application is not opted in
296*38e8c45fSAndroid Build Coastguard Worker // to use updatable driver. Application process doesn't have the ability to set up
297*38e8c45fSAndroid Build Coastguard Worker // environment variables and hence before `getenv` call will return.
298*38e8c45fSAndroid Build Coastguard Worker // For a process that is not an application process, if it's run from an environment,
299*38e8c45fSAndroid Build Coastguard Worker // for example shell, where environment variables can be set, then it can opt into using
300*38e8c45fSAndroid Build Coastguard Worker // udpatable driver by setting UPDATABLE_GFX_DRIVER to 1. By setting to 1 the developer
301*38e8c45fSAndroid Build Coastguard Worker // driver will be used currently.
302*38e8c45fSAndroid Build Coastguard Worker // TODO(b/159240322) Support the production updatable driver.
303*38e8c45fSAndroid Build Coastguard Worker const char* id = getenv("UPDATABLE_GFX_DRIVER");
304*38e8c45fSAndroid Build Coastguard Worker if (id == nullptr || std::strcmp(id, "1") != 0) {
305*38e8c45fSAndroid Build Coastguard Worker return nullptr;
306*38e8c45fSAndroid Build Coastguard Worker }
307*38e8c45fSAndroid Build Coastguard Worker const sp<IGpuService> gpuService = getGpuService();
308*38e8c45fSAndroid Build Coastguard Worker if (!gpuService) {
309*38e8c45fSAndroid Build Coastguard Worker return nullptr;
310*38e8c45fSAndroid Build Coastguard Worker }
311*38e8c45fSAndroid Build Coastguard Worker mDriverPath = gpuService->getUpdatableDriverPath();
312*38e8c45fSAndroid Build Coastguard Worker if (mDriverPath.empty()) {
313*38e8c45fSAndroid Build Coastguard Worker return nullptr;
314*38e8c45fSAndroid Build Coastguard Worker }
315*38e8c45fSAndroid Build Coastguard Worker mDriverPath.append(UPDATABLE_DRIVER_ABI);
316*38e8c45fSAndroid Build Coastguard Worker ALOGI("Driver path is setup via UPDATABLE_GFX_DRIVER: %s", mDriverPath.c_str());
317*38e8c45fSAndroid Build Coastguard Worker }
318*38e8c45fSAndroid Build Coastguard Worker
319*38e8c45fSAndroid Build Coastguard Worker auto vndkNamespace = android_get_exported_namespace(isVndkEnabled() ? "vndk" : "sphal");
320*38e8c45fSAndroid Build Coastguard Worker if (!vndkNamespace) {
321*38e8c45fSAndroid Build Coastguard Worker mDriverNamespace = nullptr;
322*38e8c45fSAndroid Build Coastguard Worker return mDriverNamespace;
323*38e8c45fSAndroid Build Coastguard Worker }
324*38e8c45fSAndroid Build Coastguard Worker
325*38e8c45fSAndroid Build Coastguard Worker mDriverNamespace = android_create_namespace("updatable gfx driver",
326*38e8c45fSAndroid Build Coastguard Worker mDriverPath.c_str(), // ld_library_path
327*38e8c45fSAndroid Build Coastguard Worker mDriverPath.c_str(), // default_library_path
328*38e8c45fSAndroid Build Coastguard Worker ANDROID_NAMESPACE_TYPE_ISOLATED,
329*38e8c45fSAndroid Build Coastguard Worker nullptr, // permitted_when_isolated_path
330*38e8c45fSAndroid Build Coastguard Worker nullptr);
331*38e8c45fSAndroid Build Coastguard Worker
332*38e8c45fSAndroid Build Coastguard Worker if (!linkDriverNamespaceLocked(mDriverNamespace, vndkNamespace, mSphalLibraries)) {
333*38e8c45fSAndroid Build Coastguard Worker mDriverNamespace = nullptr;
334*38e8c45fSAndroid Build Coastguard Worker }
335*38e8c45fSAndroid Build Coastguard Worker
336*38e8c45fSAndroid Build Coastguard Worker return mDriverNamespace;
337*38e8c45fSAndroid Build Coastguard Worker }
338*38e8c45fSAndroid Build Coastguard Worker
getDriverPath() const339*38e8c45fSAndroid Build Coastguard Worker std::string GraphicsEnv::getDriverPath() const {
340*38e8c45fSAndroid Build Coastguard Worker return mDriverPath;
341*38e8c45fSAndroid Build Coastguard Worker }
342*38e8c45fSAndroid Build Coastguard Worker
343*38e8c45fSAndroid Build Coastguard Worker /**
344*38e8c45fSAndroid Build Coastguard Worker * APIs for GpuStats
345*38e8c45fSAndroid Build Coastguard Worker */
346*38e8c45fSAndroid Build Coastguard Worker
hintActivityLaunch()347*38e8c45fSAndroid Build Coastguard Worker void GraphicsEnv::hintActivityLaunch() {
348*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
349*38e8c45fSAndroid Build Coastguard Worker
350*38e8c45fSAndroid Build Coastguard Worker {
351*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mStatsLock);
352*38e8c45fSAndroid Build Coastguard Worker if (mActivityLaunched) return;
353*38e8c45fSAndroid Build Coastguard Worker mActivityLaunched = true;
354*38e8c45fSAndroid Build Coastguard Worker }
355*38e8c45fSAndroid Build Coastguard Worker
356*38e8c45fSAndroid Build Coastguard Worker std::thread trySendGpuStatsThread([this]() {
357*38e8c45fSAndroid Build Coastguard Worker // If there's already graphics driver preloaded in the process, just send
358*38e8c45fSAndroid Build Coastguard Worker // the stats info to GpuStats directly through async binder.
359*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mStatsLock);
360*38e8c45fSAndroid Build Coastguard Worker if (mGpuStats.glDriverToSend) {
361*38e8c45fSAndroid Build Coastguard Worker mGpuStats.glDriverToSend = false;
362*38e8c45fSAndroid Build Coastguard Worker sendGpuStatsLocked(GpuStatsInfo::Api::API_GL, true, mGpuStats.glDriverLoadingTime);
363*38e8c45fSAndroid Build Coastguard Worker }
364*38e8c45fSAndroid Build Coastguard Worker if (mGpuStats.vkDriverToSend) {
365*38e8c45fSAndroid Build Coastguard Worker mGpuStats.vkDriverToSend = false;
366*38e8c45fSAndroid Build Coastguard Worker sendGpuStatsLocked(GpuStatsInfo::Api::API_VK, true, mGpuStats.vkDriverLoadingTime);
367*38e8c45fSAndroid Build Coastguard Worker }
368*38e8c45fSAndroid Build Coastguard Worker });
369*38e8c45fSAndroid Build Coastguard Worker trySendGpuStatsThread.detach();
370*38e8c45fSAndroid Build Coastguard Worker }
371*38e8c45fSAndroid Build Coastguard Worker
setGpuStats(const std::string & driverPackageName,const std::string & driverVersionName,uint64_t driverVersionCode,int64_t driverBuildTime,const std::string & appPackageName,const int vulkanVersion)372*38e8c45fSAndroid Build Coastguard Worker void GraphicsEnv::setGpuStats(const std::string& driverPackageName,
373*38e8c45fSAndroid Build Coastguard Worker const std::string& driverVersionName, uint64_t driverVersionCode,
374*38e8c45fSAndroid Build Coastguard Worker int64_t driverBuildTime, const std::string& appPackageName,
375*38e8c45fSAndroid Build Coastguard Worker const int vulkanVersion) {
376*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
377*38e8c45fSAndroid Build Coastguard Worker
378*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mStatsLock);
379*38e8c45fSAndroid Build Coastguard Worker ALOGV("setGpuStats:\n"
380*38e8c45fSAndroid Build Coastguard Worker "\tdriverPackageName[%s]\n"
381*38e8c45fSAndroid Build Coastguard Worker "\tdriverVersionName[%s]\n"
382*38e8c45fSAndroid Build Coastguard Worker "\tdriverVersionCode[%" PRIu64 "]\n"
383*38e8c45fSAndroid Build Coastguard Worker "\tdriverBuildTime[%" PRId64 "]\n"
384*38e8c45fSAndroid Build Coastguard Worker "\tappPackageName[%s]\n"
385*38e8c45fSAndroid Build Coastguard Worker "\tvulkanVersion[%d]\n",
386*38e8c45fSAndroid Build Coastguard Worker driverPackageName.c_str(), driverVersionName.c_str(), driverVersionCode, driverBuildTime,
387*38e8c45fSAndroid Build Coastguard Worker appPackageName.c_str(), vulkanVersion);
388*38e8c45fSAndroid Build Coastguard Worker
389*38e8c45fSAndroid Build Coastguard Worker mGpuStats.driverPackageName = driverPackageName;
390*38e8c45fSAndroid Build Coastguard Worker mGpuStats.driverVersionName = driverVersionName;
391*38e8c45fSAndroid Build Coastguard Worker mGpuStats.driverVersionCode = driverVersionCode;
392*38e8c45fSAndroid Build Coastguard Worker mGpuStats.driverBuildTime = driverBuildTime;
393*38e8c45fSAndroid Build Coastguard Worker mGpuStats.appPackageName = appPackageName;
394*38e8c45fSAndroid Build Coastguard Worker mGpuStats.vulkanVersion = vulkanVersion;
395*38e8c45fSAndroid Build Coastguard Worker }
396*38e8c45fSAndroid Build Coastguard Worker
setDriverToLoad(GpuStatsInfo::Driver driver)397*38e8c45fSAndroid Build Coastguard Worker void GraphicsEnv::setDriverToLoad(GpuStatsInfo::Driver driver) {
398*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
399*38e8c45fSAndroid Build Coastguard Worker
400*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mStatsLock);
401*38e8c45fSAndroid Build Coastguard Worker switch (driver) {
402*38e8c45fSAndroid Build Coastguard Worker case GpuStatsInfo::Driver::GL:
403*38e8c45fSAndroid Build Coastguard Worker case GpuStatsInfo::Driver::GL_UPDATED:
404*38e8c45fSAndroid Build Coastguard Worker case GpuStatsInfo::Driver::ANGLE:
405*38e8c45fSAndroid Build Coastguard Worker mGpuStats.glDriverToLoad = driver;
406*38e8c45fSAndroid Build Coastguard Worker break;
407*38e8c45fSAndroid Build Coastguard Worker
408*38e8c45fSAndroid Build Coastguard Worker case GpuStatsInfo::Driver::VULKAN:
409*38e8c45fSAndroid Build Coastguard Worker case GpuStatsInfo::Driver::VULKAN_UPDATED: {
410*38e8c45fSAndroid Build Coastguard Worker if (mGpuStats.vkDriverToLoad == GpuStatsInfo::Driver::NONE ||
411*38e8c45fSAndroid Build Coastguard Worker mGpuStats.vkDriverToLoad == GpuStatsInfo::Driver::VULKAN) {
412*38e8c45fSAndroid Build Coastguard Worker mGpuStats.vkDriverToLoad = driver;
413*38e8c45fSAndroid Build Coastguard Worker break;
414*38e8c45fSAndroid Build Coastguard Worker }
415*38e8c45fSAndroid Build Coastguard Worker
416*38e8c45fSAndroid Build Coastguard Worker if (mGpuStats.vkDriverFallback == GpuStatsInfo::Driver::NONE) {
417*38e8c45fSAndroid Build Coastguard Worker mGpuStats.vkDriverFallback = driver;
418*38e8c45fSAndroid Build Coastguard Worker }
419*38e8c45fSAndroid Build Coastguard Worker break;
420*38e8c45fSAndroid Build Coastguard Worker }
421*38e8c45fSAndroid Build Coastguard Worker default:
422*38e8c45fSAndroid Build Coastguard Worker break;
423*38e8c45fSAndroid Build Coastguard Worker }
424*38e8c45fSAndroid Build Coastguard Worker }
425*38e8c45fSAndroid Build Coastguard Worker
setDriverLoaded(GpuStatsInfo::Api api,bool isDriverLoaded,int64_t driverLoadingTime)426*38e8c45fSAndroid Build Coastguard Worker void GraphicsEnv::setDriverLoaded(GpuStatsInfo::Api api, bool isDriverLoaded,
427*38e8c45fSAndroid Build Coastguard Worker int64_t driverLoadingTime) {
428*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
429*38e8c45fSAndroid Build Coastguard Worker
430*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mStatsLock);
431*38e8c45fSAndroid Build Coastguard Worker if (api == GpuStatsInfo::Api::API_GL) {
432*38e8c45fSAndroid Build Coastguard Worker mGpuStats.glDriverToSend = true;
433*38e8c45fSAndroid Build Coastguard Worker mGpuStats.glDriverLoadingTime = driverLoadingTime;
434*38e8c45fSAndroid Build Coastguard Worker } else {
435*38e8c45fSAndroid Build Coastguard Worker mGpuStats.vkDriverToSend = true;
436*38e8c45fSAndroid Build Coastguard Worker mGpuStats.vkDriverLoadingTime = driverLoadingTime;
437*38e8c45fSAndroid Build Coastguard Worker }
438*38e8c45fSAndroid Build Coastguard Worker
439*38e8c45fSAndroid Build Coastguard Worker sendGpuStatsLocked(api, isDriverLoaded, driverLoadingTime);
440*38e8c45fSAndroid Build Coastguard Worker }
441*38e8c45fSAndroid Build Coastguard Worker
442*38e8c45fSAndroid Build Coastguard Worker // Hash function to calculate hash for null-terminated Vulkan extension names
443*38e8c45fSAndroid Build Coastguard Worker // We store hash values of the extensions, rather than the actual names or
444*38e8c45fSAndroid Build Coastguard Worker // indices to be able to support new extensions easily, avoid creating
445*38e8c45fSAndroid Build Coastguard Worker // a table of 'known' extensions inside Android and reduce the runtime overhead.
calculateExtensionHash(const char * word)446*38e8c45fSAndroid Build Coastguard Worker static uint64_t calculateExtensionHash(const char* word) {
447*38e8c45fSAndroid Build Coastguard Worker if (!word) {
448*38e8c45fSAndroid Build Coastguard Worker return 0;
449*38e8c45fSAndroid Build Coastguard Worker }
450*38e8c45fSAndroid Build Coastguard Worker const size_t wordLen = strlen(word);
451*38e8c45fSAndroid Build Coastguard Worker const uint32_t seed = 167;
452*38e8c45fSAndroid Build Coastguard Worker uint64_t hash = 0;
453*38e8c45fSAndroid Build Coastguard Worker for (size_t i = 0; i < wordLen; i++) {
454*38e8c45fSAndroid Build Coastguard Worker hash = (hash * seed) + word[i];
455*38e8c45fSAndroid Build Coastguard Worker }
456*38e8c45fSAndroid Build Coastguard Worker return hash;
457*38e8c45fSAndroid Build Coastguard Worker }
458*38e8c45fSAndroid Build Coastguard Worker
setVulkanInstanceExtensions(uint32_t enabledExtensionCount,const char * const * ppEnabledExtensionNames)459*38e8c45fSAndroid Build Coastguard Worker void GraphicsEnv::setVulkanInstanceExtensions(uint32_t enabledExtensionCount,
460*38e8c45fSAndroid Build Coastguard Worker const char* const* ppEnabledExtensionNames) {
461*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
462*38e8c45fSAndroid Build Coastguard Worker if (enabledExtensionCount == 0 || ppEnabledExtensionNames == nullptr) {
463*38e8c45fSAndroid Build Coastguard Worker return;
464*38e8c45fSAndroid Build Coastguard Worker }
465*38e8c45fSAndroid Build Coastguard Worker
466*38e8c45fSAndroid Build Coastguard Worker const uint32_t maxNumStats = android::GpuStatsAppInfo::MAX_NUM_EXTENSIONS;
467*38e8c45fSAndroid Build Coastguard Worker uint64_t extensionHashes[maxNumStats];
468*38e8c45fSAndroid Build Coastguard Worker const uint32_t numStats = std::min(enabledExtensionCount, maxNumStats);
469*38e8c45fSAndroid Build Coastguard Worker for(uint32_t i = 0; i < numStats; i++) {
470*38e8c45fSAndroid Build Coastguard Worker extensionHashes[i] = calculateExtensionHash(ppEnabledExtensionNames[i]);
471*38e8c45fSAndroid Build Coastguard Worker }
472*38e8c45fSAndroid Build Coastguard Worker setTargetStatsArray(android::GpuStatsInfo::Stats::VULKAN_INSTANCE_EXTENSION,
473*38e8c45fSAndroid Build Coastguard Worker extensionHashes, numStats);
474*38e8c45fSAndroid Build Coastguard Worker }
475*38e8c45fSAndroid Build Coastguard Worker
setVulkanDeviceExtensions(uint32_t enabledExtensionCount,const char * const * ppEnabledExtensionNames)476*38e8c45fSAndroid Build Coastguard Worker void GraphicsEnv::setVulkanDeviceExtensions(uint32_t enabledExtensionCount,
477*38e8c45fSAndroid Build Coastguard Worker const char* const* ppEnabledExtensionNames) {
478*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
479*38e8c45fSAndroid Build Coastguard Worker if (enabledExtensionCount == 0 || ppEnabledExtensionNames == nullptr) {
480*38e8c45fSAndroid Build Coastguard Worker return;
481*38e8c45fSAndroid Build Coastguard Worker }
482*38e8c45fSAndroid Build Coastguard Worker
483*38e8c45fSAndroid Build Coastguard Worker const uint32_t maxNumStats = android::GpuStatsAppInfo::MAX_NUM_EXTENSIONS;
484*38e8c45fSAndroid Build Coastguard Worker uint64_t extensionHashes[maxNumStats];
485*38e8c45fSAndroid Build Coastguard Worker const uint32_t numStats = std::min(enabledExtensionCount, maxNumStats);
486*38e8c45fSAndroid Build Coastguard Worker for(uint32_t i = 0; i < numStats; i++) {
487*38e8c45fSAndroid Build Coastguard Worker extensionHashes[i] = calculateExtensionHash(ppEnabledExtensionNames[i]);
488*38e8c45fSAndroid Build Coastguard Worker }
489*38e8c45fSAndroid Build Coastguard Worker setTargetStatsArray(android::GpuStatsInfo::Stats::VULKAN_DEVICE_EXTENSION,
490*38e8c45fSAndroid Build Coastguard Worker extensionHashes, numStats);
491*38e8c45fSAndroid Build Coastguard Worker }
492*38e8c45fSAndroid Build Coastguard Worker
addVulkanEngineName(const char * engineName)493*38e8c45fSAndroid Build Coastguard Worker void GraphicsEnv::addVulkanEngineName(const char* engineName) {
494*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
495*38e8c45fSAndroid Build Coastguard Worker if (engineName == nullptr) {
496*38e8c45fSAndroid Build Coastguard Worker return;
497*38e8c45fSAndroid Build Coastguard Worker }
498*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mStatsLock);
499*38e8c45fSAndroid Build Coastguard Worker if (!readyToSendGpuStatsLocked()) return;
500*38e8c45fSAndroid Build Coastguard Worker
501*38e8c45fSAndroid Build Coastguard Worker const sp<IGpuService> gpuService = getGpuService();
502*38e8c45fSAndroid Build Coastguard Worker if (gpuService) {
503*38e8c45fSAndroid Build Coastguard Worker gpuService->addVulkanEngineName(mGpuStats.appPackageName, mGpuStats.driverVersionCode,
504*38e8c45fSAndroid Build Coastguard Worker engineName);
505*38e8c45fSAndroid Build Coastguard Worker }
506*38e8c45fSAndroid Build Coastguard Worker }
507*38e8c45fSAndroid Build Coastguard Worker
readyToSendGpuStatsLocked()508*38e8c45fSAndroid Build Coastguard Worker bool GraphicsEnv::readyToSendGpuStatsLocked() {
509*38e8c45fSAndroid Build Coastguard Worker // Only send stats for processes having at least one activity launched and that process doesn't
510*38e8c45fSAndroid Build Coastguard Worker // skip the GraphicsEnvironment setup.
511*38e8c45fSAndroid Build Coastguard Worker return mActivityLaunched && !mGpuStats.appPackageName.empty();
512*38e8c45fSAndroid Build Coastguard Worker }
513*38e8c45fSAndroid Build Coastguard Worker
setTargetStats(const GpuStatsInfo::Stats stats,const uint64_t value)514*38e8c45fSAndroid Build Coastguard Worker void GraphicsEnv::setTargetStats(const GpuStatsInfo::Stats stats, const uint64_t value) {
515*38e8c45fSAndroid Build Coastguard Worker return setTargetStatsArray(stats, &value, 1);
516*38e8c45fSAndroid Build Coastguard Worker }
517*38e8c45fSAndroid Build Coastguard Worker
setTargetStatsArray(const GpuStatsInfo::Stats stats,const uint64_t * values,const uint32_t valueCount)518*38e8c45fSAndroid Build Coastguard Worker void GraphicsEnv::setTargetStatsArray(const GpuStatsInfo::Stats stats, const uint64_t* values,
519*38e8c45fSAndroid Build Coastguard Worker const uint32_t valueCount) {
520*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
521*38e8c45fSAndroid Build Coastguard Worker
522*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mStatsLock);
523*38e8c45fSAndroid Build Coastguard Worker if (!readyToSendGpuStatsLocked()) return;
524*38e8c45fSAndroid Build Coastguard Worker
525*38e8c45fSAndroid Build Coastguard Worker const sp<IGpuService> gpuService = getGpuService();
526*38e8c45fSAndroid Build Coastguard Worker if (gpuService) {
527*38e8c45fSAndroid Build Coastguard Worker gpuService->setTargetStatsArray(mGpuStats.appPackageName, mGpuStats.driverVersionCode,
528*38e8c45fSAndroid Build Coastguard Worker stats, values, valueCount);
529*38e8c45fSAndroid Build Coastguard Worker }
530*38e8c45fSAndroid Build Coastguard Worker }
531*38e8c45fSAndroid Build Coastguard Worker
sendGpuStatsLocked(GpuStatsInfo::Api api,bool isDriverLoaded,int64_t driverLoadingTime)532*38e8c45fSAndroid Build Coastguard Worker void GraphicsEnv::sendGpuStatsLocked(GpuStatsInfo::Api api, bool isDriverLoaded,
533*38e8c45fSAndroid Build Coastguard Worker int64_t driverLoadingTime) {
534*38e8c45fSAndroid Build Coastguard Worker ATRACE_CALL();
535*38e8c45fSAndroid Build Coastguard Worker
536*38e8c45fSAndroid Build Coastguard Worker if (!readyToSendGpuStatsLocked()) return;
537*38e8c45fSAndroid Build Coastguard Worker
538*38e8c45fSAndroid Build Coastguard Worker ALOGV("sendGpuStats:\n"
539*38e8c45fSAndroid Build Coastguard Worker "\tdriverPackageName[%s]\n"
540*38e8c45fSAndroid Build Coastguard Worker "\tdriverVersionName[%s]\n"
541*38e8c45fSAndroid Build Coastguard Worker "\tdriverVersionCode[%" PRIu64 "]\n"
542*38e8c45fSAndroid Build Coastguard Worker "\tdriverBuildTime[%" PRId64 "]\n"
543*38e8c45fSAndroid Build Coastguard Worker "\tappPackageName[%s]\n"
544*38e8c45fSAndroid Build Coastguard Worker "\tvulkanVersion[%d]\n"
545*38e8c45fSAndroid Build Coastguard Worker "\tapi[%d]\n"
546*38e8c45fSAndroid Build Coastguard Worker "\tisDriverLoaded[%d]\n"
547*38e8c45fSAndroid Build Coastguard Worker "\tdriverLoadingTime[%" PRId64 "]",
548*38e8c45fSAndroid Build Coastguard Worker mGpuStats.driverPackageName.c_str(), mGpuStats.driverVersionName.c_str(),
549*38e8c45fSAndroid Build Coastguard Worker mGpuStats.driverVersionCode, mGpuStats.driverBuildTime, mGpuStats.appPackageName.c_str(),
550*38e8c45fSAndroid Build Coastguard Worker mGpuStats.vulkanVersion, static_cast<int32_t>(api), isDriverLoaded, driverLoadingTime);
551*38e8c45fSAndroid Build Coastguard Worker
552*38e8c45fSAndroid Build Coastguard Worker GpuStatsInfo::Driver driver = GpuStatsInfo::Driver::NONE;
553*38e8c45fSAndroid Build Coastguard Worker bool isIntendedDriverLoaded = false;
554*38e8c45fSAndroid Build Coastguard Worker if (api == GpuStatsInfo::Api::API_GL) {
555*38e8c45fSAndroid Build Coastguard Worker driver = mGpuStats.glDriverToLoad;
556*38e8c45fSAndroid Build Coastguard Worker isIntendedDriverLoaded = isDriverLoaded;
557*38e8c45fSAndroid Build Coastguard Worker } else {
558*38e8c45fSAndroid Build Coastguard Worker driver = mGpuStats.vkDriverToLoad;
559*38e8c45fSAndroid Build Coastguard Worker isIntendedDriverLoaded =
560*38e8c45fSAndroid Build Coastguard Worker isDriverLoaded && (mGpuStats.vkDriverFallback == GpuStatsInfo::Driver::NONE);
561*38e8c45fSAndroid Build Coastguard Worker }
562*38e8c45fSAndroid Build Coastguard Worker
563*38e8c45fSAndroid Build Coastguard Worker const sp<IGpuService> gpuService = getGpuService();
564*38e8c45fSAndroid Build Coastguard Worker if (gpuService) {
565*38e8c45fSAndroid Build Coastguard Worker gpuService->setGpuStats(mGpuStats.driverPackageName, mGpuStats.driverVersionName,
566*38e8c45fSAndroid Build Coastguard Worker mGpuStats.driverVersionCode, mGpuStats.driverBuildTime,
567*38e8c45fSAndroid Build Coastguard Worker mGpuStats.appPackageName, mGpuStats.vulkanVersion, driver,
568*38e8c45fSAndroid Build Coastguard Worker isIntendedDriverLoaded, driverLoadingTime);
569*38e8c45fSAndroid Build Coastguard Worker }
570*38e8c45fSAndroid Build Coastguard Worker }
571*38e8c45fSAndroid Build Coastguard Worker
setInjectLayersPrSetDumpable()572*38e8c45fSAndroid Build Coastguard Worker bool GraphicsEnv::setInjectLayersPrSetDumpable() {
573*38e8c45fSAndroid Build Coastguard Worker if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) {
574*38e8c45fSAndroid Build Coastguard Worker return false;
575*38e8c45fSAndroid Build Coastguard Worker }
576*38e8c45fSAndroid Build Coastguard Worker return true;
577*38e8c45fSAndroid Build Coastguard Worker }
578*38e8c45fSAndroid Build Coastguard Worker
579*38e8c45fSAndroid Build Coastguard Worker /**
580*38e8c45fSAndroid Build Coastguard Worker * APIs for ANGLE
581*38e8c45fSAndroid Build Coastguard Worker */
582*38e8c45fSAndroid Build Coastguard Worker
shouldUseAngle()583*38e8c45fSAndroid Build Coastguard Worker bool GraphicsEnv::shouldUseAngle() {
584*38e8c45fSAndroid Build Coastguard Worker // Make sure we are init'ed
585*38e8c45fSAndroid Build Coastguard Worker if (mPackageName.empty()) {
586*38e8c45fSAndroid Build Coastguard Worker ALOGV("Package name is empty. setAngleInfo() has not been called to enable ANGLE.");
587*38e8c45fSAndroid Build Coastguard Worker return false;
588*38e8c45fSAndroid Build Coastguard Worker }
589*38e8c45fSAndroid Build Coastguard Worker
590*38e8c45fSAndroid Build Coastguard Worker return mShouldUseAngle;
591*38e8c45fSAndroid Build Coastguard Worker }
592*38e8c45fSAndroid Build Coastguard Worker
593*38e8c45fSAndroid Build Coastguard Worker // Set ANGLE information.
594*38e8c45fSAndroid Build Coastguard Worker // If path is "system", it means system ANGLE must be used for the process.
595*38e8c45fSAndroid Build Coastguard Worker // If shouldUseNativeDriver is true, it means native GLES drivers must be used for the process.
596*38e8c45fSAndroid Build Coastguard Worker // If path is set to nonempty and shouldUseNativeDriver is true, ANGLE will be used regardless.
setAngleInfo(const std::string & path,const bool shouldUseNativeDriver,const std::string & packageName,const std::vector<std::string> eglFeatures)597*38e8c45fSAndroid Build Coastguard Worker void GraphicsEnv::setAngleInfo(const std::string& path, const bool shouldUseNativeDriver,
598*38e8c45fSAndroid Build Coastguard Worker const std::string& packageName,
599*38e8c45fSAndroid Build Coastguard Worker const std::vector<std::string> eglFeatures) {
600*38e8c45fSAndroid Build Coastguard Worker if (mShouldUseAngle) {
601*38e8c45fSAndroid Build Coastguard Worker // ANGLE is already set up for this application process, even if the application
602*38e8c45fSAndroid Build Coastguard Worker // needs to switch from apk to system or vice versa, the application process must
603*38e8c45fSAndroid Build Coastguard Worker // be killed and relaunch so that the loader can properly load ANGLE again.
604*38e8c45fSAndroid Build Coastguard Worker // The architecture does not support runtime switch between drivers, so just return.
605*38e8c45fSAndroid Build Coastguard Worker ALOGE("ANGLE is already set for %s", packageName.c_str());
606*38e8c45fSAndroid Build Coastguard Worker return;
607*38e8c45fSAndroid Build Coastguard Worker }
608*38e8c45fSAndroid Build Coastguard Worker
609*38e8c45fSAndroid Build Coastguard Worker mAngleEglFeatures = std::move(eglFeatures);
610*38e8c45fSAndroid Build Coastguard Worker ALOGV("setting ANGLE path to '%s'", path.c_str());
611*38e8c45fSAndroid Build Coastguard Worker mAnglePath = std::move(path);
612*38e8c45fSAndroid Build Coastguard Worker ALOGV("setting app package name to '%s'", packageName.c_str());
613*38e8c45fSAndroid Build Coastguard Worker mPackageName = std::move(packageName);
614*38e8c45fSAndroid Build Coastguard Worker if (mAnglePath == "system") {
615*38e8c45fSAndroid Build Coastguard Worker mShouldUseSystemAngle = true;
616*38e8c45fSAndroid Build Coastguard Worker }
617*38e8c45fSAndroid Build Coastguard Worker if (!mAnglePath.empty()) {
618*38e8c45fSAndroid Build Coastguard Worker mShouldUseAngle = true;
619*38e8c45fSAndroid Build Coastguard Worker }
620*38e8c45fSAndroid Build Coastguard Worker mShouldUseNativeDriver = shouldUseNativeDriver;
621*38e8c45fSAndroid Build Coastguard Worker }
622*38e8c45fSAndroid Build Coastguard Worker
getPackageName()623*38e8c45fSAndroid Build Coastguard Worker std::string& GraphicsEnv::getPackageName() {
624*38e8c45fSAndroid Build Coastguard Worker return mPackageName;
625*38e8c45fSAndroid Build Coastguard Worker }
626*38e8c45fSAndroid Build Coastguard Worker
getAngleEglFeatures()627*38e8c45fSAndroid Build Coastguard Worker const std::vector<std::string>& GraphicsEnv::getAngleEglFeatures() {
628*38e8c45fSAndroid Build Coastguard Worker return mAngleEglFeatures;
629*38e8c45fSAndroid Build Coastguard Worker }
630*38e8c45fSAndroid Build Coastguard Worker
getAngleNamespace()631*38e8c45fSAndroid Build Coastguard Worker android_namespace_t* GraphicsEnv::getAngleNamespace() {
632*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mNamespaceMutex);
633*38e8c45fSAndroid Build Coastguard Worker
634*38e8c45fSAndroid Build Coastguard Worker if (mAngleNamespace) {
635*38e8c45fSAndroid Build Coastguard Worker return mAngleNamespace;
636*38e8c45fSAndroid Build Coastguard Worker }
637*38e8c45fSAndroid Build Coastguard Worker
638*38e8c45fSAndroid Build Coastguard Worker // If ANGLE path is not set, it means ANGLE should not be used for this process;
639*38e8c45fSAndroid Build Coastguard Worker // or if ANGLE path is set and set to use system ANGLE, then a namespace is not needed
640*38e8c45fSAndroid Build Coastguard Worker // because:
641*38e8c45fSAndroid Build Coastguard Worker // 1) if the default OpenGL ES driver is already ANGLE, then the loader will skip;
642*38e8c45fSAndroid Build Coastguard Worker // 2) if the default OpenGL ES driver is native, then there's no symbol conflict;
643*38e8c45fSAndroid Build Coastguard Worker // 3) if there's no OpenGL ES driver is preloaded, then there's no symbol conflict.
644*38e8c45fSAndroid Build Coastguard Worker if (mAnglePath.empty() || mShouldUseSystemAngle) {
645*38e8c45fSAndroid Build Coastguard Worker ALOGV("mAnglePath is empty or use system ANGLE, abort creating ANGLE namespace");
646*38e8c45fSAndroid Build Coastguard Worker return nullptr;
647*38e8c45fSAndroid Build Coastguard Worker }
648*38e8c45fSAndroid Build Coastguard Worker
649*38e8c45fSAndroid Build Coastguard Worker // Construct the search paths for system ANGLE.
650*38e8c45fSAndroid Build Coastguard Worker const char* const defaultLibraryPaths =
651*38e8c45fSAndroid Build Coastguard Worker #if defined(__LP64__)
652*38e8c45fSAndroid Build Coastguard Worker "/vendor/lib64/egl:/system/lib64";
653*38e8c45fSAndroid Build Coastguard Worker #else
654*38e8c45fSAndroid Build Coastguard Worker "/vendor/lib/egl:/system/lib";
655*38e8c45fSAndroid Build Coastguard Worker #endif
656*38e8c45fSAndroid Build Coastguard Worker
657*38e8c45fSAndroid Build Coastguard Worker // If the application process will run on top of system ANGLE, construct the namespace
658*38e8c45fSAndroid Build Coastguard Worker // with sphal namespace being the parent namespace so that search paths and libraries
659*38e8c45fSAndroid Build Coastguard Worker // are properly inherited.
660*38e8c45fSAndroid Build Coastguard Worker mAngleNamespace =
661*38e8c45fSAndroid Build Coastguard Worker android_create_namespace("ANGLE",
662*38e8c45fSAndroid Build Coastguard Worker mShouldUseSystemAngle ? defaultLibraryPaths
663*38e8c45fSAndroid Build Coastguard Worker : mAnglePath.c_str(), // ld_library_path
664*38e8c45fSAndroid Build Coastguard Worker mShouldUseSystemAngle
665*38e8c45fSAndroid Build Coastguard Worker ? defaultLibraryPaths
666*38e8c45fSAndroid Build Coastguard Worker : mAnglePath.c_str(), // default_library_path
667*38e8c45fSAndroid Build Coastguard Worker ANDROID_NAMESPACE_TYPE_SHARED_ISOLATED,
668*38e8c45fSAndroid Build Coastguard Worker nullptr, // permitted_when_isolated_path
669*38e8c45fSAndroid Build Coastguard Worker mShouldUseSystemAngle ? android_get_exported_namespace("sphal")
670*38e8c45fSAndroid Build Coastguard Worker : nullptr); // parent
671*38e8c45fSAndroid Build Coastguard Worker
672*38e8c45fSAndroid Build Coastguard Worker ALOGD_IF(!mAngleNamespace, "Could not create ANGLE namespace from default");
673*38e8c45fSAndroid Build Coastguard Worker
674*38e8c45fSAndroid Build Coastguard Worker if (!mShouldUseSystemAngle) {
675*38e8c45fSAndroid Build Coastguard Worker return mAngleNamespace;
676*38e8c45fSAndroid Build Coastguard Worker }
677*38e8c45fSAndroid Build Coastguard Worker
678*38e8c45fSAndroid Build Coastguard Worker auto vndkNamespace = android_get_exported_namespace(isVndkEnabled() ? "vndk" : "sphal");
679*38e8c45fSAndroid Build Coastguard Worker if (!vndkNamespace) {
680*38e8c45fSAndroid Build Coastguard Worker mAngleNamespace = nullptr;
681*38e8c45fSAndroid Build Coastguard Worker return mAngleNamespace;
682*38e8c45fSAndroid Build Coastguard Worker }
683*38e8c45fSAndroid Build Coastguard Worker
684*38e8c45fSAndroid Build Coastguard Worker if (!linkDriverNamespaceLocked(mAngleNamespace, vndkNamespace, "")) {
685*38e8c45fSAndroid Build Coastguard Worker mAngleNamespace = nullptr;
686*38e8c45fSAndroid Build Coastguard Worker }
687*38e8c45fSAndroid Build Coastguard Worker
688*38e8c45fSAndroid Build Coastguard Worker return mAngleNamespace;
689*38e8c45fSAndroid Build Coastguard Worker }
690*38e8c45fSAndroid Build Coastguard Worker
nativeToggleAngleAsSystemDriver(bool enabled)691*38e8c45fSAndroid Build Coastguard Worker void GraphicsEnv::nativeToggleAngleAsSystemDriver(bool enabled) {
692*38e8c45fSAndroid Build Coastguard Worker const sp<IGpuService> gpuService = getGpuService();
693*38e8c45fSAndroid Build Coastguard Worker if (!gpuService) {
694*38e8c45fSAndroid Build Coastguard Worker ALOGE("No GPU service");
695*38e8c45fSAndroid Build Coastguard Worker return;
696*38e8c45fSAndroid Build Coastguard Worker }
697*38e8c45fSAndroid Build Coastguard Worker gpuService->toggleAngleAsSystemDriver(enabled);
698*38e8c45fSAndroid Build Coastguard Worker }
699*38e8c45fSAndroid Build Coastguard Worker
shouldUseSystemAngle()700*38e8c45fSAndroid Build Coastguard Worker bool GraphicsEnv::shouldUseSystemAngle() {
701*38e8c45fSAndroid Build Coastguard Worker return mShouldUseSystemAngle;
702*38e8c45fSAndroid Build Coastguard Worker }
703*38e8c45fSAndroid Build Coastguard Worker
shouldUseNativeDriver()704*38e8c45fSAndroid Build Coastguard Worker bool GraphicsEnv::shouldUseNativeDriver() {
705*38e8c45fSAndroid Build Coastguard Worker return mShouldUseNativeDriver;
706*38e8c45fSAndroid Build Coastguard Worker }
707*38e8c45fSAndroid Build Coastguard Worker
708*38e8c45fSAndroid Build Coastguard Worker /**
709*38e8c45fSAndroid Build Coastguard Worker * APIs for debuggable layers
710*38e8c45fSAndroid Build Coastguard Worker */
711*38e8c45fSAndroid Build Coastguard Worker
setLayerPaths(NativeLoaderNamespace * appNamespace,const std::string & layerPaths)712*38e8c45fSAndroid Build Coastguard Worker void GraphicsEnv::setLayerPaths(NativeLoaderNamespace* appNamespace,
713*38e8c45fSAndroid Build Coastguard Worker const std::string& layerPaths) {
714*38e8c45fSAndroid Build Coastguard Worker if (mLayerPaths.empty()) {
715*38e8c45fSAndroid Build Coastguard Worker mLayerPaths = layerPaths;
716*38e8c45fSAndroid Build Coastguard Worker mAppNamespace = appNamespace;
717*38e8c45fSAndroid Build Coastguard Worker } else {
718*38e8c45fSAndroid Build Coastguard Worker ALOGV("Vulkan layer search path already set, not clobbering with '%s' for namespace %p'",
719*38e8c45fSAndroid Build Coastguard Worker layerPaths.c_str(), appNamespace);
720*38e8c45fSAndroid Build Coastguard Worker }
721*38e8c45fSAndroid Build Coastguard Worker }
722*38e8c45fSAndroid Build Coastguard Worker
getAppNamespace()723*38e8c45fSAndroid Build Coastguard Worker NativeLoaderNamespace* GraphicsEnv::getAppNamespace() {
724*38e8c45fSAndroid Build Coastguard Worker return mAppNamespace;
725*38e8c45fSAndroid Build Coastguard Worker }
726*38e8c45fSAndroid Build Coastguard Worker
getLayerPaths()727*38e8c45fSAndroid Build Coastguard Worker const std::string& GraphicsEnv::getLayerPaths() {
728*38e8c45fSAndroid Build Coastguard Worker return mLayerPaths;
729*38e8c45fSAndroid Build Coastguard Worker }
730*38e8c45fSAndroid Build Coastguard Worker
getDebugLayers()731*38e8c45fSAndroid Build Coastguard Worker const std::string& GraphicsEnv::getDebugLayers() {
732*38e8c45fSAndroid Build Coastguard Worker return mDebugLayers;
733*38e8c45fSAndroid Build Coastguard Worker }
734*38e8c45fSAndroid Build Coastguard Worker
getDebugLayersGLES()735*38e8c45fSAndroid Build Coastguard Worker const std::string& GraphicsEnv::getDebugLayersGLES() {
736*38e8c45fSAndroid Build Coastguard Worker return mDebugLayersGLES;
737*38e8c45fSAndroid Build Coastguard Worker }
738*38e8c45fSAndroid Build Coastguard Worker
setDebugLayers(const std::string & layers)739*38e8c45fSAndroid Build Coastguard Worker void GraphicsEnv::setDebugLayers(const std::string& layers) {
740*38e8c45fSAndroid Build Coastguard Worker mDebugLayers = layers;
741*38e8c45fSAndroid Build Coastguard Worker }
742*38e8c45fSAndroid Build Coastguard Worker
setDebugLayersGLES(const std::string & layers)743*38e8c45fSAndroid Build Coastguard Worker void GraphicsEnv::setDebugLayersGLES(const std::string& layers) {
744*38e8c45fSAndroid Build Coastguard Worker mDebugLayersGLES = layers;
745*38e8c45fSAndroid Build Coastguard Worker }
746*38e8c45fSAndroid Build Coastguard Worker
747*38e8c45fSAndroid Build Coastguard Worker } // namespace android
748