diff options
author | 2016-12-20 15:24:28 -0800 | |
---|---|---|
committer | 2017-01-16 21:11:36 -0800 | |
commit | 7a8d83ef77b31097cbccfc89ee93414b3f2c2d03 (patch) | |
tree | 6f59b258e55bf98d4078200d356b7d9cc5a3467c | |
parent | 53457dbae92cb6fb12fac06cf0e874ff3c49528d (diff) |
EGL: Load updated EGL/GLES drivers
Because the driver namespace is stored in libgui, and libgui depends
on libEGL, this required a hack for libEGL to access the namespace.
See the comment added in GraphicsEnv.h for details; the summary is
that the libgui->libEGL dependency should go away, and then libEGL can
depend on libgui directly.
For system drivers, the loader would happily load anything named
lib{GLES,EGL,GLESv2,GLESv1_CM}_*.so in /vendor/lib[64]/egl, for
backward-compatibility with the old and no-longer-supported egl.cfg
system. However, it preferred unsuffixed names. That's not actually a
good idea, since the DT_SONAME would clash with the system libraries.
For updated drivers, we only look for suffixes from the
ro.hardware.egl and ro.board.platform system properties, similar to
the Vulkan and HAL library search. A future change (tied to a future
release) will do the same for system drivers.
Bug: 33531483
Test: Launch GLES apps w/ and w/o updated driver package
Change-Id: Ibfbb275629b0c6cf9c51314aea1361e81ff72d4b
-rw-r--r-- | include/gui/GraphicsEnv.h | 13 | ||||
-rw-r--r-- | libs/gui/GraphicsEnv.cpp | 4 | ||||
-rw-r--r-- | opengl/libs/EGL/Loader.cpp | 72 | ||||
-rw-r--r-- | opengl/libs/EGL/Loader.h | 7 |
4 files changed, 90 insertions, 6 deletions
diff --git a/include/gui/GraphicsEnv.h b/include/gui/GraphicsEnv.h index 0d3843b7c9..4c7366f094 100644 --- a/include/gui/GraphicsEnv.h +++ b/include/gui/GraphicsEnv.h @@ -43,4 +43,17 @@ private: } // namespace android +/* FIXME + * Export an un-mangled function that just does + * return android::GraphicsEnv::getInstance().getDriverNamespace(); + * This allows libEGL to get the function pointer via dlsym, since it can't + * directly link against libgui. In a future release, we'll fix this so that + * libgui does not depend on graphics API libraries, and libEGL can link + * against it. The current dependencies from libgui -> libEGL are: + * - the GLConsumer class, which should be moved to its own library + * - the EGLsyncKHR synchronization in BufferQueue, which is deprecated and + * will be removed soon. + */ +extern "C" android_namespace_t* android_getDriverNamespace(); + #endif // ANDROID_GUI_GRAPHICS_ENV_H diff --git a/libs/gui/GraphicsEnv.cpp b/libs/gui/GraphicsEnv.cpp index ab824d3466..68f0f988e2 100644 --- a/libs/gui/GraphicsEnv.cpp +++ b/libs/gui/GraphicsEnv.cpp @@ -75,3 +75,7 @@ android_namespace_t* GraphicsEnv::getDriverNamespace() { } } // namespace android + +extern "C" android_namespace_t* android_getDriverNamespace() { + return android::GraphicsEnv::getInstance().getDriverNamespace(); +} diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp index ac455cdd70..27697aba2c 100644 --- a/opengl/libs/EGL/Loader.cpp +++ b/opengl/libs/EGL/Loader.cpp @@ -14,6 +14,9 @@ ** limitations under the License. */ +//#define LOG_NDEBUG 0 + +#include <array> #include <ctype.h> #include <dirent.h> #include <dlfcn.h> @@ -23,6 +26,7 @@ #include <stdlib.h> #include <string.h> +#include <android/dlext.h> #include <cutils/properties.h> #include <log/log.h> @@ -136,10 +140,26 @@ status_t Loader::driver_t::set(void* hnd, int32_t api) // ---------------------------------------------------------------------------- Loader::Loader() - : getProcAddress(NULL) { + : getProcAddress(NULL), + mLibGui(nullptr), + mGetDriverNamespace(nullptr) +{ + // FIXME: See note in GraphicsEnv.h about android_getDriverNamespace(). + // libgui should already be loaded in any process that uses libEGL, but + // if for some reason it isn't, then we're not going to get a driver + // namespace anyway, so don't force it to be loaded. + mLibGui = dlopen("libgui.so", RTLD_NOLOAD | RTLD_LOCAL | RTLD_LAZY); + if (!mLibGui) { + ALOGD("failed to load libgui: %s", dlerror()); + return; + } + mGetDriverNamespace = reinterpret_cast<decltype(mGetDriverNamespace)>( + dlsym(mLibGui, "android_getDriverNamespace")); } Loader::~Loader() { + if (mLibGui) + dlclose(mLibGui); } static void* load_wrapper(const char* path) { @@ -286,9 +306,7 @@ void Loader::init_api(void* dso, } } -void *Loader::load_driver(const char* kind, - egl_connection_t* cnx, uint32_t mask) -{ +static void* load_system_driver(const char* kind) { class MatchFile { public: static String8 find(const char* kind) { @@ -413,11 +431,55 @@ void *Loader::load_driver(const char* kind, ALOGD("loaded %s", driver_absolute_path); + return dso; +} + +static const std::array<const char*, 2> HAL_SUBNAME_KEY_PROPERTIES = {{ + "ro.hardware.egl", + "ro.board.platform", +}}; + +static void* load_updated_driver(const char* kind, android_namespace_t* ns) { + const android_dlextinfo dlextinfo = { + .flags = ANDROID_DLEXT_USE_NAMESPACE, + .library_namespace = ns, + }; + void* so = nullptr; + char prop[PROPERTY_VALUE_MAX + 1]; + for (auto key : HAL_SUBNAME_KEY_PROPERTIES) { + if (property_get(key, prop, nullptr) > 0) { + String8 name; + name.appendFormat("lib%s_%s.so", kind, prop); + so = android_dlopen_ext(name.string(), RTLD_LOCAL | RTLD_NOW, + &dlextinfo); + if (so) + return so; + } + } + return nullptr; +} + +void *Loader::load_driver(const char* kind, + egl_connection_t* cnx, uint32_t mask) +{ + void* dso = nullptr; + if (mGetDriverNamespace) { + android_namespace_t* ns = mGetDriverNamespace(); + if (ns) { + dso = load_updated_driver(kind, ns); + } + } + if (!dso) { + dso = load_system_driver(kind); + if (!dso) + return NULL; + } + if (mask & EGL) { getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress"); ALOGE_IF(!getProcAddress, - "can't find eglGetProcAddress() in %s", driver_absolute_path); + "can't find eglGetProcAddress() in EGL driver library"); egl_t* egl = &cnx->egl; __eglMustCastToProperFunctionPointerType* curr = diff --git a/opengl/libs/EGL/Loader.h b/opengl/libs/EGL/Loader.h index 94f680e9ea..d0435e7ea0 100644 --- a/opengl/libs/EGL/Loader.h +++ b/opengl/libs/EGL/Loader.h @@ -25,6 +25,8 @@ #include <utils/Singleton.h> #include <utils/String8.h> +#include <gui/GraphicsEnv.h> + #include <EGL/egl.h> // ---------------------------------------------------------------------------- @@ -53,7 +55,10 @@ class Loader : public Singleton<Loader> }; getProcAddressType getProcAddress; - + + void* mLibGui; + decltype(android_getDriverNamespace)* mGetDriverNamespace; + public: ~Loader(); |