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(),
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 so = do_android_dlopen_ext(name.c_str(), RTLD_LOCAL | RTLD_NOW, &dlextinfo);
552 }
553
554 if (so) {
555 return so;
556 } else {
557 ALOGE("dlopen_ext(\"%s\") failed: %s", name.c_str(), dlerror());
558 }
559
560 return nullptr;
561 }
562
load_updated_driver(const char * kind,android_namespace_t * ns)563 static void* load_updated_driver(const char* kind, android_namespace_t* ns) {
564 ATRACE_CALL();
565 const android_dlextinfo dlextinfo = {
566 .flags = ANDROID_DLEXT_USE_NAMESPACE,
567 .library_namespace = ns,
568 };
569 void* so = nullptr;
570 for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
571 auto prop = base::GetProperty(key, "");
572 if (prop.empty()) {
573 continue;
574 }
575 std::string name = std::string("lib") + kind + "_" + prop + ".so";
576 so = do_android_dlopen_ext(name.c_str(), RTLD_LOCAL | RTLD_NOW, &dlextinfo);
577 if (so) {
578 return so;
579 }
580 ALOGE("Could not load %s from updatable gfx driver namespace: %s.", name.c_str(),
581 dlerror());
582 }
583 return nullptr;
584 }
585
attempt_to_load_angle(egl_connection_t * cnx)586 Loader::driver_t* Loader::attempt_to_load_angle(egl_connection_t* cnx) {
587 ATRACE_CALL();
588
589 android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace();
590 // ANGLE namespace is used for loading ANGLE from apk, and hence if namespace is not
591 // constructed, it means ANGLE apk is not set to be the OpenGL ES driver.
592 // Hence skip if ANGLE apk and system ANGLE are not set to be the OpenGL ES driver.
593 if (!ns && !android::GraphicsEnv::getInstance().shouldUseSystemAngle()) {
594 return nullptr;
595 }
596
597 // use ANGLE APK driver
598 android::GraphicsEnv::getInstance().setDriverToLoad(android::GpuStatsInfo::Driver::ANGLE);
599 driver_t* hnd = nullptr;
600
601 // ANGLE doesn't ship with GLES library, and thus we skip GLES driver.
602 void* dso = load_angle("EGL", ns);
603 if (dso) {
604 initialize_api(dso, cnx, EGL);
605 hnd = new driver_t(dso);
606
607 dso = load_angle("GLESv1_CM", ns);
608 initialize_api(dso, cnx, GLESv1_CM);
609 hnd->set(dso, GLESv1_CM);
610
611 dso = load_angle("GLESv2", ns);
612 initialize_api(dso, cnx, GLESv2);
613 hnd->set(dso, GLESv2);
614 }
615 return hnd;
616 }
617
attempt_to_init_angle_backend(void * dso,egl_connection_t * cnx)618 void Loader::attempt_to_init_angle_backend(void* dso, egl_connection_t* cnx) {
619 cnx->angleGetDisplayPlatformFunc = dlsym(dso, "ANGLEGetDisplayPlatform");
620 cnx->angleResetDisplayPlatformFunc = dlsym(dso, "ANGLEResetDisplayPlatform");
621
622 if (cnx->angleGetDisplayPlatformFunc) {
623 ALOGV("ANGLE GLES library loaded");
624 cnx->angleLoaded = true;
625 android::GraphicsEnv::getInstance().setDriverToLoad(android::GpuStatsInfo::Driver::ANGLE);
626 } else {
627 ALOGV("Native GLES library loaded");
628 cnx->angleLoaded = false;
629 }
630 }
631
attempt_to_load_updated_driver(egl_connection_t * cnx)632 Loader::driver_t* Loader::attempt_to_load_updated_driver(egl_connection_t* cnx) {
633 ATRACE_CALL();
634
635 android_namespace_t* ns = android::GraphicsEnv::getInstance().getDriverNamespace();
636 if (!ns) {
637 return nullptr;
638 }
639
640 ALOGD("Load updated gl driver.");
641 android::GraphicsEnv::getInstance().setDriverToLoad(android::GpuStatsInfo::Driver::GL_UPDATED);
642 driver_t* hnd = nullptr;
643 void* dso = load_updated_driver("GLES", ns);
644 if (dso) {
645 initialize_api(dso, cnx, EGL | GLESv1_CM | GLESv2);
646 hnd = new driver_t(dso);
647 return hnd;
648 }
649
650 dso = load_updated_driver("EGL", ns);
651 if (dso) {
652 initialize_api(dso, cnx, EGL);
653 hnd = new driver_t(dso);
654
655 dso = load_updated_driver("GLESv1_CM", ns);
656 initialize_api(dso, cnx, GLESv1_CM);
657 hnd->set(dso, GLESv1_CM);
658
659 dso = load_updated_driver("GLESv2", ns);
660 initialize_api(dso, cnx, GLESv2);
661 hnd->set(dso, GLESv2);
662 }
663 return hnd;
664 }
665
attempt_to_load_system_driver(egl_connection_t * cnx,const char * suffix,const bool exact)666 Loader::driver_t* Loader::attempt_to_load_system_driver(egl_connection_t* cnx, const char* suffix,
667 const bool exact) {
668 ATRACE_CALL();
669 if (suffix && strcmp(suffix, "angle") == 0) {
670 // use system ANGLE driver
671 android::GraphicsEnv::getInstance().setDriverToLoad(android::GpuStatsInfo::Driver::ANGLE);
672 } else {
673 android::GraphicsEnv::getInstance().setDriverToLoad(android::GpuStatsInfo::Driver::GL);
674 }
675
676 driver_t* hnd = nullptr;
677 void* dso = load_system_driver("GLES", suffix, exact);
678 if (dso) {
679 initialize_api(dso, cnx, EGL | GLESv1_CM | GLESv2);
680 hnd = new driver_t(dso);
681 return hnd;
682 }
683 dso = load_system_driver("EGL", suffix, exact);
684 if (dso) {
685 initialize_api(dso, cnx, EGL);
686 hnd = new driver_t(dso);
687
688 dso = load_system_driver("GLESv1_CM", suffix, exact);
689 initialize_api(dso, cnx, GLESv1_CM);
690 hnd->set(dso, GLESv1_CM);
691
692 dso = load_system_driver("GLESv2", suffix, exact);
693 initialize_api(dso, cnx, GLESv2);
694 hnd->set(dso, GLESv2);
695 }
696 return hnd;
697 }
698
initialize_api(void * dso,egl_connection_t * cnx,uint32_t mask)699 void Loader::initialize_api(void* dso, egl_connection_t* cnx, uint32_t mask) {
700 if (mask & EGL) {
701 getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress");
702
703 ALOGE_IF(!getProcAddress,
704 "can't find eglGetProcAddress() in EGL driver library");
705
706 egl_t* egl = &cnx->egl;
707 __eglMustCastToProperFunctionPointerType* curr =
708 (__eglMustCastToProperFunctionPointerType*)egl;
709 char const * const * api = egl_names;
710 while (*api) {
711 char const * name = *api;
712 __eglMustCastToProperFunctionPointerType f =
713 (__eglMustCastToProperFunctionPointerType)dlsym(dso, name);
714 if (f == nullptr) {
715 // couldn't find the entry-point, use eglGetProcAddress()
716 f = getProcAddress(name);
717 if (f == nullptr) {
718 f = (__eglMustCastToProperFunctionPointerType)nullptr;
719 }
720 }
721 *curr++ = f;
722 api++;
723 }
724 }
725
726 if (mask & GLESv1_CM) {
727 init_api(dso, gl_names_1, gl_names,
728 (__eglMustCastToProperFunctionPointerType*)
729 &cnx->hooks[egl_connection_t::GLESv1_INDEX]->gl,
730 getProcAddress);
731 }
732
733 if (mask & GLESv2) {
734 init_api(dso, gl_names, nullptr,
735 (__eglMustCastToProperFunctionPointerType*)
736 &cnx->hooks[egl_connection_t::GLESv2_INDEX]->gl,
737 getProcAddress);
738 }
739 }
740
741 } // namespace android
742