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

Commit 5492618d authored by Peiyong Lin's avatar Peiyong Lin
Browse files

Clean up ANGLE integration logic.

Rename variables to clarify the meanings, remove unused methods.

Bug: b/283858001
Test: test with camera with dialog on
Test: atest CtsAngleIntegrationHostTestCases
Change-Id: I1db89b79879dec663f198fd3faad7501a3511698
parent 02deea60
Loading
Loading
Loading
Loading
+22 −52
Original line number Original line Diff line number Diff line
@@ -142,8 +142,8 @@ bool GraphicsEnv::isDebuggable() {
    return appDebuggable || platformDebuggable;
    return appDebuggable || platformDebuggable;
}
}


void GraphicsEnv::setDriverPathAndSphalLibraries(const std::string path,
void GraphicsEnv::setDriverPathAndSphalLibraries(const std::string& path,
                                                 const std::string sphalLibraries) {
                                                 const std::string& sphalLibraries) {
    if (!mDriverPath.empty() || !mSphalLibraries.empty()) {
    if (!mDriverPath.empty() || !mSphalLibraries.empty()) {
        ALOGV("ignoring attempt to change driver path from '%s' to '%s' or change sphal libraries "
        ALOGV("ignoring attempt to change driver path from '%s' to '%s' or change sphal libraries "
              "from '%s' to '%s'",
              "from '%s' to '%s'",
@@ -392,55 +392,24 @@ bool GraphicsEnv::setInjectLayersPrSetDumpable() {
    return true;
    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() {
bool GraphicsEnv::shouldUseAngle() {
    // Make sure we are init'ed
    // Make sure we are init'ed
    if (mAngleAppName.empty()) {
    if (mPackageName.empty()) {
        ALOGV("App name is empty. setAngleInfo() has not been called to enable ANGLE.");
        ALOGV("Package name is empty. setAngleInfo() has not been called to enable ANGLE.");
        return false;
        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_ANGLE = "angle";
    const char* ANGLE_PREFER_NATIVE = "native";
    const char* ANGLE_PREFER_NATIVE = "native";


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


void GraphicsEnv::setAngleInfo(const std::string path, const std::string appName,
void GraphicsEnv::setAngleInfo(const std::string& path, const std::string& packageName,
                               const std::string developerOptIn,
                               const std::string& developerOptIn,
                               const std::vector<std::string> eglFeatures) {
                               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.
        // 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(),
        ALOGV("Already evaluated the rules file for '%s': use ANGLE = %s", packageName.c_str(),
              (mUseAngle == YES) ? "true" : "false");
              (mShouldUseAngle == YES) ? "true" : "false");
        return;
        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());
    ALOGV("setting ANGLE path to '%s'", path.c_str());
    mAnglePath = path;
    mAnglePath = path;
    ALOGV("setting ANGLE app name to '%s'", appName.c_str());
    ALOGV("setting app package name to '%s'", packageName.c_str());
    mAngleAppName = appName;
    mPackageName = packageName;
    ALOGV("setting ANGLE application opt-in to '%s'", developerOptIn.c_str());
    ALOGV("setting ANGLE application opt-in to '%s'", developerOptIn.c_str());
    mAngleDeveloperOptIn = developerOptIn;
    mAngleDeveloperOptIn = developerOptIn;


    // Update the current status of whether we should use ANGLE or not
    // 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()) {
    if (mLayerPaths.empty()) {
        mLayerPaths = layerPaths;
        mLayerPaths = layerPaths;
        mAppNamespace = appNamespace;
        mAppNamespace = appNamespace;
@@ -485,8 +455,8 @@ NativeLoaderNamespace* GraphicsEnv::getAppNamespace() {
    return mAppNamespace;
    return mAppNamespace;
}
}


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


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


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


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


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

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


    /*
    /*
     * Apis for debug layer
     * Apis for debug layer
     */
     */
    // Set additional layer search paths.
    // 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.
    // Get the app namespace for loading layers.
    NativeLoaderNamespace* getAppNamespace();
    NativeLoaderNamespace* getAppNamespace();
    // Get additional layer search paths.
    // Get additional layer search paths.
    const std::string& getLayerPaths();
    const std::string& getLayerPaths();
    // Set the Vulkan debug layers.
    // Set the Vulkan debug layers.
    void setDebugLayers(const std::string layers);
    void setDebugLayers(const std::string& layers);
    // Set the GL debug layers.
    // Set the GL debug layers.
    void setDebugLayersGLES(const std::string layers);
    void setDebugLayersGLES(const std::string& layers);
    // Get the debug layers to load.
    // Get the debug layers to load.
    const std::string& getDebugLayers();
    const std::string& getDebugLayers();
    // Get the debug layers to load.
    // Get the debug layers to load.
    const std::string& getDebugLayersGLES();
    const std::string& getDebugLayersGLES();
    // Set the persist.graphics.egl system property value.
    void nativeToggleAngleAsSystemDriver(bool enabled);


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


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


    GraphicsEnv() = default;
    GraphicsEnv() = default;

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

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

    bool mActivityLaunched = false;
    /**
    // Information bookkept for GpuStats.
     * ANGLE variables.
    GpuStatsInfo mGpuStats;
     */
    // Path to ANGLE libs.
    // Path to ANGLE libs.
    std::string mAnglePath;
    std::string mAnglePath;
    // This App's name.
    // App's package name.
    std::string mAngleAppName;
    std::string mPackageName;
    // ANGLE developer opt in status.
    // ANGLE developer opt in status.
    std::string mAngleDeveloperOptIn;
    std::string mAngleDeveloperOptIn;
    // ANGLE EGL features;
    // ANGLE EGL features;
    std::vector<std::string> mAngleEglFeatures;
    std::vector<std::string> mAngleEglFeatures;
    // Use ANGLE flag.
    // 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.
    // Vulkan debug layers libs.
    std::string mDebugLayers;
    std::string mDebugLayers;
    // GL debug layers libs.
    // GL debug layers libs.
    std::string mDebugLayersGLES;
    std::string mDebugLayersGLES;
    // Additional debug layers search path.
    // Additional debug layers search path.
    std::string mLayerPaths;
    std::string mLayerPaths;
    // This mutex protects the namespace creation.
    // This App's namespace to open native libraries.
    std::mutex mNamespaceMutex;
    // Updatable driver namespace.
    android_namespace_t* mDriverNamespace = nullptr;
    // ANGLE namespace.
    android_namespace_t* mAngleNamespace = nullptr;
    // This App's namespace.
    NativeLoaderNamespace* mAppNamespace = nullptr;
    NativeLoaderNamespace* mAppNamespace = nullptr;
};
};


+14 −9
Original line number Original line Diff line number Diff line
@@ -147,13 +147,18 @@ static const char* HAL_SUBNAME_KEY_PROPERTIES[3] = {
        RO_BOARD_PLATFORM_PROPERTY,
        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) {
static bool should_unload_system_driver(egl_connection_t* cnx) {
    // Return false if the system driver has been unloaded once.
    // Return false if the system driver has been unloaded once.
    if (cnx->systemDriverUnloaded) {
    if (cnx->systemDriverUnloaded) {
        return false;
        return false;
    }
    }


    // Return true if Angle namespace is set.
    // Return true if ANGLE namespace is set.
    android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace();
    android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace();
    if (ns) {
    if (ns) {
        return true;
        return true;
@@ -279,10 +284,10 @@ void* Loader::open(egl_connection_t* cnx)
                                                            false, systemTime() - openTime);
                                                            false, systemTime() - openTime);
    } else {
    } else {
        // init_angle_backend will check if loaded driver is ANGLE or not,
        // 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),
        // Do this here so that we use ANGLE path when driver is ANGLE (e.g. loaded as native),
        // not just loading ANGLE as option.
        // 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,
    LOG_ALWAYS_FATAL_IF(!hnd,
@@ -324,7 +329,7 @@ void Loader::close(egl_connection_t* cnx)
    delete hnd;
    delete hnd;
    cnx->dso = nullptr;
    cnx->dso = nullptr;


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


void Loader::init_api(void* dso,
void Loader::init_api(void* dso,
@@ -565,14 +570,14 @@ Loader::driver_t* Loader::attempt_to_load_angle(egl_connection_t* cnx) {
    return hnd;
    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");
    void* pANGLEGetDisplayPlatform = dlsym(dso, "ANGLEGetDisplayPlatform");
    if (pANGLEGetDisplayPlatform) {
    if (pANGLEGetDisplayPlatform) {
        ALOGV("ANGLE GLES library in use");
        ALOGV("ANGLE GLES library loaded");
        cnx->useAngle = true;
        cnx->angleLoaded = true;
    } else {
    } else {
        ALOGV("Native GLES library in use");
        ALOGV("Native GLES library loaded");
        cnx->useAngle = false;
        cnx->angleLoaded = false;
    }
    }
}
}


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


        if (cnx->useAngle) {
        if (cnx->angleLoaded) {
            EGLint error;
            EGLint error;
            dpy = getPlatformDisplayAngle(display, cnx, attrib_list, &error);
            dpy = getPlatformDisplayAngle(display, cnx, attrib_list, &error);
            if (error != EGL_NONE) {
            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
        // 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).
        // 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)) {
            if (android::base::GetBoolProperty("service.sf.present_timestamp", false)) {
                mExtensionString.append("EGL_ANDROID_get_frame_timestamps ");
                mExtensionString.append("EGL_ANDROID_get_frame_timestamps ");
            }
            }
@@ -432,7 +432,7 @@ EGLBoolean egl_display_t::terminate() {
        egl_connection_t* const cnx = &gEGLImpl;
        egl_connection_t* const cnx = &gEGLImpl;
        if (cnx->dso && disp.state == egl_display_t::INITIALIZED) {
        if (cnx->dso && disp.state == egl_display_t::INITIALIZED) {
            // If we're using ANGLE reset any custom DisplayPlatform
            // If we're using ANGLE reset any custom DisplayPlatform
            if (cnx->useAngle) {
            if (cnx->angleLoaded) {
                angle::resetAnglePlatform(disp.dpy);
                angle::resetAnglePlatform(disp.dpy);
            }
            }
            if (cnx->egl.eglTerminate(disp.dpy) == EGL_FALSE) {
            if (cnx->egl.eglTerminate(disp.dpy) == EGL_FALSE) {
Loading