Loading libs/graphicsenv/GraphicsEnv.cpp +62 −49 Original line number Original line Diff line number Diff line Loading @@ -534,60 +534,73 @@ void GraphicsEnv::setDebugLayersGLES(const std::string layers) { mDebugLayersGLES = layers; mDebugLayersGLES = layers; } } android_namespace_t* GraphicsEnv::getDriverNamespace() { // Return true if all the required libraries from vndk and sphal namespace are static std::once_flag once; // linked to the Game Driver namespace correctly. std::call_once(once, [this]() { bool GraphicsEnv::linkDriverNamespaceLocked(android_namespace_t* vndkNamespace) { 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); const std::string llndkLibraries = getSystemNativeLibraries(NativeLibrary::LLNDK); if (llndkLibraries.empty()) { if (llndkLibraries.empty()) { mDriverNamespace = nullptr; return false; return; } } if (!android_link_namespaces(mDriverNamespace, nullptr, llndkLibraries.c_str())) { if (!android_link_namespaces(mDriverNamespace, nullptr, llndkLibraries.c_str())) { ALOGE("Failed to link default namespace[%s]", dlerror()); ALOGE("Failed to link default namespace[%s]", dlerror()); mDriverNamespace = nullptr; return false; return; } } const std::string vndkspLibraries = getSystemNativeLibraries(NativeLibrary::VNDKSP); const std::string vndkspLibraries = getSystemNativeLibraries(NativeLibrary::VNDKSP); if (vndkspLibraries.empty()) { if (vndkspLibraries.empty()) { mDriverNamespace = nullptr; return false; return; } } if (!android_link_namespaces(mDriverNamespace, vndkNamespace, vndkspLibraries.c_str())) { if (!android_link_namespaces(mDriverNamespace, vndkNamespace, vndkspLibraries.c_str())) { ALOGE("Failed to link vndk namespace[%s]", dlerror()); ALOGE("Failed to link vndk namespace[%s]", dlerror()); mDriverNamespace = nullptr; return false; return; } } if (mSphalLibraries.empty()) return; if (mSphalLibraries.empty()) { return true; } // Make additional libraries in sphal to be accessible // Make additional libraries in sphal to be accessible auto sphalNamespace = android_get_exported_namespace("sphal"); auto sphalNamespace = android_get_exported_namespace("sphal"); if (!sphalNamespace) { if (!sphalNamespace) { ALOGE("Depend on these libraries[%s] in sphal, but failed to get sphal namespace", ALOGE("Depend on these libraries[%s] in sphal, but failed to get sphal namespace", mSphalLibraries.c_str()); mSphalLibraries.c_str()); mDriverNamespace = nullptr; return false; return; } } if (!android_link_namespaces(mDriverNamespace, sphalNamespace, mSphalLibraries.c_str())) { if (!android_link_namespaces(mDriverNamespace, sphalNamespace, mSphalLibraries.c_str())) { ALOGE("Failed to link sphal namespace[%s]", dlerror()); ALOGE("Failed to link sphal namespace[%s]", dlerror()); return false; } return true; } android_namespace_t* GraphicsEnv::getDriverNamespace() { std::lock_guard<std::mutex> lock(mNamespaceMutex); if (mDriverNamespace) { return mDriverNamespace; } if (mDriverPath.empty()) { return nullptr; } auto vndkNamespace = android_get_exported_namespace("vndk"); if (!vndkNamespace) { return nullptr; } 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; mDriverNamespace = nullptr; return; } } }); return mDriverNamespace; return mDriverNamespace; } } Loading libs/graphicsenv/include/graphicsenv/GraphicsEnv.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -129,6 +129,7 @@ private: void* loadLibrary(std::string name); void* loadLibrary(std::string name); bool checkAngleRules(void* so); bool checkAngleRules(void* so); void updateUseAngle(); void updateUseAngle(); bool linkDriverNamespaceLocked(android_namespace_t* vndkNamespace); GraphicsEnv() = default; GraphicsEnv() = default; std::string mDriverPath; std::string mDriverPath; Loading opengl/libs/EGL/Loader.cpp +85 −3 Original line number Original line Diff line number Diff line Loading @@ -84,6 +84,11 @@ static void* do_android_load_sphal_library(const char* path, int mode) { return android_load_sphal_library(path, 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) Loader::driver_t::driver_t(void* gles) { { dso[0] = gles; dso[0] = gles; Loading Loading @@ -180,11 +185,81 @@ static const char* HAL_SUBNAME_KEY_PROPERTIES[2] = { "ro.board.platform", "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) void* Loader::open(egl_connection_t* cnx) { { ATRACE_CALL(); ATRACE_CALL(); const nsecs_t openTime = systemTime(); 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(); setEmulatorGlesValue(); // Check if we should use ANGLE early, so loading each driver doesn't require repeated queries. // Check if we should use ANGLE early, so loading each driver doesn't require repeated queries. Loading Loading @@ -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", "couldn't find an OpenGL ES implementation, make sure you set %s or %s", HAL_SUBNAME_KEY_PROPERTIES[0], HAL_SUBNAME_KEY_PROPERTIES[1]); HAL_SUBNAME_KEY_PROPERTIES[0], HAL_SUBNAME_KEY_PROPERTIES[1]); if (!cnx->libEgl) { cnx->libEgl = load_wrapper(EGL_WRAPPER_DIR "/libEGL.so"); cnx->libEgl = load_wrapper(EGL_WRAPPER_DIR "/libEGL.so"); cnx->libGles2 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv2.so"); } if (!cnx->libGles1) { cnx->libGles1 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv1_CM.so"); 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) { if (!cnx->libEgl || !cnx->libGles2 || !cnx->libGles1) { android::GraphicsEnv::getInstance().setDriverLoaded(android::GraphicsEnv::Api::API_GL, android::GraphicsEnv::getInstance().setDriverLoaded(android::GraphicsEnv::Api::API_GL, Loading Loading @@ -584,6 +665,7 @@ Loader::driver_t* Loader::attempt_to_load_updated_driver(egl_connection_t* cnx) return nullptr; return nullptr; } } ALOGD("Load updated gl driver."); android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::GL_UPDATED); android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::GL_UPDATED); driver_t* hnd = nullptr; driver_t* hnd = nullptr; void* dso = load_updated_driver("GLES", ns); void* dso = load_updated_driver("GLES", ns); Loading opengl/libs/EGL/Loader.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -58,6 +58,7 @@ private: driver_t* attempt_to_load_angle(egl_connection_t* cnx); 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_updated_driver(egl_connection_t* cnx); driver_t* attempt_to_load_system_driver(egl_connection_t* cnx, const char* suffix, const bool exact); 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); void initialize_api(void* dso, egl_connection_t* cnx, uint32_t mask); static __attribute__((noinline)) static __attribute__((noinline)) Loading opengl/libs/EGL/egl.cpp +3 −7 Original line number Original line Diff line number Diff line Loading @@ -187,13 +187,9 @@ static EGLBoolean egl_init_drivers_locked() { // dynamically load our EGL implementation // dynamically load our EGL implementation egl_connection_t* cnx = &gEGLImpl; 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::GLESv1_INDEX] = cnx->hooks[egl_connection_t::GLESv2_INDEX] = &gHooks[egl_connection_t::GLESv2_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->dso = loader.open(cnx); } // Check to see if any layers are enabled and route functions through them // Check to see if any layers are enabled and route functions through them if (cnx->dso) { if (cnx->dso) { Loading Loading
libs/graphicsenv/GraphicsEnv.cpp +62 −49 Original line number Original line Diff line number Diff line Loading @@ -534,60 +534,73 @@ void GraphicsEnv::setDebugLayersGLES(const std::string layers) { mDebugLayersGLES = layers; mDebugLayersGLES = layers; } } android_namespace_t* GraphicsEnv::getDriverNamespace() { // Return true if all the required libraries from vndk and sphal namespace are static std::once_flag once; // linked to the Game Driver namespace correctly. std::call_once(once, [this]() { bool GraphicsEnv::linkDriverNamespaceLocked(android_namespace_t* vndkNamespace) { 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); const std::string llndkLibraries = getSystemNativeLibraries(NativeLibrary::LLNDK); if (llndkLibraries.empty()) { if (llndkLibraries.empty()) { mDriverNamespace = nullptr; return false; return; } } if (!android_link_namespaces(mDriverNamespace, nullptr, llndkLibraries.c_str())) { if (!android_link_namespaces(mDriverNamespace, nullptr, llndkLibraries.c_str())) { ALOGE("Failed to link default namespace[%s]", dlerror()); ALOGE("Failed to link default namespace[%s]", dlerror()); mDriverNamespace = nullptr; return false; return; } } const std::string vndkspLibraries = getSystemNativeLibraries(NativeLibrary::VNDKSP); const std::string vndkspLibraries = getSystemNativeLibraries(NativeLibrary::VNDKSP); if (vndkspLibraries.empty()) { if (vndkspLibraries.empty()) { mDriverNamespace = nullptr; return false; return; } } if (!android_link_namespaces(mDriverNamespace, vndkNamespace, vndkspLibraries.c_str())) { if (!android_link_namespaces(mDriverNamespace, vndkNamespace, vndkspLibraries.c_str())) { ALOGE("Failed to link vndk namespace[%s]", dlerror()); ALOGE("Failed to link vndk namespace[%s]", dlerror()); mDriverNamespace = nullptr; return false; return; } } if (mSphalLibraries.empty()) return; if (mSphalLibraries.empty()) { return true; } // Make additional libraries in sphal to be accessible // Make additional libraries in sphal to be accessible auto sphalNamespace = android_get_exported_namespace("sphal"); auto sphalNamespace = android_get_exported_namespace("sphal"); if (!sphalNamespace) { if (!sphalNamespace) { ALOGE("Depend on these libraries[%s] in sphal, but failed to get sphal namespace", ALOGE("Depend on these libraries[%s] in sphal, but failed to get sphal namespace", mSphalLibraries.c_str()); mSphalLibraries.c_str()); mDriverNamespace = nullptr; return false; return; } } if (!android_link_namespaces(mDriverNamespace, sphalNamespace, mSphalLibraries.c_str())) { if (!android_link_namespaces(mDriverNamespace, sphalNamespace, mSphalLibraries.c_str())) { ALOGE("Failed to link sphal namespace[%s]", dlerror()); ALOGE("Failed to link sphal namespace[%s]", dlerror()); return false; } return true; } android_namespace_t* GraphicsEnv::getDriverNamespace() { std::lock_guard<std::mutex> lock(mNamespaceMutex); if (mDriverNamespace) { return mDriverNamespace; } if (mDriverPath.empty()) { return nullptr; } auto vndkNamespace = android_get_exported_namespace("vndk"); if (!vndkNamespace) { return nullptr; } 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; mDriverNamespace = nullptr; return; } } }); return mDriverNamespace; return mDriverNamespace; } } Loading
libs/graphicsenv/include/graphicsenv/GraphicsEnv.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -129,6 +129,7 @@ private: void* loadLibrary(std::string name); void* loadLibrary(std::string name); bool checkAngleRules(void* so); bool checkAngleRules(void* so); void updateUseAngle(); void updateUseAngle(); bool linkDriverNamespaceLocked(android_namespace_t* vndkNamespace); GraphicsEnv() = default; GraphicsEnv() = default; std::string mDriverPath; std::string mDriverPath; Loading
opengl/libs/EGL/Loader.cpp +85 −3 Original line number Original line Diff line number Diff line Loading @@ -84,6 +84,11 @@ static void* do_android_load_sphal_library(const char* path, int mode) { return android_load_sphal_library(path, 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) Loader::driver_t::driver_t(void* gles) { { dso[0] = gles; dso[0] = gles; Loading Loading @@ -180,11 +185,81 @@ static const char* HAL_SUBNAME_KEY_PROPERTIES[2] = { "ro.board.platform", "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) void* Loader::open(egl_connection_t* cnx) { { ATRACE_CALL(); ATRACE_CALL(); const nsecs_t openTime = systemTime(); 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(); setEmulatorGlesValue(); // Check if we should use ANGLE early, so loading each driver doesn't require repeated queries. // Check if we should use ANGLE early, so loading each driver doesn't require repeated queries. Loading Loading @@ -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", "couldn't find an OpenGL ES implementation, make sure you set %s or %s", HAL_SUBNAME_KEY_PROPERTIES[0], HAL_SUBNAME_KEY_PROPERTIES[1]); HAL_SUBNAME_KEY_PROPERTIES[0], HAL_SUBNAME_KEY_PROPERTIES[1]); if (!cnx->libEgl) { cnx->libEgl = load_wrapper(EGL_WRAPPER_DIR "/libEGL.so"); cnx->libEgl = load_wrapper(EGL_WRAPPER_DIR "/libEGL.so"); cnx->libGles2 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv2.so"); } if (!cnx->libGles1) { cnx->libGles1 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv1_CM.so"); 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) { if (!cnx->libEgl || !cnx->libGles2 || !cnx->libGles1) { android::GraphicsEnv::getInstance().setDriverLoaded(android::GraphicsEnv::Api::API_GL, android::GraphicsEnv::getInstance().setDriverLoaded(android::GraphicsEnv::Api::API_GL, Loading Loading @@ -584,6 +665,7 @@ Loader::driver_t* Loader::attempt_to_load_updated_driver(egl_connection_t* cnx) return nullptr; return nullptr; } } ALOGD("Load updated gl driver."); android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::GL_UPDATED); android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::GL_UPDATED); driver_t* hnd = nullptr; driver_t* hnd = nullptr; void* dso = load_updated_driver("GLES", ns); void* dso = load_updated_driver("GLES", ns); Loading
opengl/libs/EGL/Loader.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -58,6 +58,7 @@ private: driver_t* attempt_to_load_angle(egl_connection_t* cnx); 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_updated_driver(egl_connection_t* cnx); driver_t* attempt_to_load_system_driver(egl_connection_t* cnx, const char* suffix, const bool exact); 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); void initialize_api(void* dso, egl_connection_t* cnx, uint32_t mask); static __attribute__((noinline)) static __attribute__((noinline)) Loading
opengl/libs/EGL/egl.cpp +3 −7 Original line number Original line Diff line number Diff line Loading @@ -187,13 +187,9 @@ static EGLBoolean egl_init_drivers_locked() { // dynamically load our EGL implementation // dynamically load our EGL implementation egl_connection_t* cnx = &gEGLImpl; 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::GLESv1_INDEX] = cnx->hooks[egl_connection_t::GLESv2_INDEX] = &gHooks[egl_connection_t::GLESv2_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->dso = loader.open(cnx); } // Check to see if any layers are enabled and route functions through them // Check to see if any layers are enabled and route functions through them if (cnx->dso) { if (cnx->dso) { Loading