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

Commit 271c3134 authored by Yiwei Zhang's avatar Yiwei Zhang Committed by android-build-merger
Browse files

Merge "GL: unload system driver if needed" into qt-dev

am: b0406010

Change-Id: Ia29d05f1cce12f2f767d07f109f8ea930572ac61
parents f91264c7 b0406010
Loading
Loading
Loading
Loading
+62 −49
Original line number Original line Diff line number Diff line
@@ -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;
}
}
+1 −0
Original line number Original line Diff line number Diff line
@@ -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;
+85 −3
Original line number Original line Diff line number Diff line
@@ -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;
@@ -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.
@@ -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,
@@ -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);
+1 −0
Original line number Original line Diff line number Diff line
@@ -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))
+3 −7
Original line number Original line Diff line number Diff line
@@ -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