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

Commit 9a7a4797 authored by Cody Northrop's avatar Cody Northrop
Browse files

GraphicsEnvironment: Refactor setupAngle for system ANGLE

This CL updates the code to make it clear which ANGLE choice has
priority, and allows system ANGLE to be overriden multiple ways:

1. settings for ANGLE
2. persist properties for EGL
3. readonly properties for EGL

The selection is more complicated than we'd like, but hopefully
clearer now, and more functional.

Written in conjunction with yuxinhu@google.com.

Flag: android.os.query_angle_choice_flag
Test: make, flash, boot, use ANGLE settings
Bug: b/408439360
Change-Id: I0b736886ebea57dc7e2ff3bc55e28de85ea32d3b
parent 7eb97fee
Loading
Loading
Loading
Loading
+97 −21
Original line number Diff line number Diff line
@@ -548,12 +548,8 @@ public class GraphicsEnvironment {
    }

    /**
     * If ANGLE is not the system driver, determine whether ANGLE should be used, and if so, pass
     * Determine whether ANGLE should be used, and if so, pass
     * down the necessary details to the C++ GraphicsEnv class via GraphicsEnv::setAngleInfo().
     * <p>
     * If ANGLE is the system driver or the various flags indicate it should be used, attempt to
     * set up ANGLE from the APK first, so the updatable libraries are used. If APK setup fails,
     * attempt to set up the system ANGLE. Return false if both fail.
     *
     * @param context - Context of the application.
     * @param bundle - Bundle of the application.
@@ -564,6 +560,78 @@ public class GraphicsEnvironment {
     */
    private boolean setupAngle(Context context, Bundle bundle, PackageManager packageManager,
            String packageName) {

        // There are three values involved in deciding whether to load ANGLE.
        // In order of precedence:
        //
        // 1. Settings choice for ANGLE
        // 2. Persist choice for EGL (persist.graphics.egl)
        // 3. Readonly choice for EGL (ro.hardware.egl)
        //
        // One complication here is, the persist choice is *only* respected when DEFAULT is chosen.
        //
        // Settings choice can be three values:
        //
        //   ANGLE_GL_DRIVER_CHOICE_ANGLE
        //   ANGLE_GL_DRIVER_CHOICE_NATIVE
        //   ANGLE_GL_DRIVER_CHOICE_DEFAULT
        //
        // If it is ANGLE
        //   - We don't care what the other choices are, we want to use ANGLE
        // If it is NATIVE
        //   - We don't care about the persist choice
        //   - We need to check readonly choice
        // If it is DEFAULT
        //   - We need to check the persist choice (if it exists)
        //   - We need to check the readonly choice
        //
        // Finally, only call nativeSetAngleInfo if readonly choice is used, and it is *not* ANGLE
        //  - This is to match expectations in Loader::open

        // Perform a number of checks to decide if we should set up ANGLE
        boolean setupANGLE = false;

        if (android.os.Flags.queryAngleChoiceFlag()) {
            // Check settings choice first, as the highest priority
            final String settingsChoice = queryAngleChoice(context, bundle, packageName);

            if (settingsChoice.equals(ANGLE_GL_DRIVER_CHOICE_ANGLE)) {
                 // If choice was ANGLE, we explicitly want to set it up
                setupANGLE = true;

            } else if (settingsChoice.equals(ANGLE_GL_DRIVER_CHOICE_NATIVE)) {
                // If choice was NATIVE, we only check the readonly value
                setupANGLE = SystemProperties.get(PROPERTY_RO_HARDWARE_EGL)
                                    .equals(ANGLE_DRIVER_NAME);
                if (!setupANGLE) {
                    // We are using readonly choice and it is not ANGLE, inform the loader
                    nativeSetAngleInfo("", true, packageName, null);
                }

            } else if (settingsChoice.equals(ANGLE_GL_DRIVER_CHOICE_DEFAULT)) {
                // If choice was DEFAULT, we need to check persist, then readonly
                final String persistChoice  = nativeGetPersistGraphicsEgl();
                if (persistChoice != null) {
                    // We have a persist choice, check it for ANGLE
                    setupANGLE = persistChoice.equals(ANGLE_DRIVER_NAME);
                } else {
                    // No persist choice, so check readonly
                    setupANGLE = SystemProperties.get(PROPERTY_RO_HARDWARE_EGL)
                                        .equals(ANGLE_DRIVER_NAME);
                    if (!setupANGLE) {
                        // We are using readonly choice and it is not ANGLE, inform the loader
                        nativeSetAngleInfo("", true, packageName, null);
                    }
                }

            } else {
                Log.v(TAG, "Unrecognized ANGLE choice: " + settingsChoice);
                return false;
            }

        } else {
            // Original code
            // TODO: Remove the else chunk when the flag is enabled
            final String eglDriverName = SystemProperties.get(PROPERTY_RO_HARDWARE_EGL);

            // The ANGLE choice only makes sense if ANGLE is not the system driver.
@@ -578,16 +646,23 @@ public class GraphicsEnvironment {
                }
            }

            setupANGLE = true;
        }

        if (setupANGLE) {
            // If we reach here, it means either:
            // 1. system driver is not ANGLE, but ANGLE is requested.
        // 2. system driver is ANGLE.
            // 2. system driver is ANGLE, and no other driver is requested.
            // In both cases, setup ANGLE info. We attempt to setup the APK first, so
        // updated/development libraries are used if the APK is present, falling back to the system
        // libraries otherwise.
            // updated/development libraries are used if the APK is present, falling back to the
            // system libraries otherwise.
            return setupAngleFromApk(context, bundle, packageManager, packageName)
                    || setupAngleFromSystem(context, bundle, packageName);
        }

        return false;
    }

    /**
     * Attempt to set up ANGLE from the packaged apk, if the apk can be found, pass ANGLE details to
     * the C++ GraphicsEnv class.
@@ -960,6 +1035,7 @@ public class GraphicsEnvironment {
            String packageName, String[] features);
    private static native boolean setInjectLayersPrSetDumpable();
    private static native void nativeToggleAngleAsSystemDriver(boolean enabled);
    private static native String nativeGetPersistGraphicsEgl();

    /**
     * Hint for GraphicsEnvironment that an activity is launching on the process.
+7 −0
Original line number Diff line number Diff line
@@ -349,6 +349,13 @@ flag {
    bug: "345802719"
}

flag {
    name: "query_angle_choice_flag"
    namespace: "gpu"
    description: "Unconditionally querying ANGLE choice to fix a driver load malfunction"
    bug: "408439360"
}

flag {
    name: "remove_app_profiler_pss_collection"
    is_exported: true
+13 −0
Original line number Diff line number Diff line
@@ -110,6 +110,17 @@ void nativeToggleAngleAsSystemDriver_native(JNIEnv* env, jobject clazz, jboolean
    android::GraphicsEnv::getInstance().nativeToggleAngleAsSystemDriver(enabled);
}

jstring nativeGetPersistGraphicsEgl_native(JNIEnv* env, jobject clazz) {
    std::string persistGraphicsEGLValue =
            android::GraphicsEnv::getInstance().nativeGetPersistGraphicsEgl();
    jstring result = nullptr;
    if (persistGraphicsEGLValue.empty()) {
        return nullptr;
    }
    result = env->NewStringUTF(persistGraphicsEGLValue.c_str());
    return result;
}

const JNINativeMethod g_methods[] = {
        {"isDebuggable", "()Z", reinterpret_cast<void*>(isDebuggable_native)},
        {"setDriverPathAndSphalLibraries", "(Ljava/lang/String;Ljava/lang/String;)V",
@@ -128,6 +139,8 @@ const JNINativeMethod g_methods[] = {
        {"hintActivityLaunch", "()V", reinterpret_cast<void*>(hintActivityLaunch_native)},
        {"nativeToggleAngleAsSystemDriver", "(Z)V",
         reinterpret_cast<void*>(nativeToggleAngleAsSystemDriver_native)},
        {"nativeGetPersistGraphicsEgl", "()Ljava/lang/String;",
         reinterpret_cast<void*>(nativeGetPersistGraphicsEgl_native)},
};

const char* const kGraphicsEnvironmentName = "android/os/GraphicsEnvironment";