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

Commit f4162593 authored by Cody Northrop's avatar Cody Northrop
Browse files

Rootless GPU Debug for GLES

This commit adds the ability to enable debug layers for OpenGL ES.

Similar to Rootless Debug for Vulkan, layers can be loaded from the
APK or base directory of selected debuggable applications.

Layers will only be loaded when developers opt-in via settings for a
target application.

A separate application can now be specified as an additional location
for layer discovery.

Example usage:

  adb shell settings put global enable_gpu_debug_layers 1
  adb shell settings put global gpu_debug_app <target_app>
  adb shell settings put global gpu_debug_layers layer1.so:layer2.so
  adb shell settings put global gpu_debug_layer_app <layer_app>

Test: cts-tradefed run singleCommand cts -m CtsGpuToolsHostTestCases
Bug: 110883880
Change-Id: I16df1951be0c06c80a445991e3e6d1636222b17b
parent c4cfbf48
Loading
Loading
Loading
Loading
+52 −10
Original line number Original line Diff line number Diff line
@@ -55,7 +55,7 @@ public class GraphicsEnvironment {
     * Set up GraphicsEnvironment
     * Set up GraphicsEnvironment
     */
     */
    public void setup(Context context, Bundle coreSettings) {
    public void setup(Context context, Bundle coreSettings) {
        setupGpuLayers(context);
        setupGpuLayers(context, coreSettings);
        setupAngle(context, coreSettings);
        setupAngle(context, coreSettings);
        chooseDriver(context);
        chooseDriver(context);
    }
    }
@@ -80,28 +80,55 @@ public class GraphicsEnvironment {
        mDebugLayerPath = debugLayerPath;
        mDebugLayerPath = debugLayerPath;
    }
    }


    /**
     * Return the debug layer app's on-disk and in-APK lib directories
     */
    private static String getDebugLayerAppPaths(Context context, String app) {
        ApplicationInfo appInfo;
        try {
            appInfo = context.getPackageManager().getApplicationInfo(
                    app, PackageManager.MATCH_ALL);
        } catch (PackageManager.NameNotFoundException e) {
            Log.w(TAG, "Debug layer app '" + app + "' not installed");

            return null;
        }

        String abi = chooseAbi(appInfo);

        StringBuilder sb = new StringBuilder();
        sb.append(appInfo.nativeLibraryDir)
            .append(File.pathSeparator);
        sb.append(appInfo.sourceDir)
            .append("!/lib/")
            .append(abi);
        String paths = sb.toString();

        if (DEBUG) Log.v(TAG, "Debug layer app libs: " + paths);

        return paths;
    }

    /**
    /**
     * Set up layer search paths for all apps
     * Set up layer search paths for all apps
     * If debuggable, check for additional debug settings
     * If debuggable, check for additional debug settings
     */
     */
    private void setupGpuLayers(Context context) {
    private void setupGpuLayers(Context context, Bundle coreSettings) {


        String layerPaths = "";
        String layerPaths = "";


        // Only enable additional debug functionality if the following conditions are met:
        // Only enable additional debug functionality if the following conditions are met:
        // 1. App is debuggable
        // 1. App is debuggable or device is rooted
        // 2. ENABLE_GPU_DEBUG_LAYERS is true
        // 2. ENABLE_GPU_DEBUG_LAYERS is true
        // 3. Package name is equal to GPU_DEBUG_APP
        // 3. Package name is equal to GPU_DEBUG_APP


        if (isDebuggable(context)) {
        if (isDebuggable(context) || (getCanLoadSystemLibraries() == 1)) {


            int enable = Settings.Global.getInt(context.getContentResolver(),
            int enable = coreSettings.getInt(Settings.Global.ENABLE_GPU_DEBUG_LAYERS, 0);
                                                Settings.Global.ENABLE_GPU_DEBUG_LAYERS, 0);


            if (enable != 0) {
            if (enable != 0) {


                String gpuDebugApp = Settings.Global.getString(context.getContentResolver(),
                String gpuDebugApp = coreSettings.getString(Settings.Global.GPU_DEBUG_APP);
                                                               Settings.Global.GPU_DEBUG_APP);


                String packageName = context.getPackageName();
                String packageName = context.getPackageName();


@@ -115,8 +142,22 @@ public class GraphicsEnvironment {
                    // the layers specified by the app.
                    // the layers specified by the app.
                    layerPaths = mDebugLayerPath + ":";
                    layerPaths = mDebugLayerPath + ":";


                    String layers = Settings.Global.getString(context.getContentResolver(),

                                                              Settings.Global.GPU_DEBUG_LAYERS);
                    // If there is a debug layer app specified, add its path.
                    String gpuDebugLayerApp =
                            coreSettings.getString(Settings.Global.GPU_DEBUG_LAYER_APP);

                    if (gpuDebugLayerApp != null && !gpuDebugLayerApp.isEmpty()) {
                        Log.i(TAG, "GPU debug layer app: " + gpuDebugLayerApp);
                        String paths = getDebugLayerAppPaths(context, gpuDebugLayerApp);
                        if (paths != null) {
                            // Append the path so files placed in the app's base directory will
                            // override the external path
                            layerPaths += paths + ":";
                        }
                    }

                    String layers = coreSettings.getString(Settings.Global.GPU_DEBUG_LAYERS);


                    Log.i(TAG, "Debug layer list: " + layers);
                    Log.i(TAG, "Debug layer list: " + layers);
                    if (layers != null && !layers.isEmpty()) {
                    if (layers != null && !layers.isEmpty()) {
@@ -290,6 +331,7 @@ public class GraphicsEnvironment {
        return null;
        return null;
    }
    }


    private static native int getCanLoadSystemLibraries();
    private static native void setLayerPaths(ClassLoader classLoader, String layerPaths);
    private static native void setLayerPaths(ClassLoader classLoader, String layerPaths);
    private static native void setDebugLayers(String layers);
    private static native void setDebugLayers(String layers);
    private static native void setDriverPath(String path);
    private static native void setDriverPath(String path);
+6 −0
Original line number Original line Diff line number Diff line
@@ -11630,6 +11630,12 @@ public final class Settings {
         */
         */
        public static final String GPU_DEBUG_LAYERS = "gpu_debug_layers";
        public static final String GPU_DEBUG_LAYERS = "gpu_debug_layers";
        /**
         * Addition app for GPU layer discovery
         * @hide
         */
        public static final String GPU_DEBUG_LAYER_APP = "gpu_debug_layer_app";
        /**
        /**
         * Control whether the process CPU usage meter should be shown.
         * Control whether the process CPU usage meter should be shown.
         *
         *
+5 −0
Original line number Original line Diff line number Diff line
@@ -23,6 +23,10 @@


namespace {
namespace {


int getCanLoadSystemLibraries_native() {
    return android::GraphicsEnv::getInstance().getCanLoadSystemLibraries();
}

void setDriverPath(JNIEnv* env, jobject clazz, jstring path) {
void setDriverPath(JNIEnv* env, jobject clazz, jstring path) {
    ScopedUtfChars pathChars(env, path);
    ScopedUtfChars pathChars(env, path);
    android::GraphicsEnv::getInstance().setDriverPath(pathChars.c_str());
    android::GraphicsEnv::getInstance().setDriverPath(pathChars.c_str());
@@ -51,6 +55,7 @@ void setDebugLayers_native(JNIEnv* env, jobject clazz, jstring layers) {
}
}


const JNINativeMethod g_methods[] = {
const JNINativeMethod g_methods[] = {
    { "getCanLoadSystemLibraries", "()I", reinterpret_cast<void*>(getCanLoadSystemLibraries_native) },
    { "setDriverPath", "(Ljava/lang/String;)V", reinterpret_cast<void*>(setDriverPath) },
    { "setDriverPath", "(Ljava/lang/String;)V", reinterpret_cast<void*>(setDriverPath) },
    { "setAngleInfo", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V", reinterpret_cast<void*>(setAngleInfo_native) },
    { "setAngleInfo", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V", reinterpret_cast<void*>(setAngleInfo_native) },
    { "setLayerPaths", "(Ljava/lang/ClassLoader;Ljava/lang/String;)V", reinterpret_cast<void*>(setLayerPaths_native) },
    { "setLayerPaths", "(Ljava/lang/ClassLoader;Ljava/lang/String;)V", reinterpret_cast<void*>(setLayerPaths_native) },
+2 −1
Original line number Original line Diff line number Diff line
@@ -397,9 +397,10 @@ message GlobalSettingsProto {
        // Ordered GPU debug layer list
        // Ordered GPU debug layer list
        // i.e. <layer1>:<layer2>:...:<layerN>
        // i.e. <layer1>:<layer2>:...:<layerN>
        optional SettingProto debug_layers = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
        optional SettingProto debug_layers = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];

        // App will load ANGLE instead of native GLES drivers.
        // App will load ANGLE instead of native GLES drivers.
        optional SettingProto angle_enabled_app = 3;
        optional SettingProto angle_enabled_app = 3;
        // App that can provide layer libraries.
        optional SettingProto debug_layer_app = 4;
    }
    }
    optional Gpu gpu = 59;
    optional Gpu gpu = 59;


+1 −0
Original line number Original line Diff line number Diff line
@@ -450,6 +450,7 @@ public class SettingsBackupTest {
                    Settings.Global.GPU_DEBUG_APP,
                    Settings.Global.GPU_DEBUG_APP,
                    Settings.Global.GPU_DEBUG_LAYERS,
                    Settings.Global.GPU_DEBUG_LAYERS,
                    Settings.Global.ANGLE_ENABLED_APP,
                    Settings.Global.ANGLE_ENABLED_APP,
                    Settings.Global.GPU_DEBUG_LAYER_APP,
                    Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING,
                    Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING,
                    Settings.Global.INSTALL_CARRIER_APP_NOTIFICATION_PERSISTENT,
                    Settings.Global.INSTALL_CARRIER_APP_NOTIFICATION_PERSISTENT,
                    Settings.Global.INSTALL_CARRIER_APP_NOTIFICATION_SLEEP_MILLIS,
                    Settings.Global.INSTALL_CARRIER_APP_NOTIFICATION_SLEEP_MILLIS,
Loading