Loading opengl/libs/EGL/Loader.cpp +67 −84 Original line number Original line Diff line number Diff line Loading @@ -208,6 +208,11 @@ static void setEmulatorGlesValue(void) { } } } } static const char* HAL_SUBNAME_KEY_PROPERTIES[2] = { "ro.hardware.egl", "ro.board.platform", }; void* Loader::open(egl_connection_t* cnx) void* Loader::open(egl_connection_t* cnx) { { ATRACE_CALL(); ATRACE_CALL(); Loading @@ -233,8 +238,30 @@ void* Loader::open(egl_connection_t* cnx) hnd = attempt_to_load_emulation_driver(cnx); hnd = attempt_to_load_emulation_driver(cnx); } } if (!hnd) { if (!hnd) { // Finally, load system driver. // Finally, try to load system driver, start by searching for the library name appended by hnd = attempt_to_load_system_driver(cnx); // the system properties of the GLES userspace driver in both locations. // i.e.: // libGLES_${prop}.so, or: // libEGL_${prop}.so, libGLESv1_CM_${prop}.so, libGLESv2_${prop}.so char prop[PROPERTY_VALUE_MAX + 1]; for (auto key : HAL_SUBNAME_KEY_PROPERTIES) { if (property_get(key, prop, nullptr) <= 0) { continue; } hnd = attempt_to_load_system_driver(cnx, prop); if (hnd) { break; } } } if (!hnd) { // Can't find graphics driver by appending system properties, now search for the exact name // without any suffix of the GLES userspace driver in both locations. // i.e.: // libGLES.so, or: // libEGL.so, libGLESv1_CM.so, libGLESv2.so hnd = attempt_to_load_system_driver(cnx, nullptr); } } if (!hnd) { if (!hnd) { Loading Loading @@ -408,13 +435,11 @@ static void* load_emulation_driver(const char* kind) { return dso; return dso; } } static void* load_system_driver(const char* kind) { static void* load_system_driver(const char* kind, const char* suffix) { ATRACE_CALL(); ATRACE_CALL(); class MatchFile { class MatchFile { public: public: static std::string find(const char* kind) { static std::string find(const char* libraryName) { std::string result; std::string pattern = std::string("lib") + kind; const char* const searchPaths[] = { const char* const searchPaths[] = { #if defined(__LP64__) #if defined(__LP64__) "/vendor/lib64/egl", "/vendor/lib64/egl", Loading @@ -425,74 +450,23 @@ static void* load_system_driver(const char* kind) { #endif #endif }; }; // first, we search for the exact name of the GLES userspace for (auto dir : searchPaths) { // driver in both locations. std::string absolutePath = dir + std::string("/") + libraryName + ".so"; // i.e.: // libGLES.so, or: // libEGL.so, libGLESv1_CM.so, libGLESv2.so for (size_t i=0 ; i<NELEM(searchPaths) ; i++) { if (find(result, pattern, searchPaths[i], true)) { return result; } } // for compatibility with the old "egl.cfg" naming convention // we look for files that match: // libGLES_*.so, or: // libEGL_*.so, libGLESv1_CM_*.so, libGLESv2_*.so pattern.append("_"); for (size_t i=0 ; i<NELEM(searchPaths) ; i++) { if (find(result, pattern, searchPaths[i], false)) { return result; } } // we didn't find the driver. gah. result.clear(); return result; } private: static bool find(std::string& result, const std::string& pattern, const char* const search, bool exact) { if (exact) { std::string absolutePath = std::string(search) + "/" + pattern + ".so"; if (!access(absolutePath.c_str(), R_OK)) { if (!access(absolutePath.c_str(), R_OK)) { result = absolutePath; return absolutePath; return true; } } return false; } } DIR* d = opendir(search); // Driver not found. gah. if (d != nullptr) { return std::string(); struct dirent* e; while ((e = readdir(d)) != nullptr) { if (e->d_type == DT_DIR) { continue; } if (!strcmp(e->d_name, "libGLES_android.so")) { // always skip the software renderer continue; } if (strstr(e->d_name, pattern.c_str()) == e->d_name) { if (!strcmp(e->d_name + strlen(e->d_name) - 3, ".so")) { result = std::string(search) + "/" + e->d_name; closedir(d); return true; } } } closedir(d); } return false; } } }; }; std::string libraryName = std::string("lib") + kind; std::string absolutePath = MatchFile::find(kind); if (suffix) { libraryName += std::string("_") + suffix; } std::string absolutePath = MatchFile::find(libraryName.c_str()); if (absolutePath.empty()) { if (absolutePath.empty()) { // this happens often, we don't want to log an error // this happens often, we don't want to log an error return nullptr; return nullptr; Loading Loading @@ -574,7 +548,20 @@ static void* load_angle(const char* kind, android_namespace_t* ns, egl_connectio cnx->angleBackend = angleBackendDefault; cnx->angleBackend = angleBackendDefault; if (!cnx->vendorEGL && (cnx->angleBackend == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)) { if (!cnx->vendorEGL && (cnx->angleBackend == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)) { // Find and load vendor libEGL for ANGLE's GL back-end to use. // Find and load vendor libEGL for ANGLE's GL back-end to use. cnx->vendorEGL = load_system_driver("EGL"); char prop[PROPERTY_VALUE_MAX + 1]; for (auto key : HAL_SUBNAME_KEY_PROPERTIES) { if (property_get(key, prop, nullptr) <= 0) { continue; } void* dso = load_system_driver("EGL", prop); if (dso) { cnx->vendorEGL = dso; break; } } if (!cnx->vendorEGL) { cnx->vendorEGL = load_system_driver("EGL", nullptr); } } } } else { } else { ALOGV("Loaded native %s library for '%s' (instead of ANGLE)", kind, ALOGV("Loaded native %s library for '%s' (instead of ANGLE)", kind, Loading @@ -586,11 +573,6 @@ static void* load_angle(const char* kind, android_namespace_t* ns, egl_connectio return so; return so; } } static const char* HAL_SUBNAME_KEY_PROPERTIES[2] = { "ro.hardware.egl", "ro.board.platform", }; static void* load_updated_driver(const char* kind, android_namespace_t* ns) { static void* load_updated_driver(const char* kind, android_namespace_t* ns) { ATRACE_CALL(); ATRACE_CALL(); const android_dlextinfo dlextinfo = { const android_dlextinfo dlextinfo = { Loading @@ -600,14 +582,15 @@ static void* load_updated_driver(const char* kind, android_namespace_t* ns) { void* so = nullptr; void* so = nullptr; char prop[PROPERTY_VALUE_MAX + 1]; char prop[PROPERTY_VALUE_MAX + 1]; for (auto key : HAL_SUBNAME_KEY_PROPERTIES) { for (auto key : HAL_SUBNAME_KEY_PROPERTIES) { if (property_get(key, prop, nullptr) > 0) { if (property_get(key, prop, nullptr) <= 0) { continue; } std::string name = std::string("lib") + kind + "_" + prop + ".so"; std::string name = std::string("lib") + kind + "_" + prop + ".so"; so = do_android_dlopen_ext(name.c_str(), RTLD_LOCAL | RTLD_NOW, &dlextinfo); so = do_android_dlopen_ext(name.c_str(), RTLD_LOCAL | RTLD_NOW, &dlextinfo); if (so) { if (so) { return so; return so; } } } } } return nullptr; return nullptr; } } Loading Loading @@ -700,26 +683,26 @@ Loader::driver_t* Loader::attempt_to_load_emulation_driver(egl_connection_t* cnx return hnd; return hnd; } } Loader::driver_t* Loader::attempt_to_load_system_driver(egl_connection_t* cnx) { Loader::driver_t* Loader::attempt_to_load_system_driver(egl_connection_t* cnx, const char* suffix) { ATRACE_CALL(); ATRACE_CALL(); android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::GL); android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::GL); driver_t* hnd = nullptr; driver_t* hnd = nullptr; void* dso = load_system_driver("GLES"); void* dso = load_system_driver("GLES", suffix); if (dso) { if (dso) { initialize_api(dso, cnx, EGL | GLESv1_CM | GLESv2); initialize_api(dso, cnx, EGL | GLESv1_CM | GLESv2); hnd = new driver_t(dso); hnd = new driver_t(dso); return hnd; return hnd; } } dso = load_system_driver("EGL"); dso = load_system_driver("EGL", suffix); if (dso) { if (dso) { initialize_api(dso, cnx, EGL); initialize_api(dso, cnx, EGL); hnd = new driver_t(dso); hnd = new driver_t(dso); dso = load_system_driver("GLESv1_CM"); dso = load_system_driver("GLESv1_CM", suffix); initialize_api(dso, cnx, GLESv1_CM); initialize_api(dso, cnx, GLESv1_CM); hnd->set(dso, GLESv1_CM); hnd->set(dso, GLESv1_CM); dso = load_system_driver("GLESv2"); dso = load_system_driver("GLESv2", suffix); initialize_api(dso, cnx, GLESv2); initialize_api(dso, cnx, GLESv2); hnd->set(dso, GLESv2); hnd->set(dso, GLESv2); } } Loading opengl/libs/EGL/Loader.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -58,7 +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_emulation_driver(egl_connection_t* cnx); driver_t* attempt_to_load_emulation_driver(egl_connection_t* cnx); driver_t* attempt_to_load_system_driver(egl_connection_t* cnx); driver_t* attempt_to_load_system_driver(egl_connection_t* cnx, const char* suffix); 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 Loading
opengl/libs/EGL/Loader.cpp +67 −84 Original line number Original line Diff line number Diff line Loading @@ -208,6 +208,11 @@ static void setEmulatorGlesValue(void) { } } } } static const char* HAL_SUBNAME_KEY_PROPERTIES[2] = { "ro.hardware.egl", "ro.board.platform", }; void* Loader::open(egl_connection_t* cnx) void* Loader::open(egl_connection_t* cnx) { { ATRACE_CALL(); ATRACE_CALL(); Loading @@ -233,8 +238,30 @@ void* Loader::open(egl_connection_t* cnx) hnd = attempt_to_load_emulation_driver(cnx); hnd = attempt_to_load_emulation_driver(cnx); } } if (!hnd) { if (!hnd) { // Finally, load system driver. // Finally, try to load system driver, start by searching for the library name appended by hnd = attempt_to_load_system_driver(cnx); // the system properties of the GLES userspace driver in both locations. // i.e.: // libGLES_${prop}.so, or: // libEGL_${prop}.so, libGLESv1_CM_${prop}.so, libGLESv2_${prop}.so char prop[PROPERTY_VALUE_MAX + 1]; for (auto key : HAL_SUBNAME_KEY_PROPERTIES) { if (property_get(key, prop, nullptr) <= 0) { continue; } hnd = attempt_to_load_system_driver(cnx, prop); if (hnd) { break; } } } if (!hnd) { // Can't find graphics driver by appending system properties, now search for the exact name // without any suffix of the GLES userspace driver in both locations. // i.e.: // libGLES.so, or: // libEGL.so, libGLESv1_CM.so, libGLESv2.so hnd = attempt_to_load_system_driver(cnx, nullptr); } } if (!hnd) { if (!hnd) { Loading Loading @@ -408,13 +435,11 @@ static void* load_emulation_driver(const char* kind) { return dso; return dso; } } static void* load_system_driver(const char* kind) { static void* load_system_driver(const char* kind, const char* suffix) { ATRACE_CALL(); ATRACE_CALL(); class MatchFile { class MatchFile { public: public: static std::string find(const char* kind) { static std::string find(const char* libraryName) { std::string result; std::string pattern = std::string("lib") + kind; const char* const searchPaths[] = { const char* const searchPaths[] = { #if defined(__LP64__) #if defined(__LP64__) "/vendor/lib64/egl", "/vendor/lib64/egl", Loading @@ -425,74 +450,23 @@ static void* load_system_driver(const char* kind) { #endif #endif }; }; // first, we search for the exact name of the GLES userspace for (auto dir : searchPaths) { // driver in both locations. std::string absolutePath = dir + std::string("/") + libraryName + ".so"; // i.e.: // libGLES.so, or: // libEGL.so, libGLESv1_CM.so, libGLESv2.so for (size_t i=0 ; i<NELEM(searchPaths) ; i++) { if (find(result, pattern, searchPaths[i], true)) { return result; } } // for compatibility with the old "egl.cfg" naming convention // we look for files that match: // libGLES_*.so, or: // libEGL_*.so, libGLESv1_CM_*.so, libGLESv2_*.so pattern.append("_"); for (size_t i=0 ; i<NELEM(searchPaths) ; i++) { if (find(result, pattern, searchPaths[i], false)) { return result; } } // we didn't find the driver. gah. result.clear(); return result; } private: static bool find(std::string& result, const std::string& pattern, const char* const search, bool exact) { if (exact) { std::string absolutePath = std::string(search) + "/" + pattern + ".so"; if (!access(absolutePath.c_str(), R_OK)) { if (!access(absolutePath.c_str(), R_OK)) { result = absolutePath; return absolutePath; return true; } } return false; } } DIR* d = opendir(search); // Driver not found. gah. if (d != nullptr) { return std::string(); struct dirent* e; while ((e = readdir(d)) != nullptr) { if (e->d_type == DT_DIR) { continue; } if (!strcmp(e->d_name, "libGLES_android.so")) { // always skip the software renderer continue; } if (strstr(e->d_name, pattern.c_str()) == e->d_name) { if (!strcmp(e->d_name + strlen(e->d_name) - 3, ".so")) { result = std::string(search) + "/" + e->d_name; closedir(d); return true; } } } closedir(d); } return false; } } }; }; std::string libraryName = std::string("lib") + kind; std::string absolutePath = MatchFile::find(kind); if (suffix) { libraryName += std::string("_") + suffix; } std::string absolutePath = MatchFile::find(libraryName.c_str()); if (absolutePath.empty()) { if (absolutePath.empty()) { // this happens often, we don't want to log an error // this happens often, we don't want to log an error return nullptr; return nullptr; Loading Loading @@ -574,7 +548,20 @@ static void* load_angle(const char* kind, android_namespace_t* ns, egl_connectio cnx->angleBackend = angleBackendDefault; cnx->angleBackend = angleBackendDefault; if (!cnx->vendorEGL && (cnx->angleBackend == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)) { if (!cnx->vendorEGL && (cnx->angleBackend == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)) { // Find and load vendor libEGL for ANGLE's GL back-end to use. // Find and load vendor libEGL for ANGLE's GL back-end to use. cnx->vendorEGL = load_system_driver("EGL"); char prop[PROPERTY_VALUE_MAX + 1]; for (auto key : HAL_SUBNAME_KEY_PROPERTIES) { if (property_get(key, prop, nullptr) <= 0) { continue; } void* dso = load_system_driver("EGL", prop); if (dso) { cnx->vendorEGL = dso; break; } } if (!cnx->vendorEGL) { cnx->vendorEGL = load_system_driver("EGL", nullptr); } } } } else { } else { ALOGV("Loaded native %s library for '%s' (instead of ANGLE)", kind, ALOGV("Loaded native %s library for '%s' (instead of ANGLE)", kind, Loading @@ -586,11 +573,6 @@ static void* load_angle(const char* kind, android_namespace_t* ns, egl_connectio return so; return so; } } static const char* HAL_SUBNAME_KEY_PROPERTIES[2] = { "ro.hardware.egl", "ro.board.platform", }; static void* load_updated_driver(const char* kind, android_namespace_t* ns) { static void* load_updated_driver(const char* kind, android_namespace_t* ns) { ATRACE_CALL(); ATRACE_CALL(); const android_dlextinfo dlextinfo = { const android_dlextinfo dlextinfo = { Loading @@ -600,14 +582,15 @@ static void* load_updated_driver(const char* kind, android_namespace_t* ns) { void* so = nullptr; void* so = nullptr; char prop[PROPERTY_VALUE_MAX + 1]; char prop[PROPERTY_VALUE_MAX + 1]; for (auto key : HAL_SUBNAME_KEY_PROPERTIES) { for (auto key : HAL_SUBNAME_KEY_PROPERTIES) { if (property_get(key, prop, nullptr) > 0) { if (property_get(key, prop, nullptr) <= 0) { continue; } std::string name = std::string("lib") + kind + "_" + prop + ".so"; std::string name = std::string("lib") + kind + "_" + prop + ".so"; so = do_android_dlopen_ext(name.c_str(), RTLD_LOCAL | RTLD_NOW, &dlextinfo); so = do_android_dlopen_ext(name.c_str(), RTLD_LOCAL | RTLD_NOW, &dlextinfo); if (so) { if (so) { return so; return so; } } } } } return nullptr; return nullptr; } } Loading Loading @@ -700,26 +683,26 @@ Loader::driver_t* Loader::attempt_to_load_emulation_driver(egl_connection_t* cnx return hnd; return hnd; } } Loader::driver_t* Loader::attempt_to_load_system_driver(egl_connection_t* cnx) { Loader::driver_t* Loader::attempt_to_load_system_driver(egl_connection_t* cnx, const char* suffix) { ATRACE_CALL(); ATRACE_CALL(); android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::GL); android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::GL); driver_t* hnd = nullptr; driver_t* hnd = nullptr; void* dso = load_system_driver("GLES"); void* dso = load_system_driver("GLES", suffix); if (dso) { if (dso) { initialize_api(dso, cnx, EGL | GLESv1_CM | GLESv2); initialize_api(dso, cnx, EGL | GLESv1_CM | GLESv2); hnd = new driver_t(dso); hnd = new driver_t(dso); return hnd; return hnd; } } dso = load_system_driver("EGL"); dso = load_system_driver("EGL", suffix); if (dso) { if (dso) { initialize_api(dso, cnx, EGL); initialize_api(dso, cnx, EGL); hnd = new driver_t(dso); hnd = new driver_t(dso); dso = load_system_driver("GLESv1_CM"); dso = load_system_driver("GLESv1_CM", suffix); initialize_api(dso, cnx, GLESv1_CM); initialize_api(dso, cnx, GLESv1_CM); hnd->set(dso, GLESv1_CM); hnd->set(dso, GLESv1_CM); dso = load_system_driver("GLESv2"); dso = load_system_driver("GLESv2", suffix); initialize_api(dso, cnx, GLESv2); initialize_api(dso, cnx, GLESv2); hnd->set(dso, GLESv2); hnd->set(dso, GLESv2); } } Loading
opengl/libs/EGL/Loader.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -58,7 +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_emulation_driver(egl_connection_t* cnx); driver_t* attempt_to_load_emulation_driver(egl_connection_t* cnx); driver_t* attempt_to_load_system_driver(egl_connection_t* cnx); driver_t* attempt_to_load_system_driver(egl_connection_t* cnx, const char* suffix); 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