xref: /aosp_15_r20/frameworks/native/opengl/libs/EGL/Loader.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
2  ** Copyright 2007, The Android Open Source Project
3  **
4  ** Licensed under the Apache License, Version 2.0 (the "License");
5  ** you may not use this file except in compliance with the License.
6  ** You may obtain a copy of the License at
7  **
8  **     http://www.apache.org/licenses/LICENSE-2.0
9  **
10  ** Unless required by applicable law or agreed to in writing, software
11  ** distributed under the License is distributed on an "AS IS" BASIS,
12  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  ** See the License for the specific language governing permissions and
14  ** limitations under the License.
15  */
16 
17 //#define LOG_NDEBUG 0
18 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
19 
20 #include "EGL/Loader.h"
21 
22 #include <android-base/properties.h>
23 #include <android/dlext.h>
24 #include <cutils/properties.h>
25 #include <dirent.h>
26 #include <dlfcn.h>
27 #include <graphicsenv/GraphicsEnv.h>
28 #include <log/log.h>
29 #include <utils/Timers.h>
30 #include <vndksupport/linker.h>
31 
32 #include <string>
33 
34 #include "EGL/eglext_angle.h"
35 #include "egl_platform_entries.h"
36 #include "egl_trace.h"
37 #include "egldefs.h"
38 
39 namespace android {
40 
41 /*
42  * EGL userspace drivers must be provided either:
43  * - as a single library:
44  *      /vendor/${LIB}/egl/libGLES.so
45  *
46  * - as separate libraries:
47  *      /vendor/${LIB}/egl/libEGL.so
48  *      /vendor/${LIB}/egl/libGLESv1_CM.so
49  *      /vendor/${LIB}/egl/libGLESv2.so
50  *
51  * For backward compatibility and to facilitate the transition to
52  * this new naming scheme, the loader will additionally look for:
53  *
54  *      /vendor/${LIB}/egl/lib{GLES | [EGL|GLESv1_CM|GLESv2]}_${SUFFIX}.so
55  *
56  */
57 
58 #ifndef SYSTEM_LIB_PATH
59 #if defined(__LP64__)
60 #define SYSTEM_LIB_PATH "/system/lib64"
61 #else
62 #define SYSTEM_LIB_PATH "/system/lib"
63 #endif
64 #endif
65 
66 static const char* PERSIST_DRIVER_SUFFIX_PROPERTY = "persist.graphics.egl";
67 static const char* RO_DRIVER_SUFFIX_PROPERTY = "ro.hardware.egl";
68 static const char* RO_BOARD_PLATFORM_PROPERTY = "ro.board.platform";
69 static const char* ANGLE_SUFFIX_VALUE = "angle";
70 
71 static const char* HAL_SUBNAME_KEY_PROPERTIES[3] = {
72         PERSIST_DRIVER_SUFFIX_PROPERTY,
73         RO_DRIVER_SUFFIX_PROPERTY,
74         RO_BOARD_PLATFORM_PROPERTY,
75 };
76 
77 static const char* const VENDOR_LIB_EGL_DIR =
78 #if defined(__LP64__)
79         "/vendor/lib64/egl";
80 #else
81         "/vendor/lib/egl";
82 #endif
83 
84 static const char* const SYSTEM_LIB_DIR =
85 #if defined(__LP64__)
86         "/system/lib64";
87 #else
88         "/system/lib";
89 #endif
90 
do_dlopen(const char * path,int mode)91 static void* do_dlopen(const char* path, int mode) {
92     ATRACE_CALL();
93     return dlopen(path, mode);
94 }
95 
do_android_dlopen_ext(const char * path,int mode,const android_dlextinfo * info)96 static void* do_android_dlopen_ext(const char* path, int mode, const android_dlextinfo* info) {
97     ATRACE_CALL();
98     return android_dlopen_ext(path, mode, info);
99 }
100 
do_android_load_sphal_library(const char * path,int mode)101 static void* do_android_load_sphal_library(const char* path, int mode) {
102     ATRACE_CALL();
103     return android_load_sphal_library(path, mode);
104 }
105 
do_android_unload_sphal_library(void * dso)106 static int do_android_unload_sphal_library(void* dso) {
107     ATRACE_CALL();
108     return android_unload_sphal_library(dso);
109 }
110 
load_wrapper(const char * path)111 static void* load_wrapper(const char* path) {
112     void* so = do_dlopen(path, RTLD_NOW | RTLD_LOCAL);
113     ALOGE_IF(!so, "dlopen(\"%s\") failed: %s", path, dlerror());
114     return so;
115 }
116 
getInstance()117 Loader& Loader::getInstance() {
118     static Loader loader;
119     return loader;
120 }
121 
driver_t(void * gles)122 Loader::driver_t::driver_t(void* gles)
123 {
124     dso[0] = gles;
125     for (size_t i=1 ; i<NELEM(dso) ; i++)
126         dso[i] = nullptr;
127 }
128 
~driver_t()129 Loader::driver_t::~driver_t()
130 {
131     for (size_t i=0 ; i<NELEM(dso) ; i++) {
132         if (dso[i]) {
133             dlclose(dso[i]);
134             dso[i] = nullptr;
135         }
136     }
137 }
138 
set(void * hnd,int32_t api)139 int Loader::driver_t::set(void* hnd, int32_t api)
140 {
141     switch (api) {
142         case EGL:
143             dso[0] = hnd;
144             break;
145         case GLESv1_CM:
146             dso[1] = hnd;
147             break;
148         case GLESv2:
149             dso[2] = hnd;
150             break;
151         default:
152             return -EOVERFLOW;
153     }
154     return 0;
155 }
156 
Loader()157 Loader::Loader()
158     : getProcAddress(nullptr)
159 {
160 }
161 
~Loader()162 Loader::~Loader() {
163 }
164 
165 // Check whether the loaded system drivers should be unloaded in order to
166 // load ANGLE or the updatable graphics drivers.
167 // If ANGLE namespace is set, it means the application is identified to run on top of ANGLE.
168 // If updatable graphics driver namespace is set, it means the application is identified to
169 // run on top of updatable graphics drivers.
should_unload_system_driver(egl_connection_t * cnx)170 static bool should_unload_system_driver(egl_connection_t* cnx) {
171     // Return false if the system driver has been unloaded once.
172     if (cnx->systemDriverUnloaded) {
173         return false;
174     }
175 
176     // Return true if ANGLE namespace is set.
177     android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace();
178     if (ns) {
179         // Unless the default GLES driver is ANGLE and the process should use system ANGLE, since
180         // the intended GLES driver is already loaded.
181         // This should be updated in a later patch that cleans up namespaces
182         if (!(cnx->angleLoaded && android::GraphicsEnv::getInstance().shouldUseSystemAngle())) {
183             return true;
184         }
185     }
186 
187     // Return true if app requests to use ANGLE, but ANGLE is not loaded.
188     // Difference with the case above is on devices that don't have an ANGLE apk installed,
189     // ANGLE namespace is not set. In that case if ANGLE in system partition is not loaded,
190     // we should unload the system driver first, and then load ANGLE from system partition.
191     if (!cnx->angleLoaded && android::GraphicsEnv::getInstance().shouldUseAngle()) {
192         return true;
193     }
194 
195     // Return true if native GLES drivers should be used and ANGLE is already loaded.
196     if (android::GraphicsEnv::getInstance().shouldUseNativeDriver() && cnx->angleLoaded) {
197         return true;
198     }
199 
200     // Return true if updated driver namespace is set.
201     ns = android::GraphicsEnv::getInstance().getDriverNamespace();
202     if (ns) {
203         return true;
204     }
205 
206     return false;
207 }
208 
uninit_api(char const * const * api,__eglMustCastToProperFunctionPointerType * curr)209 static void uninit_api(char const* const* api, __eglMustCastToProperFunctionPointerType* curr) {
210     while (*api) {
211         *curr++ = nullptr;
212         api++;
213     }
214 }
215 
unload_system_driver(egl_connection_t * cnx)216 void Loader::unload_system_driver(egl_connection_t* cnx) {
217     ATRACE_CALL();
218 
219     uninit_api(gl_names,
220                (__eglMustCastToProperFunctionPointerType*)&cnx
221                        ->hooks[egl_connection_t::GLESv2_INDEX]
222                        ->gl);
223     uninit_api(gl_names,
224                (__eglMustCastToProperFunctionPointerType*)&cnx
225                        ->hooks[egl_connection_t::GLESv1_INDEX]
226                        ->gl);
227     uninit_api(egl_names, (__eglMustCastToProperFunctionPointerType*)&cnx->egl);
228 
229     if (cnx->dso) {
230         ALOGD("Unload system gl driver.");
231         driver_t* hnd = (driver_t*)cnx->dso;
232         if (hnd->dso[2]) {
233             do_android_unload_sphal_library(hnd->dso[2]);
234         }
235         if (hnd->dso[1]) {
236             do_android_unload_sphal_library(hnd->dso[1]);
237         }
238         if (hnd->dso[0]) {
239             do_android_unload_sphal_library(hnd->dso[0]);
240         }
241         cnx->dso = nullptr;
242         cnx->angleLoaded = false;
243     }
244 
245     cnx->systemDriverUnloaded = true;
246 }
247 
open(egl_connection_t * cnx)248 void* Loader::open(egl_connection_t* cnx) {
249     ATRACE_CALL();
250     const nsecs_t openTime = systemTime();
251 
252     if (cnx->dso && should_unload_system_driver(cnx)) {
253         unload_system_driver(cnx);
254     }
255 
256     // If a driver has been loaded, return the driver directly.
257     if (cnx->dso) {
258         return cnx->dso;
259     }
260 
261     driver_t* hnd = nullptr;
262     // Firstly, try to load ANGLE driver, if ANGLE should be loaded and fail, abort.
263     if (android::GraphicsEnv::getInstance().shouldUseAngle()) {
264         hnd = attempt_to_load_angle(cnx);
265         LOG_ALWAYS_FATAL_IF(!hnd, "Failed to load ANGLE.");
266     }
267 
268     if (!hnd) {
269         // Secondly, try to load from driver apk.
270         hnd = attempt_to_load_updated_driver(cnx);
271 
272         // If updated driver apk is set but fail to load, abort here.
273         LOG_ALWAYS_FATAL_IF(android::GraphicsEnv::getInstance().getDriverNamespace() && !hnd,
274                             "couldn't find an OpenGL ES implementation from %s",
275                             android::GraphicsEnv::getInstance().getDriverPath().c_str());
276     }
277 
278     // Attempt to load native GLES drivers specified by ro.hardware.egl if native is selected.
279     // If native is selected but fail to load, abort.
280     if (!hnd && android::GraphicsEnv::getInstance().shouldUseNativeDriver()) {
281         auto driverSuffix = base::GetProperty(RO_DRIVER_SUFFIX_PROPERTY, "");
282         LOG_ALWAYS_FATAL_IF(driverSuffix.empty(),
283                             "Native GLES driver is selected but not specified in %s",
284                             RO_DRIVER_SUFFIX_PROPERTY);
285         hnd = attempt_to_load_system_driver(cnx, driverSuffix.c_str(), true);
286         LOG_ALWAYS_FATAL_IF(!hnd, "Native GLES driver is selected but failed to load. %s=%s",
287                             RO_DRIVER_SUFFIX_PROPERTY, driverSuffix.c_str());
288     }
289 
290     // Finally, try to load default driver.
291     bool failToLoadFromDriverSuffixProperty = false;
292     if (!hnd) {
293         // Start by searching for the library name appended by the system
294         // properties of the GLES userspace driver in both locations.
295         // i.e.:
296         //      libGLES_${prop}.so, or:
297         //      libEGL_${prop}.so, libGLESv1_CM_${prop}.so, libGLESv2_${prop}.so
298         for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
299             auto prop = base::GetProperty(key, "");
300             if (prop.empty()) {
301                 continue;
302             }
303             hnd = attempt_to_load_system_driver(cnx, prop.c_str(), true);
304             if (!hnd) {
305                 ALOGD("Failed to load drivers from property %s with value %s", key, prop.c_str());
306                 failToLoadFromDriverSuffixProperty = true;
307             }
308 
309             // Abort regardless of whether subsequent properties are set, the value must be set
310             // correctly with the first property that has a value.
311             break;
312         }
313     }
314 
315     if (!hnd) {
316         // Can't find graphics driver by appending the value from system properties, now search for
317         // the exact name without any suffix of the GLES userspace driver in both locations.
318         // i.e.:
319         //      libGLES.so, or:
320         //      libEGL.so, libGLESv1_CM.so, libGLESv2.so
321         hnd = attempt_to_load_system_driver(cnx, nullptr, true);
322     }
323 
324     if (!hnd && !failToLoadFromDriverSuffixProperty &&
325         property_get_int32("ro.vendor.api_level", 0) < __ANDROID_API_U__) {
326         // Still can't find the graphics drivers with the exact name. This time try to use wildcard
327         // matching if the device is launched before Android 14.
328         hnd = attempt_to_load_system_driver(cnx, nullptr, false);
329     }
330 
331     if (!hnd) {
332         android::GraphicsEnv::getInstance().setDriverLoaded(android::GpuStatsInfo::Api::API_GL,
333                                                             false, systemTime() - openTime);
334     } else {
335         // init_angle_backend will check if loaded driver is ANGLE or not,
336         // will set cnx->angleLoaded appropriately.
337         // Do this here so that we use ANGLE path when driver is ANGLE (e.g. loaded as native),
338         // not just loading ANGLE as option.
339         attempt_to_init_angle_backend(hnd->dso[2], cnx);
340     }
341 
342     LOG_ALWAYS_FATAL_IF(!hnd,
343                         "couldn't find an OpenGL ES implementation, make sure one of %s, %s and %s "
344                         "is set",
345                         HAL_SUBNAME_KEY_PROPERTIES[0], HAL_SUBNAME_KEY_PROPERTIES[1],
346                         HAL_SUBNAME_KEY_PROPERTIES[2]);
347 
348     if (!cnx->libEgl) {
349         cnx->libEgl = load_wrapper(SYSTEM_LIB_PATH "/libEGL.so");
350     }
351     if (!cnx->libGles1) {
352         cnx->libGles1 = load_wrapper(SYSTEM_LIB_PATH "/libGLESv1_CM.so");
353     }
354     if (!cnx->libGles2) {
355         cnx->libGles2 = load_wrapper(SYSTEM_LIB_PATH "/libGLESv2.so");
356     }
357 
358     if (!cnx->libEgl || !cnx->libGles2 || !cnx->libGles1) {
359         android::GraphicsEnv::getInstance().setDriverLoaded(android::GpuStatsInfo::Api::API_GL,
360                                                             false, systemTime() - openTime);
361     }
362 
363     LOG_ALWAYS_FATAL_IF(!cnx->libEgl,
364             "couldn't load system EGL wrapper libraries");
365 
366     LOG_ALWAYS_FATAL_IF(!cnx->libGles2 || !cnx->libGles1,
367                         "couldn't load system OpenGL ES wrapper libraries");
368 
369     android::GraphicsEnv::getInstance().setDriverLoaded(android::GpuStatsInfo::Api::API_GL, true,
370                                                         systemTime() - openTime);
371 
372     return (void*)hnd;
373 }
374 
close(egl_connection_t * cnx)375 void Loader::close(egl_connection_t* cnx)
376 {
377     driver_t* hnd = (driver_t*) cnx->dso;
378     delete hnd;
379     cnx->dso = nullptr;
380 
381     cnx->angleLoaded = false;
382 }
383 
init_api(void * dso,char const * const * api,char const * const * ref_api,__eglMustCastToProperFunctionPointerType * curr,getProcAddressType getProcAddress)384 void Loader::init_api(void* dso,
385         char const * const * api,
386         char const * const * ref_api,
387         __eglMustCastToProperFunctionPointerType* curr,
388         getProcAddressType getProcAddress)
389 {
390     ATRACE_CALL();
391 
392     const ssize_t SIZE = 256;
393     char scrap[SIZE];
394     while (*api) {
395         char const * name = *api;
396         if (ref_api) {
397             char const * ref_name = *ref_api;
398             if (std::strcmp(name, ref_name) != 0) {
399                 *curr++ = nullptr;
400                 ref_api++;
401                 continue;
402             }
403         }
404 
405         __eglMustCastToProperFunctionPointerType f =
406             (__eglMustCastToProperFunctionPointerType)dlsym(dso, name);
407         if (f == nullptr) {
408             // couldn't find the entry-point, use eglGetProcAddress()
409             f = getProcAddress(name);
410         }
411         if (f == nullptr) {
412             // Try without the OES postfix
413             ssize_t index = ssize_t(strlen(name)) - 3;
414             if ((index>0 && (index<SIZE-1)) && (!strcmp(name+index, "OES"))) {
415                 strncpy(scrap, name, index);
416                 scrap[index] = 0;
417                 f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap);
418                 //ALOGD_IF(f, "found <%s> instead", scrap);
419             }
420         }
421         if (f == nullptr) {
422             // Try with the OES postfix
423             ssize_t index = ssize_t(strlen(name)) - 3;
424             if (index>0 && strcmp(name+index, "OES")) {
425                 snprintf(scrap, SIZE, "%sOES", name);
426                 f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap);
427                 //ALOGD_IF(f, "found <%s> instead", scrap);
428             }
429         }
430         if (f == nullptr) {
431             //ALOGD("%s", name);
432             f = (__eglMustCastToProperFunctionPointerType)gl_unimplemented;
433 
434             /*
435              * GL_EXT_debug_marker is special, we always report it as
436              * supported, it's handled by GLES_trace. If GLES_trace is not
437              * enabled, then these are no-ops.
438              */
439             if (!strcmp(name, "glInsertEventMarkerEXT")) {
440                 f = (__eglMustCastToProperFunctionPointerType)gl_noop;
441             } else if (!strcmp(name, "glPushGroupMarkerEXT")) {
442                 f = (__eglMustCastToProperFunctionPointerType)gl_noop;
443             } else if (!strcmp(name, "glPopGroupMarkerEXT")) {
444                 f = (__eglMustCastToProperFunctionPointerType)gl_noop;
445             }
446         }
447         *curr++ = f;
448         api++;
449         if (ref_api) ref_api++;
450     }
451 }
452 
findLibrary(const std::string libraryName,const std::string searchPath,const bool exact)453 static std::string findLibrary(const std::string libraryName, const std::string searchPath,
454                                const bool exact) {
455     if (exact) {
456         std::string absolutePath = searchPath + "/" + libraryName + ".so";
457         if (!access(absolutePath.c_str(), R_OK)) {
458             return absolutePath;
459         }
460         return std::string();
461     }
462 
463     DIR* d = opendir(searchPath.c_str());
464     if (d != nullptr) {
465         struct dirent* e;
466         while ((e = readdir(d)) != nullptr) {
467             if (e->d_type == DT_DIR) {
468                 continue;
469             }
470             if (!strcmp(e->d_name, "libGLES_android.so")) {
471                 // always skip the software renderer
472                 continue;
473             }
474             if (strstr(e->d_name, libraryName.c_str()) == e->d_name) {
475                 if (!strcmp(e->d_name + strlen(e->d_name) - 3, ".so")) {
476                     std::string result = searchPath + "/" + e->d_name;
477                     closedir(d);
478                     return result;
479                 }
480             }
481         }
482         closedir(d);
483     }
484     // Driver not found. gah.
485     return std::string();
486 }
487 
load_system_driver(const char * kind,const char * suffix,const bool exact)488 static void* load_system_driver(const char* kind, const char* suffix, const bool exact) {
489     ATRACE_CALL();
490 
491     std::string libraryName = std::string("lib") + kind;
492     if (suffix) {
493         libraryName += std::string("_") + suffix;
494     } else if (!exact) {
495         // Deprecated for devices launching in Android 14
496         // Look for files that match
497         //      libGLES_*.so, or,
498         //      libEGL_*.so, libGLESv1_CM_*.so, libGLESv2_*.so
499         libraryName += std::string("_");
500     }
501 
502     void* dso = nullptr;
503 
504     const bool isSuffixAngle = suffix != nullptr && strcmp(suffix, ANGLE_SUFFIX_VALUE) == 0;
505     const std::string absolutePath =
506             findLibrary(libraryName, isSuffixAngle ? SYSTEM_LIB_PATH : VENDOR_LIB_EGL_DIR, exact);
507     if (absolutePath.empty()) {
508         // this happens often, we don't want to log an error
509         return nullptr;
510     }
511     const char* const driverAbsolutePath = absolutePath.c_str();
512 
513     // Currently the default driver is unlikely to be ANGLE on most devices,
514     // hence put this first. Only use sphal namespace when system ANGLE binaries
515     // are not the default drivers.
516     if (!isSuffixAngle) {
517         // Try to load drivers from the 'sphal' namespace, if it exist. Fall back to
518         // the original routine when the namespace does not exist.
519         // See /system/linkerconfig/contents/namespace for the configuration of the
520         // sphal namespace.
521         dso = do_android_load_sphal_library(driverAbsolutePath, RTLD_NOW | RTLD_LOCAL);
522     } else {
523         // Try to load drivers from the default namespace.
524         // See /system/linkerconfig/contents/namespace for the configuration of the
525         // default namespace.
526         dso = do_dlopen(driverAbsolutePath, RTLD_NOW | RTLD_LOCAL);
527     }
528 
529     if (dso == nullptr) {
530         const char* err = dlerror();
531         ALOGE("load_driver(%s): %s", driverAbsolutePath, err ? err : "unknown");
532         return nullptr;
533     }
534 
535     ALOGV("loaded %s", driverAbsolutePath);
536 
537     return dso;
538 }
539 
load_angle(const char * kind,android_namespace_t * ns)540 static void* load_angle(const char* kind, android_namespace_t* ns) {
541     std::string name = std::string("lib") + kind + "_angle.so";
542     void* so = nullptr;
543 
544     if (android::GraphicsEnv::getInstance().shouldUseSystemAngle()) {
545         so = do_dlopen(name.c_str(), RTLD_NOW | RTLD_LOCAL);
546     } else {
547         const android_dlextinfo dlextinfo = {
548                 .flags = ANDROID_DLEXT_USE_NAMESPACE,
549                 .library_namespace = ns,
550         };
551         auto prop = base::GetProperty("debug.angle.libs.suffix", "");
552         if (!prop.empty()) {
553             name = std::string("lib") + kind + "_" + prop + ".so";
554         }
555         so = do_android_dlopen_ext(name.c_str(), RTLD_LOCAL | RTLD_NOW, &dlextinfo);
556     }
557 
558     if (so) {
559         return so;
560     } else {
561         ALOGE("dlopen_ext(\"%s\") failed: %s", name.c_str(), dlerror());
562     }
563 
564     return nullptr;
565 }
566 
load_updated_driver(const char * kind,android_namespace_t * ns)567 static void* load_updated_driver(const char* kind, android_namespace_t* ns) {
568     ATRACE_CALL();
569     const android_dlextinfo dlextinfo = {
570         .flags = ANDROID_DLEXT_USE_NAMESPACE,
571         .library_namespace = ns,
572     };
573     void* so = nullptr;
574     for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
575         auto prop = base::GetProperty(key, "");
576         if (prop.empty()) {
577             continue;
578         }
579         std::string name = std::string("lib") + kind + "_" + prop + ".so";
580         so = do_android_dlopen_ext(name.c_str(), RTLD_LOCAL | RTLD_NOW, &dlextinfo);
581         if (so) {
582             return so;
583         }
584         ALOGE("Could not load %s from updatable gfx driver namespace: %s.", name.c_str(),
585               dlerror());
586     }
587     return nullptr;
588 }
589 
attempt_to_load_angle(egl_connection_t * cnx)590 Loader::driver_t* Loader::attempt_to_load_angle(egl_connection_t* cnx) {
591     ATRACE_CALL();
592 
593     android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace();
594     // ANGLE namespace is used for loading ANGLE from apk, and hence if namespace is not
595     // constructed, it means ANGLE apk is not set to be the OpenGL ES driver.
596     // Hence skip if ANGLE apk and system ANGLE are not set to be the OpenGL ES driver.
597     if (!ns && !android::GraphicsEnv::getInstance().shouldUseSystemAngle()) {
598         return nullptr;
599     }
600 
601     // use ANGLE APK driver
602     android::GraphicsEnv::getInstance().setDriverToLoad(android::GpuStatsInfo::Driver::ANGLE);
603     driver_t* hnd = nullptr;
604 
605     // ANGLE doesn't ship with GLES library, and thus we skip GLES driver.
606     // b/370113081: if there is no libEGL_angle.so in namespace ns, libEGL_angle.so in system
607     // partition will be loaded instead. If there is no libEGL_angle.so in system partition, no
608     // angle libs are loaded, and app that sets to use ANGLE will crash.
609     void* dso = load_angle("EGL", ns);
610     if (dso) {
611         initialize_api(dso, cnx, EGL);
612         hnd = new driver_t(dso);
613 
614         dso = load_angle("GLESv1_CM", ns);
615         initialize_api(dso, cnx, GLESv1_CM);
616         hnd->set(dso, GLESv1_CM);
617 
618         dso = load_angle("GLESv2", ns);
619         initialize_api(dso, cnx, GLESv2);
620         hnd->set(dso, GLESv2);
621     }
622     return hnd;
623 }
624 
attempt_to_init_angle_backend(void * dso,egl_connection_t * cnx)625 void Loader::attempt_to_init_angle_backend(void* dso, egl_connection_t* cnx) {
626     cnx->angleGetDisplayPlatformFunc = dlsym(dso, "ANGLEGetDisplayPlatform");
627     cnx->angleResetDisplayPlatformFunc = dlsym(dso, "ANGLEResetDisplayPlatform");
628 
629     if (cnx->angleGetDisplayPlatformFunc) {
630         ALOGV("ANGLE GLES library loaded");
631         cnx->angleLoaded = true;
632         android::GraphicsEnv::getInstance().setDriverToLoad(android::GpuStatsInfo::Driver::ANGLE);
633     } else {
634         ALOGV("Native GLES library loaded");
635         cnx->angleLoaded = false;
636     }
637 }
638 
attempt_to_load_updated_driver(egl_connection_t * cnx)639 Loader::driver_t* Loader::attempt_to_load_updated_driver(egl_connection_t* cnx) {
640     ATRACE_CALL();
641 
642     android_namespace_t* ns = android::GraphicsEnv::getInstance().getDriverNamespace();
643     if (!ns) {
644         return nullptr;
645     }
646 
647     ALOGD("Load updated gl driver.");
648     android::GraphicsEnv::getInstance().setDriverToLoad(android::GpuStatsInfo::Driver::GL_UPDATED);
649     driver_t* hnd = nullptr;
650     void* dso = load_updated_driver("GLES", ns);
651     if (dso) {
652         initialize_api(dso, cnx, EGL | GLESv1_CM | GLESv2);
653         hnd = new driver_t(dso);
654         return hnd;
655     }
656 
657     dso = load_updated_driver("EGL", ns);
658     if (dso) {
659         initialize_api(dso, cnx, EGL);
660         hnd = new driver_t(dso);
661 
662         dso = load_updated_driver("GLESv1_CM", ns);
663         initialize_api(dso, cnx, GLESv1_CM);
664         hnd->set(dso, GLESv1_CM);
665 
666         dso = load_updated_driver("GLESv2", ns);
667         initialize_api(dso, cnx, GLESv2);
668         hnd->set(dso, GLESv2);
669     }
670     return hnd;
671 }
672 
attempt_to_load_system_driver(egl_connection_t * cnx,const char * suffix,const bool exact)673 Loader::driver_t* Loader::attempt_to_load_system_driver(egl_connection_t* cnx, const char* suffix,
674                                                         const bool exact) {
675     ATRACE_CALL();
676     if (suffix && strcmp(suffix, "angle") == 0) {
677         // use system ANGLE driver
678         android::GraphicsEnv::getInstance().setDriverToLoad(android::GpuStatsInfo::Driver::ANGLE);
679     } else {
680         android::GraphicsEnv::getInstance().setDriverToLoad(android::GpuStatsInfo::Driver::GL);
681     }
682 
683     driver_t* hnd = nullptr;
684     void* dso = load_system_driver("GLES", suffix, exact);
685     if (dso) {
686         initialize_api(dso, cnx, EGL | GLESv1_CM | GLESv2);
687         hnd = new driver_t(dso);
688         return hnd;
689     }
690     dso = load_system_driver("EGL", suffix, exact);
691     if (dso) {
692         initialize_api(dso, cnx, EGL);
693         hnd = new driver_t(dso);
694 
695         dso = load_system_driver("GLESv1_CM", suffix, exact);
696         initialize_api(dso, cnx, GLESv1_CM);
697         hnd->set(dso, GLESv1_CM);
698 
699         dso = load_system_driver("GLESv2", suffix, exact);
700         initialize_api(dso, cnx, GLESv2);
701         hnd->set(dso, GLESv2);
702     }
703     return hnd;
704 }
705 
initialize_api(void * dso,egl_connection_t * cnx,uint32_t mask)706 void Loader::initialize_api(void* dso, egl_connection_t* cnx, uint32_t mask) {
707     if (mask & EGL) {
708         getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress");
709 
710         ALOGE_IF(!getProcAddress,
711                 "can't find eglGetProcAddress() in EGL driver library");
712 
713         egl_t* egl = &cnx->egl;
714         __eglMustCastToProperFunctionPointerType* curr =
715             (__eglMustCastToProperFunctionPointerType*)egl;
716         char const * const * api = egl_names;
717         while (*api) {
718             char const * name = *api;
719             __eglMustCastToProperFunctionPointerType f =
720                 (__eglMustCastToProperFunctionPointerType)dlsym(dso, name);
721             if (f == nullptr) {
722                 // couldn't find the entry-point, use eglGetProcAddress()
723                 f = getProcAddress(name);
724                 if (f == nullptr) {
725                     f = (__eglMustCastToProperFunctionPointerType)nullptr;
726                 }
727             }
728             *curr++ = f;
729             api++;
730         }
731     }
732 
733     if (mask & GLESv1_CM) {
734         init_api(dso, gl_names_1, gl_names,
735             (__eglMustCastToProperFunctionPointerType*)
736                 &cnx->hooks[egl_connection_t::GLESv1_INDEX]->gl,
737             getProcAddress);
738     }
739 
740     if (mask & GLESv2) {
741         init_api(dso, gl_names, nullptr,
742             (__eglMustCastToProperFunctionPointerType*)
743                 &cnx->hooks[egl_connection_t::GLESv2_INDEX]->gl,
744             getProcAddress);
745     }
746 }
747 
748 } // namespace android
749