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

Commit 9e7649d5 authored by Ian Elliott's avatar Ian Elliott Committed by Gerrit Code Review
Browse files

Merge changes from topic "UpstreamAngleSwitch"

* changes:
  Add 2 ANGLE deferlist settings
  Can switch to legacy GLES driver when ANGLE is system driver
parents 41690b16 ce7b086c
Loading
Loading
Loading
Loading
+145 −52
Original line number Diff line number Diff line
@@ -107,20 +107,42 @@ public class GraphicsEnvironment {
    private static final int UPDATABLE_DRIVER_GLOBAL_OPT_IN_PRERELEASE_DRIVER = 2;
    private static final int UPDATABLE_DRIVER_GLOBAL_OPT_IN_OFF = 3;

    // System properties related to ANGLE and legacy GLES graphics drivers.
    private static final String PROPERTY_EGL_SYSTEM_DRIVER = "ro.hardware.egl";
    // TODO (b/224558229): Properly add this to the list of system properties for a device:
    private static final String PROPERTY_EGL_LEGACY_DRIVER = "ro.hardware.egl_legacy";

    // Values for ANGLE_GL_DRIVER_ALL_ANGLE
    private static final int ANGLE_GL_DRIVER_ALL_ANGLE_ON = 1;
    private static final int ANGLE_GL_DRIVER_ALL_ANGLE_OFF = 0;
    private static final int ANGLE_GL_DRIVER_ALL_LEGACY = -1;

    // Values for ANGLE_GL_DRIVER_SELECTION_VALUES
    private static final String ANGLE_GL_DRIVER_CHOICE_DEFAULT = "default";
    private static final String ANGLE_GL_DRIVER_CHOICE_ANGLE = "angle";
    private static final String ANGLE_GL_DRIVER_CHOICE_LEGACY = "legacy";
    // The following value is a deprecated choice for "legacy"
    private static final String ANGLE_GL_DRIVER_CHOICE_NATIVE = "native";

    // Values returned by getDriverForPackage() and getDefaultDriverToUse() (avoid returning
    // strings for performance reasons)
    private static final int ANGLE_GL_DRIVER_TO_USE_LEGACY = 0;
    private static final int ANGLE_GL_DRIVER_TO_USE_ANGLE = 1;

    private ClassLoader mClassLoader;
    private String mLibrarySearchPaths;
    private String mLibraryPermittedPaths;
    private GameManager mGameManager;

    private boolean mAngleIsSystemDriver = false;
    private boolean mNoLegacyDriver = false;
    // When ANGLE is the system driver, this is the name of the legacy driver.
    //
    // IMPORTANT: When ANGLE is the system driver, and if there is a fallback "legacy" GLES driver
    // (e.g. from the GPU provider), the name of that driver must be set here, unles and until
    // PROPERTY_EGL_LEGACY_DRIVER has been properly plumbed and this becomes broadly available.
    private String mEglLegacyDriver = "";

    private int mAngleOptInIndex = -1;

    /**
@@ -138,6 +160,23 @@ public class GraphicsEnvironment {
        setupGpuLayers(context, coreSettings, pm, packageName, appInfoWithMetaData);
        Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);

        // Determine if ANGLE is the system driver, as this will determine other logic
        final String eglSystemDriver = SystemProperties.get(PROPERTY_EGL_SYSTEM_DRIVER);
        Log.v(TAG, "GLES system driver is '" + eglSystemDriver + "'");
        mAngleIsSystemDriver = eglSystemDriver.equals(ANGLE_DRIVER_NAME);
        if (mAngleIsSystemDriver) {
            // Lookup the legacy driver, to send down to the EGL loader
            final String eglLegacyDriver = SystemProperties.get(PROPERTY_EGL_LEGACY_DRIVER);
            if (eglLegacyDriver.isEmpty()) {
                mNoLegacyDriver = true;
                mEglLegacyDriver = eglSystemDriver;
            }
        } else {
            mEglLegacyDriver = eglSystemDriver;
        }
        Log.v(TAG, "Legacy GLES driver is '" + mEglLegacyDriver + "'");

        // Setup ANGLE and pass down ANGLE details to the C++ code
        Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "setupAngle");
        boolean useAngle = false;
        if (setupAngle(context, coreSettings, pm, packageName)) {
@@ -145,6 +184,9 @@ public class GraphicsEnvironment {
                useAngle = true;
                setGpuStats(ANGLE_DRIVER_NAME, ANGLE_DRIVER_VERSION_NAME, ANGLE_DRIVER_VERSION_CODE,
                        0, packageName, getVulkanVersion(pm));
            } else if (mNoLegacyDriver) {
                Log.e(TAG, "Unexpected problem with the ANGLE for use with: '" + packageName + "'");
                useAngle = true;
            }
        }
        Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
@@ -188,28 +230,15 @@ public class GraphicsEnvironment {
    /**
     * Query to determine if ANGLE should be used
     */
    private boolean shouldUseAngle(Context context, Bundle coreSettings,
            String packageName) {
    private boolean shouldUseAngle(Context context, Bundle coreSettings, String packageName) {
        if (TextUtils.isEmpty(packageName)) {
            Log.v(TAG, "No package name specified, ANGLE should not be used");
            return false;
        }

        final String devOptIn = getDriverForPackage(context, coreSettings, packageName);
        Log.v(TAG, "ANGLE Developer option for '" + packageName + "' "
                + "set to: '" + devOptIn + "'");

        // We only want to use ANGLE if the developer has explicitly chosen something other than
        // default driver.
        final boolean forceAngle = devOptIn.equals(ANGLE_GL_DRIVER_CHOICE_ANGLE);
        final boolean forceNative = devOptIn.equals(ANGLE_GL_DRIVER_CHOICE_NATIVE);
        if (forceAngle || forceNative) {
            Log.v(TAG, "ANGLE developer option for " + packageName + ": " + devOptIn);
            Log.v(TAG, "No package name specified; use the system driver");
            return mAngleIsSystemDriver ? true : false;
        }

        final boolean gameModeEnabledAngle = isAngleEnabledByGameMode(context, packageName);

        return !forceNative && (forceAngle || gameModeEnabledAngle);
        final int driverToUse = getDriverForPackage(context, coreSettings, packageName);
        boolean yesOrNo = driverToUse == ANGLE_GL_DRIVER_TO_USE_ANGLE;
        return yesOrNo;
    }

    private int getVulkanVersion(PackageManager pm) {
@@ -417,34 +446,69 @@ public class GraphicsEnvironment {
        return ai;
    }

    private String getDriverForPackage(Context context, Bundle bundle, String packageName) {
    /**
     * Return the appropriate "default" driver, unless overridden by isAngleEnabledByGameMode().
     */
    private int getDefaultDriverToUse(Context context, String packageName) {
        if (mAngleIsSystemDriver || isAngleEnabledByGameMode(context, packageName)) {
            return ANGLE_GL_DRIVER_TO_USE_ANGLE;
        } else {
            return ANGLE_GL_DRIVER_TO_USE_LEGACY;
        }
    }

    /*
     * Determine which GLES "driver" should be used for the package, taking into account the
     * following factors (in priority order):
     *
     * 1) The semi-global switch (i.e. Settings.Global.ANGLE_GL_DRIVER_ALL_ANGLE; which is set by
     *    the "angle_gl_driver_all_angle" setting; which forces a driver for all processes that
     *    start after the Java run time is up), if it forces a choice; otherwise ...
     * 2) The per-application switch (i.e. Settings.Global.ANGLE_GL_DRIVER_SELECTION_PKGS and
     *    Settings.Global.ANGLE_GL_DRIVER_SELECTION_VALUES; which corresponds to the
     *    “angle_gl_driver_selection_pkgs” and “angle_gl_driver_selection_values” settings); if it
     *    forces a choice; otherwise ...
     * 3) Use ANGLE if isAngleEnabledByGameMode() returns true; otherwise ...
     * 4) The global switch (i.e. use the system driver, whether ANGLE or legacy;
     *    a.k.a. mAngleIsSystemDriver, which is set by the device’s “ro.hardware.egl” property)
     *
     * Factors 1 and 2 are decided by this method.  Factors 3 and 4 are decided by
     * getDefaultDriverToUse().
     */
    private int getDriverForPackage(Context context, Bundle bundle, String packageName) {
        // Check the semi-global switch (i.e. once system has booted enough) for whether ANGLE
        // should be forced on or off for "all appplications"
        final int allUseAngle;
        if (bundle != null) {
            allUseAngle =
                    bundle.getInt(Settings.Global.ANGLE_GL_DRIVER_ALL_ANGLE);
            allUseAngle = bundle.getInt(Settings.Global.ANGLE_GL_DRIVER_ALL_ANGLE);
        } else {
            ContentResolver contentResolver = context.getContentResolver();
            allUseAngle = Settings.Global.getInt(contentResolver,
                    Settings.Global.ANGLE_GL_DRIVER_ALL_ANGLE,
                    ANGLE_GL_DRIVER_ALL_ANGLE_OFF);
                    Settings.Global.ANGLE_GL_DRIVER_ALL_ANGLE, ANGLE_GL_DRIVER_ALL_ANGLE_OFF);
        }
        if (allUseAngle == ANGLE_GL_DRIVER_ALL_ANGLE_ON) {
            Log.v(TAG, "Turn on ANGLE for all applications.");
            return ANGLE_GL_DRIVER_CHOICE_ANGLE;
            return ANGLE_GL_DRIVER_TO_USE_ANGLE;
        }
        if (allUseAngle == ANGLE_GL_DRIVER_ALL_LEGACY) {
            Log.v(TAG, "Disable ANGLE for all applications.");
            return ANGLE_GL_DRIVER_TO_USE_LEGACY;
        }

        // Make sure we have a good package name
        if (TextUtils.isEmpty(packageName)) {
            return ANGLE_GL_DRIVER_CHOICE_DEFAULT;
            return getDefaultDriverToUse(context, packageName);
        }

        // Get the per-application settings lists
        final ContentResolver contentResolver = context.getContentResolver();
        final List<String> optInPackages =
                getGlobalSettingsString(contentResolver, bundle,
                        Settings.Global.ANGLE_GL_DRIVER_SELECTION_PKGS);
        final List<String> optInValues =
                getGlobalSettingsString(contentResolver, bundle,
                        Settings.Global.ANGLE_GL_DRIVER_SELECTION_VALUES);
        final List<String> optInPackages = getGlobalSettingsString(
                contentResolver, bundle, Settings.Global.ANGLE_GL_DRIVER_SELECTION_PKGS);
        final List<String> optInValues = getGlobalSettingsString(
                contentResolver, bundle, Settings.Global.ANGLE_GL_DRIVER_SELECTION_VALUES);
        Log.v(TAG, "Currently set values for:");
        Log.v(TAG, "  angle_gl_driver_selection_pkgs = " + optInPackages);
        Log.v(TAG, "  angle_gl_driver_selection_values =" + optInValues);

        // Make sure we have good settings to use
        if (optInPackages.size() != optInValues.size()) {
@@ -454,17 +518,40 @@ public class GraphicsEnvironment {
                            + optInPackages.size() + ", "
                        + "number of values: "
                            + optInValues.size());
            return ANGLE_GL_DRIVER_CHOICE_DEFAULT;
            return getDefaultDriverToUse(context, packageName);
        }

        // See if this application is listed in the per-application settings lists
        final int pkgIndex = getPackageIndex(packageName, optInPackages);

        if (pkgIndex < 0) {
            return ANGLE_GL_DRIVER_CHOICE_DEFAULT;
            // The application is NOT listed in the per-application settings lists; and so use the
            // system driver (i.e. either ANGLE or the Legacy driver)
            Log.v(TAG, "getDriverForPackage(): No per-application setting");
            return getDefaultDriverToUse(context, packageName);
        }
        mAngleOptInIndex = pkgIndex;

        return optInValues.get(pkgIndex);
        Log.v(TAG,
                "getDriverForPackage(): using per-application switch: "
                        + optInValues.get(pkgIndex));
        // The application IS listed in the per-application settings lists; and so use the
        // setting--choosing the current system driver if the setting is "default" (i.e. either
        // ANGLE or the Legacy driver)
        String rtnValue = optInValues.get(pkgIndex);
        Log.v(TAG,
                "ANGLE Developer option for '" + packageName + "' "
                        + "set to: '" + rtnValue + "'");
        if (rtnValue.equals(ANGLE_GL_DRIVER_CHOICE_ANGLE)) {
            return ANGLE_GL_DRIVER_TO_USE_ANGLE;
        } else if (rtnValue.equals(ANGLE_GL_DRIVER_CHOICE_NATIVE)
                || rtnValue.equals(ANGLE_GL_DRIVER_CHOICE_LEGACY)) {
            return ANGLE_GL_DRIVER_TO_USE_LEGACY;
        } else {
            // The user either chose default or an invalid value; go with the default driver or what
            // the game dashboard indicates
            return getDefaultDriverToUse(context, packageName);
        }
    }

    /**
@@ -514,7 +601,13 @@ public class GraphicsEnvironment {
    }

    /**
     * Pass ANGLE details down to trigger enable logic
     * Determine whether ANGLE should be used, set it up if so, and pass ANGLE details down to
     * the C++ GraphicsEnv class.
     *
     * If ANGLE will be used, GraphicsEnv::setAngleInfo() will be called to enable ANGLE to be
     * properly used.  Otherwise, GraphicsEnv::setLegacyDriverInfo() will be called to
     * enable the legacy GLES driver (e.g. when ANGLE is the system driver) to be identified and
     * used.
     *
     * @param context
     * @param bundle
@@ -527,6 +620,7 @@ public class GraphicsEnvironment {
            String packageName) {

        if (!shouldUseAngle(context, bundle, packageName)) {
            setLegacyDriverInfo(packageName, mAngleIsSystemDriver, mEglLegacyDriver);
            return false;
        }

@@ -541,6 +635,7 @@ public class GraphicsEnvironment {
                angleInfo = pm.getApplicationInfo(anglePkgName, 0);
            } catch (PackageManager.NameNotFoundException e) {
                Log.w(TAG, "ANGLE debug package '" + anglePkgName + "' not installed");
                setLegacyDriverInfo(packageName, mAngleIsSystemDriver, mEglLegacyDriver);
                return false;
            }
        }
@@ -550,16 +645,18 @@ public class GraphicsEnvironment {
            anglePkgName = getAnglePackageName(pm);
            if (TextUtils.isEmpty(anglePkgName)) {
                Log.w(TAG, "Failed to find ANGLE package.");
                setLegacyDriverInfo(packageName, mAngleIsSystemDriver, mEglLegacyDriver);
                return false;
            }

            Log.i(TAG, "ANGLE package enabled: " + anglePkgName);
            Log.v(TAG, "ANGLE package enabled: " + anglePkgName);
            try {
                // Production ANGLE libraries must be pre-installed as a system app
                angleInfo = pm.getApplicationInfo(anglePkgName,
                        PackageManager.MATCH_SYSTEM_ONLY);
            } catch (PackageManager.NameNotFoundException e) {
                Log.w(TAG, "ANGLE package '" + anglePkgName + "' not installed");
                setLegacyDriverInfo(packageName, mAngleIsSystemDriver, mEglLegacyDriver);
                return false;
            }
        }
@@ -573,21 +670,15 @@ public class GraphicsEnvironment {
                + "!/lib/"
                + abi;

        if (DEBUG) Log.v(TAG, "ANGLE package libs: " + paths);
        if (DEBUG) {
            Log.v(TAG, "ANGLE package libs: " + paths);
        }

        // We need to call setAngleInfo() with the package name and the developer option value
        //(native/angle/other). Then later when we are actually trying to load a driver,
        //GraphicsEnv::getShouldUseAngle() has seen the package name before and can confidently
        //answer yes/no based on the previously set developer option value.
        final String devOptIn;
        // If we make it to here, ANGLE will be used.  Call setAngleInfo() with the package name,
        // and features to use.
        final String[] features = getAngleEglFeatures(context, bundle);
        final boolean gameModeEnabledAngle = isAngleEnabledByGameMode(context, packageName);
        if (gameModeEnabledAngle) {
            devOptIn = ANGLE_GL_DRIVER_CHOICE_ANGLE;
        } else {
            devOptIn = getDriverForPackage(context, bundle, packageName);
        }
        setAngleInfo(paths, packageName, devOptIn, features);
        setAngleInfo(
                paths, packageName, mAngleIsSystemDriver, ANGLE_GL_DRIVER_CHOICE_ANGLE, features);

        return true;
    }
@@ -876,8 +967,10 @@ public class GraphicsEnvironment {
    private static native void setDriverPathAndSphalLibraries(String path, String sphalLibraries);
    private static native void setGpuStats(String driverPackageName, String driverVersionName,
            long driverVersionCode, long driverBuildTime, String appPackageName, int vulkanVersion);
    private static native void setAngleInfo(String path, String appPackage, String devOptIn,
            String[] features);
    private static native void setAngleInfo(String path, String appPackage,
            boolean angleIsSystemDriver, String devOptIn, String[] features);
    private static native void setLegacyDriverInfo(
            String appPackage, boolean angleIsSystemDriver, String legacyDriverName);
    private static native boolean getShouldUseAngle(String packageName);
    private static native boolean setInjectLayersPrSetDumpable();

+12 −0
Original line number Diff line number Diff line
@@ -14409,6 +14409,18 @@ public final class Settings {
        @Readable
        public static final String ANGLE_EGL_FEATURES = "angle_egl_features";
        /**
         * Comma-separated list of package names that ANGLE may have issues with
         * @hide
         */
        public static final String ANGLE_DEFERLIST = "angle_deferlist";
        /**
         * Integer mode of the logic for applying `angle_deferlist`
         * @hide
         */
        public static final String ANGLE_DEFERLIST_MODE = "angle_deferlist_mode";
        /**
         * Show the "ANGLE In Use" dialog box to the user when ANGLE is the OpenGL driver.
         * The value is a boolean (1 or 0).
+16 −3
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@ void setGpuStats_native(JNIEnv* env, jobject clazz, jstring driverPackageName,
}

void setAngleInfo_native(JNIEnv* env, jobject clazz, jstring path, jstring appName,
                         jstring devOptIn, jobjectArray featuresObj) {
                         jboolean angleIsSystemDriver, jstring devOptIn, jobjectArray featuresObj) {
    ScopedUtfChars pathChars(env, path);
    ScopedUtfChars appNameChars(env, appName);
    ScopedUtfChars devOptInChars(env, devOptIn);
@@ -74,7 +74,18 @@ void setAngleInfo_native(JNIEnv* env, jobject clazz, jstring path, jstring appNa
    }

    android::GraphicsEnv::getInstance().setAngleInfo(pathChars.c_str(), appNameChars.c_str(),
                                                     devOptInChars.c_str(), features);
                                                     angleIsSystemDriver, devOptInChars.c_str(),
                                                     features);
}

void setLegacyDriverInfo_native(JNIEnv* env, jobject clazz, jstring appName,
                                jboolean angleIsSystemDriver, jstring legacyDriverName) {
    ScopedUtfChars appNameChars(env, appName);
    ScopedUtfChars legacyDriverNameChars(env, legacyDriverName);

    android::GraphicsEnv::getInstance().setLegacyDriverInfo(appNameChars.c_str(),
                                                            angleIsSystemDriver,
                                                            legacyDriverNameChars.c_str());
}

bool shouldUseAngle_native(JNIEnv* env, jobject clazz, jstring appName) {
@@ -120,8 +131,10 @@ const JNINativeMethod g_methods[] = {
        {"setInjectLayersPrSetDumpable", "()Z",
         reinterpret_cast<void*>(setInjectLayersPrSetDumpable_native)},
        {"setAngleInfo",
         "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V",
         "(Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;[Ljava/lang/String;)V",
         reinterpret_cast<void*>(setAngleInfo_native)},
        {"setLegacyDriverInfo", "(Ljava/lang/String;ZLjava/lang/String;)V",
         reinterpret_cast<void*>(setLegacyDriverInfo_native)},
        {"getShouldUseAngle", "(Ljava/lang/String;)Z",
         reinterpret_cast<void*>(shouldUseAngle_native)},
        {"setLayerPaths", "(Ljava/lang/ClassLoader;Ljava/lang/String;)V",
+4 −0
Original line number Diff line number Diff line
@@ -468,6 +468,10 @@ message GlobalSettingsProto {
        optional SettingProto updatable_driver_prerelease_opt_in_apps = 18;

        optional SettingProto angle_egl_features = 19;
        // ANGLE - List of Apps that ANGLE may have issues with
        optional SettingProto angle_deferlist = 20;
        // ANGLE - Integer mode of the logic for applying `angle_deferlist`
        optional SettingProto angle_deferlist_mode = 21;
    }
    optional Gpu gpu = 59;

+6 −0
Original line number Diff line number Diff line
@@ -770,6 +770,12 @@ class SettingsProtoDumpUtil {
        dumpSetting(s, p,
                Settings.Global.ANGLE_EGL_FEATURES,
                GlobalSettingsProto.Gpu.ANGLE_EGL_FEATURES);
        dumpSetting(s, p,
                Settings.Global.ANGLE_DEFERLIST,
                GlobalSettingsProto.Gpu.ANGLE_DEFERLIST);
        dumpSetting(s, p,
                Settings.Global.ANGLE_DEFERLIST_MODE,
                GlobalSettingsProto.Gpu.ANGLE_DEFERLIST_MODE);
        dumpSetting(s, p,
                Settings.Global.SHOW_ANGLE_IN_USE_DIALOG_BOX,
                GlobalSettingsProto.Gpu.SHOW_ANGLE_IN_USE_DIALOG);
Loading