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

Commit 901f8ee2 authored by Yiwei Zhang's avatar Yiwei Zhang
Browse files

Vulkan: unload builtin driver to reload updated driver if needed

Android historically preloads GL driver in Zygote to speed up app launch
time and avoid the duplicate extra memory for each process loading the
graphics driver. In Android 10, we landed GL driver unloading mechanism
to ship updatable driver and ANGLE without perf overhead on the rest of
the system.

To get prepared for the HWUI Vulkan backend being turned on as the
default renderer for UI componments, this CL will do the same to the
Vulkan driver to preload it in Zygote and unload so to reload updated
driver if needed.

Bug: 135536511
Test: atest CtsUiRenderingTestCases no regression on VK backend
Change-Id: I2909f6ecc4f011b1f3670aacdf817ed3b6e9a487
parent d5dc0406
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -54,8 +54,9 @@ typedef union {
/* A hwvulkan_device_t corresponds to an ICD on other systems. Currently there
 * can only be one on a system (HWVULKAN_DEVICE_0). It is opened once per
 * process when the Vulkan API is first used; the hw_device_t::close() function
 * is never called. Any non-trivial resource allocation should be done when
 * the VkInstance is created rather than when the hwvulkan_device_t is opened.
 * is called upon driver unloading. Any non-trivial resource allocation should
 * be done when the VkInstance is created rather than when the hwvulkan_device_t
 * is opened.
 */
typedef struct hwvulkan_device_t {
    struct hw_device_t common;
+12 −17
Original line number Diff line number Diff line
@@ -1174,23 +1174,18 @@ const LayerChain::ActiveLayer* LayerChain::GetActiveLayers(
// ----------------------------------------------------------------------------

bool EnsureInitialized() {
    static std::once_flag once_flag;
    static bool initialized;
    static bool initialized = false;
    static pid_t init_attempted_for_pid = 0;
    static std::mutex init_lock;

    std::call_once(once_flag, []() {
        if (driver::OpenHAL()) {
            initialized = true;
        }
    });
    std::lock_guard<std::mutex> lock(init_lock);
    if (init_attempted_for_pid == getpid())
        return initialized;

    {
        static pid_t pid = getpid() + 1;
        static std::mutex layer_lock;
        std::lock_guard<std::mutex> lock(layer_lock);
        if (pid != getpid()) {
            pid = getpid();
    init_attempted_for_pid = getpid();
    if (driver::OpenHAL()) {
        DiscoverLayers();
        }
        initialized = true;
    }

    return initialized;
+40 −1
Original line number Diff line number Diff line
@@ -84,6 +84,8 @@ class Hal {
    Hal(const Hal&) = delete;
    Hal& operator=(const Hal&) = delete;

    bool ShouldUnloadBuiltinDriver();
    void UnloadBuiltinDriver();
    bool InitDebugReportIndex();

    static Hal hal_;
@@ -243,7 +245,12 @@ bool Hal::Open() {

    const nsecs_t openTime = systemTime();

    ALOG_ASSERT(!hal_.dev_, "OpenHAL called more than once");
    if (hal_.ShouldUnloadBuiltinDriver()) {
        hal_.UnloadBuiltinDriver();
    }

    if (hal_.dev_)
        return true;

    // Use a stub device unless we successfully open a real HAL device.
    hal_.dev_ = &stubhal::kDevice;
@@ -288,6 +295,38 @@ bool Hal::Open() {
    return true;
}

bool Hal::ShouldUnloadBuiltinDriver() {
    // Should not unload since the driver was not loaded
    if (!hal_.dev_)
        return false;

    // Should not unload if stubhal is used on the device
    if (hal_.dev_ == &stubhal::kDevice)
        return false;

    // Unload the driver if updated driver is chosen
    if (android::GraphicsEnv::getInstance().getDriverNamespace())
        return true;

    return false;
}

void Hal::UnloadBuiltinDriver() {
    ATRACE_CALL();

    ALOGD("Unload builtin Vulkan driver.");

    // Close the opened device
    ALOG_ASSERT(!hal_.dev_->common.close(hal_.dev_->common),
                "hw_device_t::close() failed.");

    // Close the opened shared library in the hw_module_t
    dlclose(hal_.dev_->common.module->dso);

    hal_.dev_ = nullptr;
    hal_.debug_report_index_ = -1;
}

bool Hal::InitDebugReportIndex() {
    ATRACE_CALL();