diff options
| author | 2019-06-06 16:13:49 -0700 | |
|---|---|---|
| committer | 2019-06-06 16:13:49 -0700 | |
| commit | 271c3134256d4d4be07cb7974e8726bcc21283ab (patch) | |
| tree | 6841b9bd6916d5cda2399a0e9373bab26dd72711 | |
| parent | f91264c7d62e10e03645768e4ccfdab34a20004e (diff) | |
| parent | b0406010989bdbb9d7270a55fd64be573e3c7a14 (diff) | |
Merge "GL: unload system driver if needed" into qt-dev
am: b040601098
Change-Id: Ia29d05f1cce12f2f767d07f109f8ea930572ac61
| -rw-r--r-- | libs/graphicsenv/GraphicsEnv.cpp | 111 | ||||
| -rw-r--r-- | libs/graphicsenv/include/graphicsenv/GraphicsEnv.h | 1 | ||||
| -rw-r--r-- | opengl/libs/EGL/Loader.cpp | 88 | ||||
| -rw-r--r-- | opengl/libs/EGL/Loader.h | 1 | ||||
| -rw-r--r-- | opengl/libs/EGL/egl.cpp | 10 | ||||
| -rw-r--r-- | opengl/libs/EGL/egl_display.cpp | 2 | ||||
| -rw-r--r-- | opengl/libs/EGL/egldefs.h | 7 |
7 files changed, 159 insertions, 61 deletions
diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp index 407f77d88b..1c5fa52855 100644 --- a/libs/graphicsenv/GraphicsEnv.cpp +++ b/libs/graphicsenv/GraphicsEnv.cpp @@ -534,60 +534,73 @@ void GraphicsEnv::setDebugLayersGLES(const std::string layers) { mDebugLayersGLES = layers; } +// Return true if all the required libraries from vndk and sphal namespace are +// linked to the Game Driver namespace correctly. +bool GraphicsEnv::linkDriverNamespaceLocked(android_namespace_t* vndkNamespace) { + const std::string llndkLibraries = getSystemNativeLibraries(NativeLibrary::LLNDK); + if (llndkLibraries.empty()) { + return false; + } + if (!android_link_namespaces(mDriverNamespace, nullptr, llndkLibraries.c_str())) { + ALOGE("Failed to link default namespace[%s]", dlerror()); + return false; + } + + const std::string vndkspLibraries = getSystemNativeLibraries(NativeLibrary::VNDKSP); + if (vndkspLibraries.empty()) { + return false; + } + if (!android_link_namespaces(mDriverNamespace, vndkNamespace, vndkspLibraries.c_str())) { + ALOGE("Failed to link vndk namespace[%s]", dlerror()); + return false; + } + + if (mSphalLibraries.empty()) { + return true; + } + + // Make additional libraries in sphal to be accessible + auto sphalNamespace = android_get_exported_namespace("sphal"); + if (!sphalNamespace) { + ALOGE("Depend on these libraries[%s] in sphal, but failed to get sphal namespace", + mSphalLibraries.c_str()); + return false; + } + + if (!android_link_namespaces(mDriverNamespace, sphalNamespace, mSphalLibraries.c_str())) { + ALOGE("Failed to link sphal namespace[%s]", dlerror()); + return false; + } + + return true; +} + android_namespace_t* GraphicsEnv::getDriverNamespace() { - static std::once_flag once; - std::call_once(once, [this]() { - if (mDriverPath.empty()) return; - - auto vndkNamespace = android_get_exported_namespace("vndk"); - if (!vndkNamespace) return; - - mDriverNamespace = android_create_namespace("gfx driver", - mDriverPath.c_str(), // ld_library_path - mDriverPath.c_str(), // default_library_path - ANDROID_NAMESPACE_TYPE_ISOLATED, - nullptr, // permitted_when_isolated_path - nullptr); - - const std::string llndkLibraries = getSystemNativeLibraries(NativeLibrary::LLNDK); - if (llndkLibraries.empty()) { - mDriverNamespace = nullptr; - return; - } - if (!android_link_namespaces(mDriverNamespace, nullptr, llndkLibraries.c_str())) { - ALOGE("Failed to link default namespace[%s]", dlerror()); - mDriverNamespace = nullptr; - return; - } + std::lock_guard<std::mutex> lock(mNamespaceMutex); - const std::string vndkspLibraries = getSystemNativeLibraries(NativeLibrary::VNDKSP); - if (vndkspLibraries.empty()) { - mDriverNamespace = nullptr; - return; - } - if (!android_link_namespaces(mDriverNamespace, vndkNamespace, vndkspLibraries.c_str())) { - ALOGE("Failed to link vndk namespace[%s]", dlerror()); - mDriverNamespace = nullptr; - return; - } + if (mDriverNamespace) { + return mDriverNamespace; + } - if (mSphalLibraries.empty()) return; + if (mDriverPath.empty()) { + return nullptr; + } - // Make additional libraries in sphal to be accessible - auto sphalNamespace = android_get_exported_namespace("sphal"); - if (!sphalNamespace) { - ALOGE("Depend on these libraries[%s] in sphal, but failed to get sphal namespace", - mSphalLibraries.c_str()); - mDriverNamespace = nullptr; - return; - } + auto vndkNamespace = android_get_exported_namespace("vndk"); + if (!vndkNamespace) { + return nullptr; + } - if (!android_link_namespaces(mDriverNamespace, sphalNamespace, mSphalLibraries.c_str())) { - ALOGE("Failed to link sphal namespace[%s]", dlerror()); - mDriverNamespace = nullptr; - return; - } - }); + mDriverNamespace = android_create_namespace("gfx driver", + mDriverPath.c_str(), // ld_library_path + mDriverPath.c_str(), // default_library_path + ANDROID_NAMESPACE_TYPE_ISOLATED, + nullptr, // permitted_when_isolated_path + nullptr); + + if (!linkDriverNamespaceLocked(vndkNamespace)) { + mDriverNamespace = nullptr; + } return mDriverNamespace; } diff --git a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h index 7d627500fd..f5d19db493 100644 --- a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h +++ b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h @@ -129,6 +129,7 @@ private: void* loadLibrary(std::string name); bool checkAngleRules(void* so); void updateUseAngle(); + bool linkDriverNamespaceLocked(android_namespace_t* vndkNamespace); GraphicsEnv() = default; std::string mDriverPath; diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp index d5c46c6683..038a432337 100644 --- a/opengl/libs/EGL/Loader.cpp +++ b/opengl/libs/EGL/Loader.cpp @@ -84,6 +84,11 @@ static void* do_android_load_sphal_library(const char* path, int mode) { return android_load_sphal_library(path, mode); } +static int do_android_unload_sphal_library(void* dso) { + ATRACE_CALL(); + return android_unload_sphal_library(dso); +} + Loader::driver_t::driver_t(void* gles) { dso[0] = gles; @@ -180,11 +185,81 @@ static const char* HAL_SUBNAME_KEY_PROPERTIES[2] = { "ro.board.platform", }; +static bool should_unload_system_driver(egl_connection_t* cnx) { + // Return false if the system driver has been unloaded once. + if (cnx->systemDriverUnloaded) { + return false; + } + + // Return true if Angle namespace is set. + android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace(); + if (ns) { + return true; + } + +#ifndef __ANDROID_VNDK__ + // Return true if updated driver namespace is set. + ns = android::GraphicsEnv::getInstance().getDriverNamespace(); + if (ns) { + return true; + } +#endif + + return false; +} + +static void uninit_api(char const* const* api, __eglMustCastToProperFunctionPointerType* curr) { + while (*api) { + *curr++ = nullptr; + api++; + } +} + +void Loader::unload_system_driver(egl_connection_t* cnx) { + ATRACE_CALL(); + + uninit_api(gl_names, + (__eglMustCastToProperFunctionPointerType*)&cnx + ->hooks[egl_connection_t::GLESv2_INDEX] + ->gl); + uninit_api(gl_names, + (__eglMustCastToProperFunctionPointerType*)&cnx + ->hooks[egl_connection_t::GLESv1_INDEX] + ->gl); + uninit_api(egl_names, (__eglMustCastToProperFunctionPointerType*)&cnx->egl); + + if (cnx->dso) { + ALOGD("Unload system gl driver."); + driver_t* hnd = (driver_t*)cnx->dso; + if (hnd->dso[2]) { + do_android_unload_sphal_library(hnd->dso[2]); + } + if (hnd->dso[1]) { + do_android_unload_sphal_library(hnd->dso[1]); + } + if (hnd->dso[0]) { + do_android_unload_sphal_library(hnd->dso[0]); + } + cnx->dso = nullptr; + } + + cnx->systemDriverUnloaded = true; +} + void* Loader::open(egl_connection_t* cnx) { ATRACE_CALL(); const nsecs_t openTime = systemTime(); + if (should_unload_system_driver(cnx)) { + unload_system_driver(cnx); + } + + // If a driver has been loaded, return the driver directly. + if (cnx->dso) { + return cnx->dso; + } + setEmulatorGlesValue(); // Check if we should use ANGLE early, so loading each driver doesn't require repeated queries. @@ -244,9 +319,15 @@ void* Loader::open(egl_connection_t* cnx) "couldn't find an OpenGL ES implementation, make sure you set %s or %s", HAL_SUBNAME_KEY_PROPERTIES[0], HAL_SUBNAME_KEY_PROPERTIES[1]); - cnx->libEgl = load_wrapper(EGL_WRAPPER_DIR "/libEGL.so"); - cnx->libGles2 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv2.so"); - cnx->libGles1 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv1_CM.so"); + if (!cnx->libEgl) { + cnx->libEgl = load_wrapper(EGL_WRAPPER_DIR "/libEGL.so"); + } + if (!cnx->libGles1) { + cnx->libGles1 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv1_CM.so"); + } + if (!cnx->libGles2) { + cnx->libGles2 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv2.so"); + } if (!cnx->libEgl || !cnx->libGles2 || !cnx->libGles1) { android::GraphicsEnv::getInstance().setDriverLoaded(android::GraphicsEnv::Api::API_GL, @@ -584,6 +665,7 @@ Loader::driver_t* Loader::attempt_to_load_updated_driver(egl_connection_t* cnx) return nullptr; } + ALOGD("Load updated gl driver."); android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::GL_UPDATED); driver_t* hnd = nullptr; void* dso = load_updated_driver("GLES", ns); diff --git a/opengl/libs/EGL/Loader.h b/opengl/libs/EGL/Loader.h index 0292d02e1d..6f31ab4741 100644 --- a/opengl/libs/EGL/Loader.h +++ b/opengl/libs/EGL/Loader.h @@ -58,6 +58,7 @@ private: driver_t* attempt_to_load_angle(egl_connection_t* cnx); driver_t* attempt_to_load_updated_driver(egl_connection_t* cnx); driver_t* attempt_to_load_system_driver(egl_connection_t* cnx, const char* suffix, const bool exact); + void unload_system_driver(egl_connection_t* cnx); void initialize_api(void* dso, egl_connection_t* cnx, uint32_t mask); static __attribute__((noinline)) diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp index 8870d5f571..25b1009ba2 100644 --- a/opengl/libs/EGL/egl.cpp +++ b/opengl/libs/EGL/egl.cpp @@ -187,13 +187,9 @@ static EGLBoolean egl_init_drivers_locked() { // dynamically load our EGL implementation egl_connection_t* cnx = &gEGLImpl; - if (cnx->dso == nullptr) { - cnx->hooks[egl_connection_t::GLESv1_INDEX] = - &gHooks[egl_connection_t::GLESv1_INDEX]; - cnx->hooks[egl_connection_t::GLESv2_INDEX] = - &gHooks[egl_connection_t::GLESv2_INDEX]; - cnx->dso = loader.open(cnx); - } + cnx->hooks[egl_connection_t::GLESv1_INDEX] = &gHooks[egl_connection_t::GLESv1_INDEX]; + cnx->hooks[egl_connection_t::GLESv2_INDEX] = &gHooks[egl_connection_t::GLESv2_INDEX]; + cnx->dso = loader.open(cnx); // Check to see if any layers are enabled and route functions through them if (cnx->dso) { diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp index 8841a3b02c..67d69b4d06 100644 --- a/opengl/libs/EGL/egl_display.cpp +++ b/opengl/libs/EGL/egl_display.cpp @@ -217,7 +217,7 @@ EGLDisplay egl_display_t::getPlatformDisplay(EGLNativeDisplayType display, Loader& loader(Loader::getInstance()); egl_connection_t* const cnx = &gEGLImpl; - if (cnx->dso && disp.dpy == EGL_NO_DISPLAY) { + if (cnx->dso) { EGLDisplay dpy = EGL_NO_DISPLAY; if (cnx->useAngle) { diff --git a/opengl/libs/EGL/egldefs.h b/opengl/libs/EGL/egldefs.h index 9e112cc034..7bb9b59ea4 100644 --- a/opengl/libs/EGL/egldefs.h +++ b/opengl/libs/EGL/egldefs.h @@ -44,7 +44,11 @@ struct egl_connection_t { GLESv2_INDEX = 1 }; - inline egl_connection_t() : dso(nullptr) { + inline egl_connection_t() : dso(nullptr), + libEgl(nullptr), + libGles1(nullptr), + libGles2(nullptr), + systemDriverUnloaded(false) { char const* const* entries = platform_names; EGLFuncPointer* curr = reinterpret_cast<EGLFuncPointer*>(&platform); @@ -76,6 +80,7 @@ struct egl_connection_t { void* libGles1; void* libGles2; + bool systemDriverUnloaded; bool shouldUseAngle; // Should we attempt to load ANGLE bool angleDecided; // Have we tried to load ANGLE bool useAngle; // Was ANGLE successfully loaded |