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

Commit 7aec354b authored by Stefania Halac's avatar Stefania Halac Committed by Android (Google) Code Review
Browse files

Merge "opengl: Revert "opengl: defer GLESV1 library loading until context creation time""

parents a02c87df 840bd53e
Loading
Loading
Loading
Loading
+31 −92
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <dlfcn.h>

#include <android/dlext.h>
#include <cutils/properties.h>
#include <log/log.h>
#include <utils/Timers.h>

@@ -205,7 +206,6 @@ void Loader::unload_system_driver(egl_connection_t* cnx) {
    }

    cnx->systemDriverUnloaded = true;
    cnx->loadedDriverType = egl_connection_t::GLES_NO_DRIVER;
}

void* Loader::open(egl_connection_t* cnx)
@@ -228,7 +228,6 @@ void* Loader::open(egl_connection_t* cnx)
    } else {
        cnx->shouldUseAngle = false;
    }
    cnx->loadedDriverType = egl_connection_t::GLES_NO_DRIVER;

    // Firstly, try to load ANGLE driver.
    driver_t* hnd = attempt_to_load_angle(cnx);
@@ -238,7 +237,6 @@ void* Loader::open(egl_connection_t* cnx)
    }

    bool failToLoadFromDriverSuffixProperty = false;
    cnx->systemDriverUseExactName = true;
    if (!hnd) {
        // If updated driver apk is set but fail to load, abort here.
        if (android::GraphicsEnv::getInstance().getDriverNamespace()) {
@@ -250,22 +248,19 @@ void* Loader::open(egl_connection_t* cnx)
        // 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, cnx->systemDriverProperty, nullptr) <= 0) {
            if (property_get(key, prop, nullptr) <= 0) {
                continue;
            }
            hnd = attempt_to_load_system_driver(cnx, cnx->systemDriverProperty,
                                                cnx->systemDriverUseExactName);
            hnd = attempt_to_load_system_driver(cnx, prop, true);
            if (hnd) {
                cnx->systemDriverUseProperty = true;
                break;
            } else {
                if (strcmp(key, DRIVER_SUFFIX_PROPERTY) == 0) {
            } else if (strcmp(key, DRIVER_SUFFIX_PROPERTY) == 0) {
                failToLoadFromDriverSuffixProperty = true;
            }
        }
    }
    }

    if (!hnd) {
        // Can't find graphics driver by appending system properties, now search for the exact name
@@ -273,12 +268,11 @@ void* Loader::open(egl_connection_t* cnx)
        // i.e.:
        //      libGLES.so, or:
        //      libEGL.so, libGLESv1_CM.so, libGLESv2.so
        hnd = attempt_to_load_system_driver(cnx, nullptr, cnx->systemDriverUseExactName);
        hnd = attempt_to_load_system_driver(cnx, nullptr, true);
    }

    if (!hnd && !failToLoadFromDriverSuffixProperty) {
        cnx->systemDriverUseExactName = false;
        hnd = attempt_to_load_system_driver(cnx, nullptr, cnx->systemDriverUseExactName);
        hnd = attempt_to_load_system_driver(cnx, nullptr, false);
    }

    if (!hnd) {
@@ -293,11 +287,14 @@ void* Loader::open(egl_connection_t* cnx)
    if (!cnx->libEgl) {
        cnx->libEgl = load_wrapper(EGL_WRAPPER_DIR "/libEGL.so");
    }
    if (!cnx->libGles1) {
        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) {
    if (!cnx->libEgl || !cnx->libGles2 || !cnx->libGles1) {
        android::GraphicsEnv::getInstance().setDriverLoaded(android::GpuStatsInfo::Api::API_GL,
                                                            false, systemTime() - openTime);
    }
@@ -305,7 +302,8 @@ void* Loader::open(egl_connection_t* cnx)
    LOG_ALWAYS_FATAL_IF(!cnx->libEgl,
            "couldn't load system EGL wrapper libraries");

    LOG_ALWAYS_FATAL_IF(!cnx->libGles2, "couldn't load system OpenGL ESv2+ wrapper libraries");
    LOG_ALWAYS_FATAL_IF(!cnx->libGles2 || !cnx->libGles1,
                        "couldn't load system OpenGL ES wrapper libraries");

    android::GraphicsEnv::getInstance().setDriverLoaded(android::GpuStatsInfo::Api::API_GL, true,
                                                        systemTime() - openTime);
@@ -321,7 +319,7 @@ void Loader::close(egl_connection_t* cnx)

    cnx->shouldUseAngle = false;
    cnx->angleDecided = false;
    cnx->loadedDriverType = egl_connection_t::GLES_NO_DRIVER;
    cnx->useAngle = false;

    if (cnx->vendorEGL) {
        dlclose(cnx->vendorEGL);
@@ -526,6 +524,7 @@ static void* load_angle(const char* kind, android_namespace_t* ns, egl_connectio
    if (so) {
        ALOGV("Loaded ANGLE %s library for '%s' (instead of native)", kind,
            android::GraphicsEnv::getInstance().getAngleAppName().c_str());
        cnx->useAngle = true;

        char prop[PROPERTY_VALUE_MAX];

@@ -568,6 +567,7 @@ static void* load_angle(const char* kind, android_namespace_t* ns, egl_connectio
    } else {
        ALOGV("Loaded native %s library for '%s' (instead of ANGLE)", kind,
            android::GraphicsEnv::getInstance().getAngleAppName().c_str());
        cnx->useAngle = false;
    }
    cnx->angleDecided = true;

@@ -597,7 +597,6 @@ static void* load_updated_driver(const char* kind, android_namespace_t* ns) {

Loader::driver_t* Loader::attempt_to_load_angle(egl_connection_t* cnx) {
    ATRACE_CALL();
    assert(cnx->loadedDriverType == egl_connection_t::GLES_NO_DRIVER);
    android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace();
    if (!ns) {
        return nullptr;
@@ -612,17 +611,19 @@ Loader::driver_t* Loader::attempt_to_load_angle(egl_connection_t* cnx) {
        initialize_api(dso, cnx, EGL);
        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);
        cnx->loadedDriverType = egl_connection_t::GLES_ANGLE_STANDALONE_DRIVER;
    }
    return hnd;
}

Loader::driver_t* Loader::attempt_to_load_updated_driver(egl_connection_t* cnx) {
    ATRACE_CALL();
    assert(cnx->loadedDriverType == egl_connection_t::GLES_NO_DRIVER);
#ifndef __ANDROID_VNDK__
    android_namespace_t* ns = android::GraphicsEnv::getInstance().getDriverNamespace();
    if (!ns) {
@@ -634,9 +635,8 @@ Loader::driver_t* Loader::attempt_to_load_updated_driver(egl_connection_t* cnx)
    driver_t* hnd = nullptr;
    void* dso = load_updated_driver("GLES", ns);
    if (dso) {
        initialize_api(dso, cnx, EGL | GLESv2);
        initialize_api(dso, cnx, EGL | GLESv1_CM | GLESv2);
        hnd = new driver_t(dso);
        if (hnd) cnx->loadedDriverType = egl_connection_t::GLES_UPDATED_COMBO_DRIVER;
        return hnd;
    }

@@ -645,10 +645,13 @@ Loader::driver_t* Loader::attempt_to_load_updated_driver(egl_connection_t* cnx)
        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);
        cnx->loadedDriverType = egl_connection_t::GLES_UPDATED_STANDALONE_DRIVER;
    }
    return hnd;
#else
@@ -659,94 +662,30 @@ Loader::driver_t* Loader::attempt_to_load_updated_driver(egl_connection_t* cnx)
Loader::driver_t* Loader::attempt_to_load_system_driver(egl_connection_t* cnx, const char* suffix,
                                                        const bool exact) {
    ATRACE_CALL();
    assert(cnx->loadedDriverType == egl_connection_t::GLES_NO_DRIVER);
    android::GraphicsEnv::getInstance().setDriverToLoad(android::GpuStatsInfo::Driver::GL);
    driver_t* hnd = nullptr;
    void* dso = load_system_driver("GLES", suffix, exact);
    if (dso) {
        initialize_api(dso, cnx, EGL | GLESv2);
        initialize_api(dso, cnx, EGL | GLESv1_CM | GLESv2);
        hnd = new driver_t(dso);
        if (hnd) cnx->loadedDriverType = egl_connection_t::GLES_SYSTEM_COMBO_DRIVER;
        return hnd;
    }

    dso = load_system_driver("EGL", suffix, exact);
    if (dso) {
        initialize_api(dso, cnx, EGL);
        hnd = new driver_t(dso);

        dso = load_system_driver("GLESv1_CM", suffix, exact);
        initialize_api(dso, cnx, GLESv1_CM);
        hnd->set(dso, GLESv1_CM);

        dso = load_system_driver("GLESv2", suffix, exact);
        initialize_api(dso, cnx, GLESv2);
        hnd->set(dso, GLESv2);
        cnx->loadedDriverType = egl_connection_t::GLES_SYSTEM_STANDALONE_DRIVER;
    }
    return hnd;
}

bool Loader::load_glesv1_driver(egl_connection_t* cnx) {
    ATRACE_CALL();
    void* dso = nullptr;

    driver_t* hnd = (driver_t*)cnx->dso;
    // EGL driver must have been loaded. if not, something went wrong.
    if (!hnd || cnx->loadedDriverType == egl_connection_t::GLES_NO_DRIVER) {
        return false;
    }

    if (cnx->libGles1) return EGL_TRUE;

    // If there is a GLES driver, use that first
    switch (cnx->loadedDriverType) {
        case egl_connection_t::GLES_SYSTEM_COMBO_DRIVER:
        case egl_connection_t::GLES_UPDATED_COMBO_DRIVER: {
            dso = hnd->dso[0];
            initialize_api(dso, cnx, GLESv1_CM);
            break;
        }
        case egl_connection_t::GLES_ANGLE_STANDALONE_DRIVER: {
            android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace();
            dso = load_angle("GLESv1_CM", ns, cnx);
            if (dso) {
                initialize_api(dso, cnx, GLESv1_CM);
                hnd->set(dso, GLESv1_CM);
            }
            break;
        }
        case egl_connection_t::GLES_UPDATED_STANDALONE_DRIVER: {
            android_namespace_t* ns = android::GraphicsEnv::getInstance().getDriverNamespace();
            void* dso = load_updated_driver("GLESv1_CM", ns);
            if (dso) {
                initialize_api(dso, cnx, GLESv1_CM);
                hnd->set(dso, GLESv1_CM);
            }
            break;
        }
        case egl_connection_t::GLES_SYSTEM_STANDALONE_DRIVER: {
            dso = load_system_driver("GLESv1_CM",
                                     cnx->systemDriverUseProperty ? cnx->systemDriverProperty
                                                                  : nullptr,
                                     cnx->systemDriverUseExactName);
            if (dso) {
                initialize_api(dso, cnx, GLESv1_CM);
                hnd->set(dso, GLESv1_CM);
            }
            break;
        }
        default: {
            ALOGE("Bad loadedDriverType (%d)", cnx->loadedDriverType);
            break;
        }
    }

    if (!cnx->libGles1) {
        cnx->libGles1 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv1_CM.so");
    }

    LOG_ALWAYS_FATAL_IF(!cnx->libGles1, "couldn't load system OpenGL ES V1 wrapper libraries");

    return dso ? true : false;
}

void Loader::initialize_api(void* dso, egl_connection_t* cnx, uint32_t mask) {
    if (mask & EGL) {
        getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress");
+0 −2
Original line number Diff line number Diff line
@@ -53,8 +53,6 @@ public:
    void* open(egl_connection_t* cnx);
    void close(egl_connection_t* cnx);

    bool load_glesv1_driver(egl_connection_t* cnx);

private:
    Loader();
    driver_t* attempt_to_load_angle(egl_connection_t* cnx);
+0 −16
Original line number Diff line number Diff line
@@ -198,14 +198,6 @@ static EGLBoolean egl_init_drivers_locked() {
    return cnx->dso ? EGL_TRUE : EGL_FALSE;
}

static EGLBoolean egl_init_glesv1_drivers_locked() {
    // get our driver loader
    Loader& loader(Loader::getInstance());

    // dynamically load our GLESV1 implementation
    egl_connection_t* cnx = &gEGLImpl;
    return loader.load_glesv1_driver(cnx);
}

// this mutex protects driver load logic as a critical section since it accesses to global variable
// like gEGLImpl
@@ -219,14 +211,6 @@ EGLBoolean egl_init_drivers() {
    return res;
}

EGLBoolean egl_init_glesv1_drivers() {
    EGLBoolean res;
    pthread_mutex_lock(&sInitDriverMutex);
    res = egl_init_glesv1_drivers_locked();
    pthread_mutex_unlock(&sInitDriverMutex);
    return res;
}

static pthread_mutex_t sLogPrintMutex = PTHREAD_MUTEX_INITIALIZER;
static std::chrono::steady_clock::time_point sLogPrintTime;
static constexpr std::chrono::seconds DURATION(1);
+2 −2
Original line number Diff line number Diff line
@@ -220,7 +220,7 @@ EGLDisplay egl_display_t::getPlatformDisplay(EGLNativeDisplayType display,
    if (cnx->dso) {
        EGLDisplay dpy = EGL_NO_DISPLAY;

        if (cnx->loadedDriverType == egl_connection_t::GLES_ANGLE_STANDALONE_DRIVER) {
        if (cnx->useAngle) {
            EGLint error;
            dpy = getPlatformDisplayAngle(display, cnx, attrib_list, &error);
            if (error != EGL_NONE) {
@@ -464,7 +464,7 @@ EGLBoolean egl_display_t::terminate() {
        egl_connection_t* const cnx = &gEGLImpl;
        if (cnx->dso && disp.state == egl_display_t::INITIALIZED) {
            // If we're using ANGLE reset any custom DisplayPlatform
            if (cnx->loadedDriverType == egl_connection_t::GLES_ANGLE_STANDALONE_DRIVER) {
            if (cnx->useAngle) {
                angle::resetAnglePlatform(disp.dpy);
            }
            if (cnx->egl.eglTerminate(disp.dpy) == EGL_FALSE) {
+31 −31
Original line number Diff line number Diff line
@@ -277,7 +277,6 @@ static void(*findProcAddress(const char* name,

extern void setGLHooksThreadSpecific(gl_hooks_t const *value);
extern EGLBoolean egl_init_drivers();
extern EGLBoolean egl_init_glesv1_drivers();
extern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS];
extern gl_hooks_t gHooksTrace;

@@ -957,42 +956,43 @@ EGLContext eglCreateContextImpl(EGLDisplay dpy, EGLConfig config,
            egl_context_t* const c = get_context(share_list);
            share_list = c->context;
        }

        // figure out if it's a GLESv1 or GLESv2
        int gles_version_idx = egl_connection_t::GLESv1_INDEX;
        if (attrib_list) {
            const EGLint* ptr = attrib_list; // so that we don't modify attrib_list
            while (*ptr != EGL_NONE) {
                GLint attr = *ptr++;
                GLint value = *ptr++;
                if (attr == EGL_CONTEXT_CLIENT_VERSION) {
                    if (value == 1) {
                        gles_version_idx = egl_connection_t::GLESv1_INDEX;
                    } else if (value == 2 || value == 3) {
                        gles_version_idx = egl_connection_t::GLESv2_INDEX;
                    }
                } else if (attr == EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR &&
                           cnx->driverVersion < EGL_MAKE_VERSION(1, 5, 0)) {
        // b/111083885 - If we are presenting EGL 1.4 interface to apps
        // error out on robust access attributes that are invalid
        // in EGL 1.4 as the driver may be fine with them but dEQP expects
        // tests to fail according to spec.
        if (attrib_list && (cnx->driverVersion < EGL_MAKE_VERSION(1, 5, 0))) {
            const EGLint* attrib_ptr = attrib_list;
            while (*attrib_ptr != EGL_NONE) {
                GLint attr = *attrib_ptr++;
                GLint value = *attrib_ptr++;
                if (attr == EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR) {
                    // We are GL ES context with EGL 1.4, this is an invalid
                    // attribute
                    return setError(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
                }
            };
        }
        }

        // GLESV1 driver is lazily loaded and initialized
        if (gles_version_idx == egl_connection_t::GLESv1_INDEX) {
            android::GraphicsEnv::getInstance().setTargetStats(
                    android::GpuStatsInfo::Stats::GLES_1_IN_USE);
            if (!egl_init_glesv1_drivers()) return EGL_NO_CONTEXT;
        }

        EGLContext context = cnx->egl.eglCreateContext(
                dp->disp.dpy, config, share_list, attrib_list);
        if (context != EGL_NO_CONTEXT) {
            egl_context_t* c = new egl_context_t(dpy, context, config, cnx, gles_version_idx);
            // figure out if it's a GLESv1 or GLESv2
            int version = 0;
            if (attrib_list) {
                while (*attrib_list != EGL_NONE) {
                    GLint attr = *attrib_list++;
                    GLint value = *attrib_list++;
                    if (attr == EGL_CONTEXT_CLIENT_VERSION) {
                        if (value == 1) {
                            version = egl_connection_t::GLESv1_INDEX;
                            android::GraphicsEnv::getInstance().setTargetStats(
                                    android::GpuStatsInfo::Stats::GLES_1_IN_USE);
                        } else if (value == 2 || value == 3) {
                            version = egl_connection_t::GLESv2_INDEX;
                        }
                    }
                };
            }
            egl_context_t* c = new egl_context_t(dpy, context, config, cnx, version);
            return c;
        }
    }
Loading