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

Commit 8cd204d6 authored by Peiyong Lin's avatar Peiyong Lin
Browse files

[GL Loader] Split loading logic based on API set and driver choices.

Previously, the order of loading the graphics driver is:
1) Try to load libGLES from ANGLE -> Driver apk -> emulation driver -> system;
2) If 1) fails, fall back to load [libEGL, libGLESv1_CM, libGLESv2] from ANGLE
  -> Driver apk -> emulation driver -> system.

However, there might be multiple variants of the same library exist in the
device and they all follow the same naming convention, which makes the driver
loading choice unpredictable. This patch refactors this ordering such that, we
loop over driver choices first, and for each driver choice, we try to see if we
can load either libGLES or [libEGL, libGLESv1_CM, libGLESv2] from it, if fails,
proceed to the next driver choice.

Minor: Code clean up here and there.

BUG: 127353494
Test: Build, verified with Developer Options and emulator
Test: atest CtsAngleIntegrationHostTestCases
Change-Id: I408dc20d8e41f69eac25c943e7c79af559d3d160
parent 7f2d108a
Loading
Loading
Loading
Loading
+115 −59
Original line number Original line Diff line number Diff line
@@ -39,10 +39,7 @@
#include "egldefs.h"
#include "egldefs.h"
#include <EGL/eglext_angle.h>
#include <EGL/eglext_angle.h>


// ----------------------------------------------------------------------------
namespace android {
namespace android {
// ----------------------------------------------------------------------------



/*
/*
 * EGL userspace drivers must be provided either:
 * EGL userspace drivers must be provided either:
@@ -122,8 +119,6 @@ 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);
}
}


// ----------------------------------------------------------------------------

Loader::driver_t::driver_t(void* gles)
Loader::driver_t::driver_t(void* gles)
{
{
    dso[0] = gles;
    dso[0] = gles;
@@ -159,8 +154,6 @@ int Loader::driver_t::set(void* hnd, int32_t api)
    return 0;
    return 0;
}
}


// ----------------------------------------------------------------------------

Loader::Loader()
Loader::Loader()
    : getProcAddress(nullptr)
    : getProcAddress(nullptr)
{
{
@@ -220,9 +213,6 @@ void* Loader::open(egl_connection_t* cnx)
    ATRACE_CALL();
    ATRACE_CALL();
    const nsecs_t openTime = systemTime();
    const nsecs_t openTime = systemTime();


    void* dso;
    driver_t* hnd = nullptr;

    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.
@@ -232,19 +222,19 @@ void* Loader::open(egl_connection_t* cnx)
        cnx->shouldUseAngle = false;
        cnx->shouldUseAngle = false;
    }
    }


    dso = load_driver("GLES", cnx, EGL | GLESv1_CM | GLESv2);
    // Firstly, try to load ANGLE driver.
    if (dso) {
    driver_t* hnd = attempt_to_load_angle(cnx);
        hnd = new driver_t(dso);
    if (!hnd) {
    } else {
        // Secondly, try to load from driver apk.
        android::GraphicsEnv::getInstance().clearDriverLoadingInfo(
        hnd = attempt_to_load_updated_driver(cnx);
                android::GraphicsEnv::Api::API_GL);
    }
        // Always load EGL first
    if (!hnd) {
        dso = load_driver("EGL", cnx, EGL);
        // Thirdly, try to load emulation driver.
        if (dso) {
        hnd = attempt_to_load_emulation_driver(cnx);
            hnd = new driver_t(dso);
            hnd->set( load_driver("GLESv1_CM", cnx, GLESv1_CM), GLESv1_CM );
            hnd->set( load_driver("GLESv2",    cnx, GLESv2),    GLESv2 );
    }
    }
    if (!hnd) {
        // Finally, load system driver.
        hnd = attempt_to_load_system_driver(cnx);
    }
    }


    if (!hnd) {
    if (!hnd) {
@@ -360,7 +350,7 @@ void Loader::init_api(void* dso,
    }
    }
}
}


static void* attempt_to_load_emulation_driver(const char* kind) {
static void* load_emulation_driver(const char* kind) {
    const int emulationStatus = checkGlesEmulationStatus();
    const int emulationStatus = checkGlesEmulationStatus();


    // Invalid emulation status, abort.
    // Invalid emulation status, abort.
@@ -547,11 +537,6 @@ static void* load_angle_from_namespace(const char* kind, android_namespace_t* ns
}
}


static void* load_angle(const char* kind, android_namespace_t* ns, egl_connection_t* cnx) {
static void* load_angle(const char* kind, android_namespace_t* ns, egl_connection_t* cnx) {
    // Only attempt to load ANGLE libs
    if (strcmp(kind, "EGL") != 0 && strcmp(kind, "GLESv2") != 0 && strcmp(kind, "GLESv1_CM") != 0) {
        return nullptr;
    }

    void* so = nullptr;
    void* so = nullptr;


    if ((cnx->shouldUseAngle) || android::GraphicsEnv::getInstance().shouldUseAngle()) {
    if ((cnx->shouldUseAngle) || android::GraphicsEnv::getInstance().shouldUseAngle()) {
@@ -626,46 +611,119 @@ static void* load_updated_driver(const char* kind, android_namespace_t* ns) {
    return nullptr;
    return nullptr;
}
}


void *Loader::load_driver(const char* kind,
Loader::driver_t* Loader::attempt_to_load_angle(egl_connection_t* cnx) {
        egl_connection_t* cnx, uint32_t mask)
{
    ATRACE_CALL();
    ATRACE_CALL();

    void* dso = nullptr;
    android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace();
    android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace();
    if (ns) {
    if (!ns) {
        return nullptr;
    }

    android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::ANGLE);
    android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::ANGLE);
        dso = load_angle(kind, ns, cnx);
    driver_t* hnd = nullptr;

    // ANGLE doesn't ship with GLES library, and thus we skip GLES driver.
    void* dso = load_angle("EGL", ns, cnx);
    if (dso) {
    if (dso) {
            initialize_api(dso, cnx, mask);
        initialize_api(dso, cnx, EGL);
            return dso;
        hnd = new driver_t(dso);

        dso = load_angle("GLESv1_CM", ns, cnx);
        initialize_api(dso, cnx, GLESv1_CM);
        hnd->set(dso, GLESv1_CM);

        dso = load_angle("GLESv2", ns, cnx);
        initialize_api(dso, cnx, GLESv2);
        hnd->set(dso, GLESv2);
    }
    }
    return hnd;
}
}

Loader::driver_t* Loader::attempt_to_load_updated_driver(egl_connection_t* cnx) {
    ATRACE_CALL();
#ifndef __ANDROID_VNDK__
#ifndef __ANDROID_VNDK__
    ns = android::GraphicsEnv::getInstance().getDriverNamespace();
    android_namespace_t* ns = android::GraphicsEnv::getInstance().getDriverNamespace();
    if (ns) {
    if (!ns) {
        return nullptr;
    }

    android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::GL_UPDATED);
    android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::GL_UPDATED);
        dso = load_updated_driver(kind, ns);
    driver_t* hnd = nullptr;
    void* dso = load_updated_driver("GLES", ns);
    if (dso) {
    if (dso) {
            initialize_api(dso, cnx, mask);
        initialize_api(dso, cnx, EGL | GLESv1_CM | GLESv2);
            return dso;
        hnd = new driver_t(dso);
        return hnd;
    }
    }

    dso = load_updated_driver("EGL", ns);
    if (dso) {
        initialize_api(dso, cnx, EGL);
        hnd = new driver_t(dso);

        dso = load_updated_driver("GLESv1_CM", ns);
        initialize_api(dso, cnx, GLESv1_CM);
        hnd->set(dso, GLESv1_CM);

        dso = load_updated_driver("GLESv2", ns);
        initialize_api(dso, cnx, GLESv2);
        hnd->set(dso, GLESv2);
    }
    }
    return hnd;
#else
    return nullptr;
#endif
#endif
}

Loader::driver_t* Loader::attempt_to_load_emulation_driver(egl_connection_t* cnx) {
    ATRACE_CALL();
    android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::GL);
    android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::GL);
    dso = attempt_to_load_emulation_driver(kind);
    driver_t* hnd = nullptr;
    void* dso = load_emulation_driver("GLES");
    if (dso) {
    if (dso) {
        initialize_api(dso, cnx, mask);
        initialize_api(dso, cnx, EGL | GLESv1_CM | GLESv2);
        return dso;
        hnd = new driver_t(dso);
        return hnd;
    }
    dso = load_emulation_driver("EGL");
    if (dso) {
        initialize_api(dso, cnx, EGL);
        hnd = new driver_t(dso);

        dso = load_emulation_driver("GLESv1_CM");
        initialize_api(dso, cnx, GLESv1_CM);
        hnd->set(dso, GLESv1_CM);

        dso = load_emulation_driver("GLESv2");
        initialize_api(dso, cnx, GLESv2);
        hnd->set(dso, GLESv2);
    }
    return hnd;
}
}


    dso = load_system_driver(kind);
Loader::driver_t* Loader::attempt_to_load_system_driver(egl_connection_t* cnx) {
    ATRACE_CALL();
    android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::GL);
    driver_t* hnd = nullptr;
    void* dso = load_system_driver("GLES");
    if (dso) {
    if (dso) {
        initialize_api(dso, cnx, mask);
        initialize_api(dso, cnx, EGL | GLESv1_CM | GLESv2);
        return dso;
        hnd = new driver_t(dso);
        return hnd;
    }
    }
    dso = load_system_driver("EGL");
    if (dso) {
        initialize_api(dso, cnx, EGL);
        hnd = new driver_t(dso);


    return nullptr;
        dso = load_system_driver("GLESv1_CM");
        initialize_api(dso, cnx, GLESv1_CM);
        hnd->set(dso, GLESv1_CM);

        dso = load_system_driver("GLESv2");
        initialize_api(dso, cnx, GLESv2);
        hnd->set(dso, GLESv2);
    }
    return hnd;
}
}


void Loader::initialize_api(void* dso, egl_connection_t* cnx, uint32_t mask) {
void Loader::initialize_api(void* dso, egl_connection_t* cnx, uint32_t mask) {
@@ -710,6 +768,4 @@ void Loader::initialize_api(void* dso, egl_connection_t* cnx, uint32_t mask) {
    }
    }
}
}


// ----------------------------------------------------------------------------
} // namespace android
}; // namespace android
// ----------------------------------------------------------------------------
+4 −1
Original line number Original line Diff line number Diff line
@@ -55,7 +55,10 @@ public:


private:
private:
    Loader();
    Loader();
    void *load_driver(const char* kind, egl_connection_t* cnx, uint32_t mask);
    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_emulation_driver(egl_connection_t* cnx);
    driver_t* attempt_to_load_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))