xref: /aosp_15_r20/frameworks/native/libs/graphicsenv/GraphicsEnv.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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