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

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

GraphicsEnvironment: Determine storage limit for EGL blob cache

The application has a quota provided by the platform informing it
how much space it can use for temp storage.  The value can change
over time based platform resources.

Use this value to dictate how much space drivers can use to store
persistent entries in EGL blob cache.

For games, allow 50% of the storage to be used.
For non-games, limit to 25%.

This CL works in conjunction with a native change to use multiple
files for EGL blob cache. (ag/20505145)  The limits for monolithic
cache are unchanged.

Test: ANGLE trace tests, various games and apps
Bug: b/246966894
Change-Id: I38ee45a27c29f913f5de9c0d76722da0d1dcade3
parent 7c0634d9
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.storage.StorageManager;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
@@ -210,6 +211,25 @@ public class GraphicsEnvironment {
            mGameManager.notifyGraphicsEnvironmentSetup();
        }
        Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);

        Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "setBlobCacheQuotaBytes");
        new Thread(() -> {
            try {
                // Perform this lookup on a thread since getCacheQuotaBytes can be slow
                // and we don't need the answer right away. The result is consumed in
                // checkMultifileCacheSize in egl_cache_multifile.cpp. If the value isn't
                // ready, a default is used. The results will likely be ready by the time
                // an app starts using the blobcache.
                final StorageManager sm = context.getSystemService(StorageManager.class);
                final long cacheBytes = sm.getCacheQuotaBytes(appInfoWithMetaData.storageUuid);
                final long scaledCacheBytes =
                        getScaledCacheQuotaBytes(packageName, cacheBytes, appInfoWithMetaData);
                setBlobCacheQuotaBytes(scaledCacheBytes);
            } catch (IOException e) {
                Log.w(TAG, "Failed to look up getCacheQuotaBytes for package: " + packageName);
            }
        }).start();
        Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
    }

    /**
@@ -448,6 +468,31 @@ public class GraphicsEnvironment {
        return ai;
    }

    private static long getScaledCacheQuotaBytes(String packageName, long cacheBytes,
                                                 ApplicationInfo appInfoWithMetaData) {
        if (cacheBytes <= 0) {
            Log.v(TAG, "cacheBytes are zero for " + packageName);
            return 0;
        }
        // Limit the amount of temp storage available to OpenGL drivers to a percentage
        // based on the app type. Games will typically need more space than applications,
        // so give them 50%, 25% for everything else.
        long scaledCacheBytes = 0;
        if (((appInfoWithMetaData.flags & ApplicationInfo.FLAG_IS_GAME) != 0)
                || appInfoWithMetaData.category == ApplicationInfo.CATEGORY_GAME) {
            scaledCacheBytes = cacheBytes / 2;
            Log.v(TAG, "Treating " + packageName
                    + " as a game, setting shader cache quota to 50% ("
                    + scaledCacheBytes + ")");
        } else {
            scaledCacheBytes = cacheBytes / 4;
            Log.v(TAG, "Treating " + packageName
                    + " as an application, setting shader cache quota to 25% ("
                    + scaledCacheBytes + ")");
        }
        return scaledCacheBytes;
    }

    /**
     * Return the appropriate "default" driver, unless overridden by isAngleEnabledByGameMode().
     */
@@ -996,4 +1041,7 @@ public class GraphicsEnvironment {
     * Then the app process is allowed to send stats to GpuStats module.
     */
    public static native void hintActivityLaunch();

    private static native void setBlobCacheQuotaBytes(long cacheBytes);

}
+5 −0
Original line number Diff line number Diff line
@@ -122,6 +122,10 @@ void hintActivityLaunch_native(JNIEnv* env, jobject clazz) {
    android::GraphicsEnv::getInstance().hintActivityLaunch();
}

void setBlobCacheQuotaBytes_native(JNIEnv* env, jobject clazz, jlong cacheBytes) {
    android::GraphicsEnv::getInstance().setBlobCacheQuotaBytes(cacheBytes);
}

const JNINativeMethod g_methods[] = {
        {"isDebuggable", "()Z", reinterpret_cast<void*>(isDebuggable_native)},
        {"setDriverPathAndSphalLibraries", "(Ljava/lang/String;Ljava/lang/String;)V",
@@ -143,6 +147,7 @@ const JNINativeMethod g_methods[] = {
        {"setDebugLayersGLES", "(Ljava/lang/String;)V",
         reinterpret_cast<void*>(setDebugLayersGLES_native)},
        {"hintActivityLaunch", "()V", reinterpret_cast<void*>(hintActivityLaunch_native)},
        {"setBlobCacheQuotaBytes", "(J)V", reinterpret_cast<void*>(setBlobCacheQuotaBytes_native)},
};

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