Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 08efa6ba authored by Peiyong Lin's avatar Peiyong Lin Committed by Gerrit Code Review
Browse files

Merge "Make ANGLE loadable from system image." into main

parents d4bdb4b5 e4da7a81
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -575,17 +575,23 @@ android_namespace_t* GraphicsEnv::getAngleNamespace() {
        return mAngleNamespace;
    }

    if (mAnglePath.empty() && !mShouldUseSystemAngle) {
        ALOGV("mAnglePath is empty and not using system ANGLE, abort creating ANGLE namespace");
    // If ANGLE path is not set, it means ANGLE should not be used for this process;
    // or if ANGLE path is set and set to use system ANGLE, then a namespace is not needed
    // because:
    //     1) if the default OpenGL ES driver is already ANGLE, then the loader will skip;
    //     2) if the default OpenGL ES driver is native, then there's no symbol conflict;
    //     3) if there's no OpenGL ES driver is preloaded, then there's no symbol conflict.
    if (mAnglePath.empty() || mShouldUseSystemAngle) {
        ALOGV("mAnglePath is empty or use system ANGLE, abort creating ANGLE namespace");
        return nullptr;
    }

    // Construct the search paths for system ANGLE.
    const char* const defaultLibraryPaths =
#if defined(__LP64__)
            "/vendor/lib64/egl:/system/lib64/egl";
            "/vendor/lib64/egl:/system/lib64";
#else
            "/vendor/lib/egl:/system/lib/egl";
            "/vendor/lib/egl:/system/lib";
#endif

    // If the application process will run on top of system ANGLE, construct the namespace
+85 −64
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ namespace android {
static const char* PERSIST_DRIVER_SUFFIX_PROPERTY = "persist.graphics.egl";
static const char* RO_DRIVER_SUFFIX_PROPERTY = "ro.hardware.egl";
static const char* RO_BOARD_PLATFORM_PROPERTY = "ro.board.platform";
static const char* ANGLE_SUFFIX_VALUE = "angle";

static const char* HAL_SUBNAME_KEY_PROPERTIES[3] = {
        PERSIST_DRIVER_SUFFIX_PROPERTY,
@@ -80,6 +81,13 @@ static const char* const VENDOR_LIB_EGL_DIR =
        "/vendor/lib/egl";
#endif

static const char* const SYSTEM_LIB_DIR =
#if defined(__LP64__)
        "/system/lib64";
#else
        "/system/lib";
#endif

static void* do_dlopen(const char* path, int mode) {
    ATRACE_CALL();
    return dlopen(path, mode);
@@ -434,32 +442,17 @@ void Loader::init_api(void* dso,
    }
}

static void* load_system_driver(const char* kind, const char* suffix, const bool exact) {
    ATRACE_CALL();
    class MatchFile {
    public:
        static std::string find(const char* libraryName, const bool exact) {
            std::string absolutePath;
            if (findLibPath(absolutePath, libraryName, exact)) {
                return absolutePath;
            }

            // Driver not found. gah.
            return std::string();
        }
    private:
        static bool findLibPath(std::string& result, const std::string& pattern, bool exact) {
            const std::string vendorLibEglDirString = std::string(VENDOR_LIB_EGL_DIR);
static std::string findLibrary(const std::string libraryName, const std::string searchPath,
                               const bool exact) {
    if (exact) {
                std::string absolutePath = vendorLibEglDirString + "/" + pattern + ".so";
        std::string absolutePath = searchPath + "/" + libraryName + ".so";
        if (!access(absolutePath.c_str(), R_OK)) {
                    result = absolutePath;
                    return true;
            return absolutePath;
        }
                return false;
        return std::string();
    }

            DIR* d = opendir(VENDOR_LIB_EGL_DIR);
    DIR* d = opendir(searchPath.c_str());
    if (d != nullptr) {
        struct dirent* e;
        while ((e = readdir(d)) != nullptr) {
@@ -470,62 +463,87 @@ static void* load_system_driver(const char* kind, const char* suffix, const bool
                // always skip the software renderer
                continue;
            }
                    if (strstr(e->d_name, pattern.c_str()) == e->d_name) {
            if (strstr(e->d_name, libraryName.c_str()) == e->d_name) {
                if (!strcmp(e->d_name + strlen(e->d_name) - 3, ".so")) {
                            result = vendorLibEglDirString + "/" + e->d_name;
                    std::string result = searchPath + "/" + e->d_name;
                    closedir(d);
                            return true;
                    return result;
                }
            }
        }
        closedir(d);
    }
            return false;
    // Driver not found. gah.
    return std::string();
}
    };

static void* load_system_driver(const char* kind, const char* suffix, const bool exact) {
    ATRACE_CALL();

    std::string libraryName = std::string("lib") + kind;
    if (suffix) {
        libraryName += std::string("_") + suffix;
    } else if (!exact) {
        // Deprecated: we look for files that match
        //      libGLES_*.so, or:
        // Deprecated for devices launching in Android 14
        // Look for files that match
        //      libGLES_*.so, or,
        //      libEGL_*.so, libGLESv1_CM_*.so, libGLESv2_*.so
        libraryName += std::string("_");
    }
    std::string absolutePath = MatchFile::find(libraryName.c_str(), exact);

    void* dso = nullptr;

    // Only use sphal namespace when system ANGLE binaries are not the default drivers.
    const bool useSphalNamespace = strcmp(suffix, ANGLE_SUFFIX_VALUE) != 0;

    const std::string absolutePath =
            findLibrary(libraryName, useSphalNamespace ? VENDOR_LIB_EGL_DIR : SYSTEM_LIB_PATH,
                        exact);
    if (absolutePath.empty()) {
        // this happens often, we don't want to log an error
        return nullptr;
    }
    const char* const driver_absolute_path = absolutePath.c_str();
    const char* const driverAbsolutePath = absolutePath.c_str();

    // Currently the default driver is unlikely to be ANGLE on most devices,
    // hence put this first.
    if (useSphalNamespace) {
        // Try to load drivers from the 'sphal' namespace, if it exist. Fall back to
        // the original routine when the namespace does not exist.
    // See /system/core/rootdir/etc/ld.config.txt for the configuration of the
        // See /system/linkerconfig/contents/namespace for the configuration of the
        // sphal namespace.
    void* dso = do_android_load_sphal_library(driver_absolute_path,
                                              RTLD_NOW | RTLD_LOCAL);
        dso = do_android_load_sphal_library(driverAbsolutePath, RTLD_NOW | RTLD_LOCAL);
    } else {
        // Try to load drivers from the default namespace.
        // See /system/linkerconfig/contents/namespace for the configuration of the
        // default namespace.
        dso = do_dlopen(driverAbsolutePath, RTLD_NOW | RTLD_LOCAL);
    }

    if (dso == nullptr) {
        const char* err = dlerror();
        ALOGE("load_driver(%s): %s", driver_absolute_path, err ? err : "unknown");
        ALOGE("load_driver(%s): %s", driverAbsolutePath, err ? err : "unknown");
        return nullptr;
    }

    ALOGD("loaded %s", driver_absolute_path);
    ALOGV("loaded %s", driverAbsolutePath);

    return dso;
}

static void* load_angle(const char* kind, android_namespace_t* ns) {
    std::string name = std::string("lib") + kind + "_angle.so";
    void* so = nullptr;

    if (android::GraphicsEnv::getInstance().shouldUseSystemAngle()) {
        so = do_dlopen(name.c_str(), RTLD_NOW | RTLD_LOCAL);
    } else {
        const android_dlextinfo dlextinfo = {
                .flags = ANDROID_DLEXT_USE_NAMESPACE,
                .library_namespace = ns,
        };

    std::string name = std::string("lib") + kind + "_angle.so";

    void* 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) {
        return so;
@@ -563,11 +581,13 @@ Loader::driver_t* Loader::attempt_to_load_angle(egl_connection_t* cnx) {
    ATRACE_CALL();

    android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace();
    if (!ns) {
    // ANGLE namespace is used for loading ANGLE from apk, and hence if namespace is not
    // constructed, it means ANGLE apk is not set to be the OpenGL ES driver.
    // Hence skip if ANGLE apk and system ANGLE are not set to be the OpenGL ES driver.
    if (!ns && !android::GraphicsEnv::getInstance().shouldUseSystemAngle()) {
        return nullptr;
    }

    android::GraphicsEnv::getInstance().setDriverToLoad(android::GpuStatsInfo::Driver::ANGLE);
    driver_t* hnd = nullptr;

    // ANGLE doesn't ship with GLES library, and thus we skip GLES driver.
@@ -592,6 +612,7 @@ void Loader::attempt_to_init_angle_backend(void* dso, egl_connection_t* cnx) {
    if (pANGLEGetDisplayPlatform) {
        ALOGV("ANGLE GLES library loaded");
        cnx->angleLoaded = true;
        android::GraphicsEnv::getInstance().setDriverToLoad(android::GpuStatsInfo::Driver::ANGLE);
    } else {
        ALOGV("Native GLES library loaded");
        cnx->angleLoaded = false;
+2 −2
Original line number Diff line number Diff line
@@ -128,8 +128,8 @@ bool initializeAnglePlatform(EGLDisplay dpy) {
            return false;
        }
    } else {
        // If we are here, ANGLE is loaded as built-in gl driver in the sphal.
        so = android_load_sphal_library(kAngleEs2Lib, kAngleDlFlags);
        // If we are here, ANGLE is loaded as the default OpenGL ES driver.
        so = dlopen(kAngleEs2Lib, kAngleDlFlags);
        if (so) {
            ALOGD("dlopen (%s) success at %p", kAngleEs2Lib, so);
        } else {