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

Commit e881745b authored by Peiyong Lin's avatar Peiyong Lin Committed by Automerger Merge Worker
Browse files

Merge "Clean up ANGLE integration logic." into udc-qpr-dev am: 7f4c6322 am: a71f6607

parents 8d3170ac a71f6607
Loading
Loading
Loading
Loading
+22 −52
Original line number Diff line number Diff line
@@ -142,8 +142,8 @@ bool GraphicsEnv::isDebuggable() {
    return appDebuggable || platformDebuggable;
}

void GraphicsEnv::setDriverPathAndSphalLibraries(const std::string path,
                                                 const std::string sphalLibraries) {
void GraphicsEnv::setDriverPathAndSphalLibraries(const std::string& path,
                                                 const std::string& sphalLibraries) {
    if (!mDriverPath.empty() || !mSphalLibraries.empty()) {
        ALOGV("ignoring attempt to change driver path from '%s' to '%s' or change sphal libraries "
              "from '%s' to '%s'",
@@ -392,55 +392,24 @@ bool GraphicsEnv::setInjectLayersPrSetDumpable() {
    return true;
}

void* GraphicsEnv::loadLibrary(std::string name) {
    const android_dlextinfo dlextinfo = {
            .flags = ANDROID_DLEXT_USE_NAMESPACE,
            .library_namespace = getAngleNamespace(),
    };

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

    void* so = android_dlopen_ext(libName.c_str(), RTLD_LOCAL | RTLD_NOW, &dlextinfo);

    if (so) {
        ALOGD("dlopen_ext from APK (%s) success at %p", libName.c_str(), so);
        return so;
    } else {
        ALOGE("dlopen_ext(\"%s\") failed: %s", libName.c_str(), dlerror());
    }

    return nullptr;
}

bool GraphicsEnv::shouldUseAngle(std::string appName) {
    if (appName != mAngleAppName) {
        // Make sure we are checking the app we were init'ed for
        ALOGE("App name does not match: expected '%s', got '%s'", mAngleAppName.c_str(),
              appName.c_str());
        return false;
    }

    return shouldUseAngle();
}

bool GraphicsEnv::shouldUseAngle() {
    // Make sure we are init'ed
    if (mAngleAppName.empty()) {
        ALOGV("App name is empty. setAngleInfo() has not been called to enable ANGLE.");
    if (mPackageName.empty()) {
        ALOGV("Package name is empty. setAngleInfo() has not been called to enable ANGLE.");
        return false;
    }

    return (mUseAngle == YES) ? true : false;
    return (mShouldUseAngle == YES) ? true : false;
}

void GraphicsEnv::updateUseAngle() {
void GraphicsEnv::updateShouldUseAngle() {
    const char* ANGLE_PREFER_ANGLE = "angle";
    const char* ANGLE_PREFER_NATIVE = "native";

    mUseAngle = NO;
    mShouldUseAngle = NO;
    if (mAngleDeveloperOptIn == ANGLE_PREFER_ANGLE) {
        ALOGV("User set \"Developer Options\" to force the use of ANGLE");
        mUseAngle = YES;
        mShouldUseAngle = YES;
    } else if (mAngleDeveloperOptIn == ANGLE_PREFER_NATIVE) {
        ALOGV("User set \"Developer Options\" to force the use of Native");
    } else {
@@ -448,13 +417,13 @@ void GraphicsEnv::updateUseAngle() {
    }
}

void GraphicsEnv::setAngleInfo(const std::string path, const std::string appName,
                               const std::string developerOptIn,
void GraphicsEnv::setAngleInfo(const std::string& path, const std::string& packageName,
                               const std::string& developerOptIn,
                               const std::vector<std::string> eglFeatures) {
    if (mUseAngle != UNKNOWN) {
    if (mShouldUseAngle != UNKNOWN) {
        // We've already figured out an answer for this app, so just return.
        ALOGV("Already evaluated the rules file for '%s': use ANGLE = %s", appName.c_str(),
              (mUseAngle == YES) ? "true" : "false");
        ALOGV("Already evaluated the rules file for '%s': use ANGLE = %s", packageName.c_str(),
              (mShouldUseAngle == YES) ? "true" : "false");
        return;
    }

@@ -462,16 +431,17 @@ void GraphicsEnv::setAngleInfo(const std::string path, const std::string appName

    ALOGV("setting ANGLE path to '%s'", path.c_str());
    mAnglePath = path;
    ALOGV("setting ANGLE app name to '%s'", appName.c_str());
    mAngleAppName = appName;
    ALOGV("setting app package name to '%s'", packageName.c_str());
    mPackageName = packageName;
    ALOGV("setting ANGLE application opt-in to '%s'", developerOptIn.c_str());
    mAngleDeveloperOptIn = developerOptIn;

    // Update the current status of whether we should use ANGLE or not
    updateUseAngle();
    updateShouldUseAngle();
}

void GraphicsEnv::setLayerPaths(NativeLoaderNamespace* appNamespace, const std::string layerPaths) {
void GraphicsEnv::setLayerPaths(NativeLoaderNamespace* appNamespace,
                                const std::string& layerPaths) {
    if (mLayerPaths.empty()) {
        mLayerPaths = layerPaths;
        mAppNamespace = appNamespace;
@@ -485,8 +455,8 @@ NativeLoaderNamespace* GraphicsEnv::getAppNamespace() {
    return mAppNamespace;
}

std::string& GraphicsEnv::getAngleAppName() {
    return mAngleAppName;
std::string& GraphicsEnv::getPackageName() {
    return mPackageName;
}

const std::vector<std::string>& GraphicsEnv::getAngleEglFeatures() {
@@ -505,11 +475,11 @@ const std::string& GraphicsEnv::getDebugLayersGLES() {
    return mDebugLayersGLES;
}

void GraphicsEnv::setDebugLayers(const std::string layers) {
void GraphicsEnv::setDebugLayers(const std::string& layers) {
    mDebugLayers = layers;
}

void GraphicsEnv::setDebugLayersGLES(const std::string layers) {
void GraphicsEnv::setDebugLayersGLES(const std::string& layers) {
    mDebugLayersGLES = layers;
}

+44 −32
Original line number Diff line number Diff line
@@ -55,7 +55,7 @@ public:
    // Also set additional required sphal libraries to the linker for loading
    // graphics drivers. The string is a list of libraries separated by ':',
    // which is required by android_link_namespaces.
    void setDriverPathAndSphalLibraries(const std::string path, const std::string sphalLibraries);
    void setDriverPathAndSphalLibraries(const std::string& path, const std::string& sphalLibraries);
    // Get the updatable driver namespace.
    android_namespace_t* getDriverNamespace();
    std::string getDriverPath() const;
@@ -96,8 +96,6 @@ public:
    /*
     * Apis for ANGLE
     */
    // Check if the requested app should use ANGLE.
    bool shouldUseAngle(std::string appName);
    // Check if this app process should use ANGLE.
    bool shouldUseAngle();
    // Set a search path for loading ANGLE libraries. The path is a list of
@@ -105,42 +103,39 @@ public:
    // (libraries must be stored uncompressed and page aligned); such elements
    // in the search path must have a '!' after the zip filename, e.g.
    //     /system/app/ANGLEPrebuilt/ANGLEPrebuilt.apk!/lib/arm64-v8a
    void setAngleInfo(const std::string path, const std::string appName, std::string devOptIn,
                      const std::vector<std::string> eglFeatures);
    void setAngleInfo(const std::string& path, const std::string& packageName,
                      const std::string& devOptIn, const std::vector<std::string> eglFeatures);
    // Get the ANGLE driver namespace.
    android_namespace_t* getAngleNamespace();
    // Get the app name for ANGLE debug message.
    std::string& getAngleAppName();

    // Get the app package name.
    std::string& getPackageName();
    const std::vector<std::string>& getAngleEglFeatures();
    // Set the persist.graphics.egl system property value.
    void nativeToggleAngleAsSystemDriver(bool enabled);

    /*
     * Apis for debug layer
     */
    // Set additional layer search paths.
    void setLayerPaths(NativeLoaderNamespace* appNamespace, const std::string layerPaths);
    void setLayerPaths(NativeLoaderNamespace* appNamespace, const std::string& layerPaths);
    // Get the app namespace for loading layers.
    NativeLoaderNamespace* getAppNamespace();
    // Get additional layer search paths.
    const std::string& getLayerPaths();
    // Set the Vulkan debug layers.
    void setDebugLayers(const std::string layers);
    void setDebugLayers(const std::string& layers);
    // Set the GL debug layers.
    void setDebugLayersGLES(const std::string layers);
    void setDebugLayersGLES(const std::string& layers);
    // Get the debug layers to load.
    const std::string& getDebugLayers();
    // Get the debug layers to load.
    const std::string& getDebugLayersGLES();
    // Set the persist.graphics.egl system property value.
    void nativeToggleAngleAsSystemDriver(bool enabled);

private:
    enum UseAngle { UNKNOWN, YES, NO };

    // Load requested ANGLE library.
    void* loadLibrary(std::string name);
    // Update whether ANGLE should be used.
    void updateUseAngle();
    void updateShouldUseAngle();
    // Link updatable driver namespace with llndk and vndk-sp libs.
    bool linkDriverNamespaceLocked(android_namespace_t* vndkNamespace);
    // Check whether this process is ready to send stats.
@@ -149,39 +144,56 @@ private:
    void sendGpuStatsLocked(GpuStatsInfo::Api api, bool isDriverLoaded, int64_t driverLoadingTime);

    GraphicsEnv() = default;

    // This mutex protects the namespace creation.
    std::mutex mNamespaceMutex;

    /**
     * Updatable driver variables.
     */
    // Path to updatable driver libs.
    std::string mDriverPath;
    // Path to additional sphal libs linked to updatable driver namespace.
    std::string mSphalLibraries;
    // This mutex protects mGpuStats and get gpuservice call.
    std::mutex mStatsLock;
    // Cache the activity launch info
    bool mActivityLaunched = false;
    // Information bookkept for GpuStats.
    GpuStatsInfo mGpuStats;
    // Updatable driver namespace.
    android_namespace_t* mDriverNamespace = nullptr;

    /**
     * ANGLE variables.
     */
    // Path to ANGLE libs.
    std::string mAnglePath;
    // This App's name.
    std::string mAngleAppName;
    // App's package name.
    std::string mPackageName;
    // ANGLE developer opt in status.
    std::string mAngleDeveloperOptIn;
    // ANGLE EGL features;
    std::vector<std::string> mAngleEglFeatures;
    // Use ANGLE flag.
    UseAngle mUseAngle = UNKNOWN;
    UseAngle mShouldUseAngle = UNKNOWN;
    // ANGLE namespace.
    android_namespace_t* mAngleNamespace = nullptr;

    /**
     * GPU metrics.
     */
    // This mutex protects mGpuStats and get gpuservice call.
    std::mutex mStatsLock;
    // Cache the activity launch info
    bool mActivityLaunched = false;
    // Information bookkept for GpuStats.
    GpuStatsInfo mGpuStats;

    /**
     * Debug layers.
     */
    // Vulkan debug layers libs.
    std::string mDebugLayers;
    // GL debug layers libs.
    std::string mDebugLayersGLES;
    // Additional debug layers search path.
    std::string mLayerPaths;
    // This mutex protects the namespace creation.
    std::mutex mNamespaceMutex;
    // Updatable driver namespace.
    android_namespace_t* mDriverNamespace = nullptr;
    // ANGLE namespace.
    android_namespace_t* mAngleNamespace = nullptr;
    // This App's namespace.
    // This App's namespace to open native libraries.
    NativeLoaderNamespace* mAppNamespace = nullptr;
};

+14 −9
Original line number Diff line number Diff line
@@ -147,13 +147,18 @@ static const char* HAL_SUBNAME_KEY_PROPERTIES[3] = {
        RO_BOARD_PLATFORM_PROPERTY,
};

// Check whether the loaded system drivers should be unloaded in order to
// load ANGLE or the updatable graphics drivers.
// If ANGLE namespace is set, it means the application is identified to run on top of ANGLE.
// If updatable graphics driver namespace is set, it means the application is identified to
// run on top of updatable graphics drivers.
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.
    // Return true if ANGLE namespace is set.
    android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace();
    if (ns) {
        return true;
@@ -279,10 +284,10 @@ void* Loader::open(egl_connection_t* cnx)
                                                            false, systemTime() - openTime);
    } else {
        // init_angle_backend will check if loaded driver is ANGLE or not,
        // will set cnx->useAngle appropriately.
        // will set cnx->angleLoaded appropriately.
        // Do this here so that we use ANGLE path when driver is ANGLE (e.g. loaded as native),
        // not just loading ANGLE as option.
        init_angle_backend(hnd->dso[2], cnx);
        attempt_to_init_angle_backend(hnd->dso[2], cnx);
    }

    LOG_ALWAYS_FATAL_IF(!hnd,
@@ -324,7 +329,7 @@ void Loader::close(egl_connection_t* cnx)
    delete hnd;
    cnx->dso = nullptr;

    cnx->useAngle = false;
    cnx->angleLoaded = false;
}

void Loader::init_api(void* dso,
@@ -565,14 +570,14 @@ Loader::driver_t* Loader::attempt_to_load_angle(egl_connection_t* cnx) {
    return hnd;
}

void Loader::init_angle_backend(void* dso, egl_connection_t* cnx) {
void Loader::attempt_to_init_angle_backend(void* dso, egl_connection_t* cnx) {
    void* pANGLEGetDisplayPlatform = dlsym(dso, "ANGLEGetDisplayPlatform");
    if (pANGLEGetDisplayPlatform) {
        ALOGV("ANGLE GLES library in use");
        cnx->useAngle = true;
        ALOGV("ANGLE GLES library loaded");
        cnx->angleLoaded = true;
    } else {
        ALOGV("Native GLES library in use");
        cnx->useAngle = false;
        ALOGV("Native GLES library loaded");
        cnx->angleLoaded = false;
    }
}

+1 −1
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ private:
    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 init_angle_backend(void* dso, egl_connection_t* cnx);
    void attempt_to_init_angle_backend(void* dso, egl_connection_t* cnx);

    static __attribute__((noinline)) void init_api(void* dso, const char* const* api,
                                                   const char* const* ref_api,
+3 −3
Original line number Diff line number Diff line
@@ -191,7 +191,7 @@ EGLDisplay egl_display_t::getPlatformDisplay(EGLNativeDisplayType display,
    if (cnx->dso) {
        EGLDisplay dpy = EGL_NO_DISPLAY;

        if (cnx->useAngle) {
        if (cnx->angleLoaded) {
            EGLint error;
            dpy = getPlatformDisplayAngle(display, cnx, attrib_list, &error);
            if (error != EGL_NONE) {
@@ -324,7 +324,7 @@ EGLBoolean egl_display_t::initialize(EGLint* major, EGLint* minor) {

        // b/269060366 Conditionally enabled EGL_ANDROID_get_frame_timestamps extension if the
        // device's present timestamps are reliable (which may not be the case on emulators).
        if (cnx->useAngle) {
        if (cnx->angleLoaded) {
            if (android::base::GetBoolProperty("service.sf.present_timestamp", false)) {
                mExtensionString.append("EGL_ANDROID_get_frame_timestamps ");
            }
@@ -432,7 +432,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->useAngle) {
            if (cnx->angleLoaded) {
                angle::resetAnglePlatform(disp.dpy);
            }
            if (cnx->egl.eglTerminate(disp.dpy) == EGL_FALSE) {
Loading