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

Commit 5f66fb81 authored by John Reck's avatar John Reck
Browse files

Change how memory policy is configured

Should be a mostly no-op but adds a handful of new options

* Adds a 'MemoryPolicy' to mostly consolidate memory settings
* Moves trim handling into HWUI proper
* Adds settings for UI hidden & context destruction that's not
  dependent on TRIM signals
* Treats persistent process the same as system_server
* Tweaks HardwareBitmapUploader timeout to reduce churn

Bug: 245565051
Test: builds & boots

Change-Id: I1f1b3db884ef7fa45ff2556436464a99440b998e
parent d1128537
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -6662,6 +6662,9 @@ public final class ActivityThread extends ClientTransactionHandler


        // Pass the current context to HardwareRenderer
        // Pass the current context to HardwareRenderer
        HardwareRenderer.setContextForInit(getSystemContext());
        HardwareRenderer.setContextForInit(getSystemContext());
        if (data.persistent) {
            HardwareRenderer.setIsSystemOrPersistent();
        }


        // Instrumentation info affects the class loader, so load it before
        // Instrumentation info affects the class loader, so load it before
        // setting up the app context.
        // setting up the app context.
+3 −5
Original line number Original line Diff line number Diff line
@@ -196,8 +196,6 @@ public final class ThreadedRenderer extends HardwareRenderer {
     */
     */
    public static boolean sRendererEnabled = true;
    public static boolean sRendererEnabled = true;


    public static boolean sTrimForeground = false;

    /**
    /**
     * Controls whether or not the renderer should aggressively trim
     * Controls whether or not the renderer should aggressively trim
     * memory. Note that this must not be set for any process that uses
     * memory. Note that this must not be set for any process that uses
@@ -205,9 +203,10 @@ public final class ThreadedRenderer extends HardwareRenderer {
     * that do not go into the background.
     * that do not go into the background.
     */
     */
    public static void enableForegroundTrimming() {
    public static void enableForegroundTrimming() {
        sTrimForeground = true;
        // TODO: Remove
    }
    }



    /**
    /**
     * Initialize HWUI for being in a system process like system_server
     * Initialize HWUI for being in a system process like system_server
     * Should not be called in non-system processes
     * Should not be called in non-system processes
@@ -218,9 +217,8 @@ public final class ThreadedRenderer extends HardwareRenderer {
        // process.
        // process.
        if (!ActivityManager.isHighEndGfx()) {
        if (!ActivityManager.isHighEndGfx()) {
            sRendererEnabled = false;
            sRendererEnabled = false;
        } else {
            enableForegroundTrimming();
        }
        }
        setIsSystemOrPersistent();
    }
    }


    /**
    /**
+0 −3
Original line number Original line Diff line number Diff line
@@ -1766,9 +1766,6 @@ public final class ViewRootImpl implements ViewParent,
                mAppVisibilityChanged = true;
                mAppVisibilityChanged = true;
                scheduleTraversals();
                scheduleTraversals();
            }
            }
            if (!mAppVisible) {
                WindowManagerGlobal.trimForeground();
            }
            AnimationHandler.requestAnimatorsEnabled(mAppVisible, this);
            AnimationHandler.requestAnimatorsEnabled(mAppVisible, this);
        }
        }
    }
    }
+0 −61
Original line number Original line Diff line number Diff line
@@ -19,9 +19,7 @@ package android.view;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.compat.annotation.UnsupportedAppUsage;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.ApplicationInfo;
import android.content.res.Configuration;
import android.content.res.Configuration;
@@ -524,9 +522,6 @@ public final class WindowManagerGlobal {
            }
            }
            allViewsRemoved = mRoots.isEmpty();
            allViewsRemoved = mRoots.isEmpty();
        }
        }
        if (ThreadedRenderer.sTrimForeground) {
            doTrimForeground();
        }


        // If we don't have any views anymore in our process, we no longer need the
        // If we don't have any views anymore in our process, we no longer need the
        // InsetsAnimationThread to save some resources.
        // InsetsAnimationThread to save some resources.
@@ -543,65 +538,9 @@ public final class WindowManagerGlobal {
        return index;
        return index;
    }
    }


    public static boolean shouldDestroyEglContext(int trimLevel) {
        // On low-end gfx devices we trim when memory is moderate;
        // on high-end devices we do this when low.
        if (trimLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
            return true;
        }
        if (trimLevel >= ComponentCallbacks2.TRIM_MEMORY_MODERATE
                && !ActivityManager.isHighEndGfx()) {
            return true;
        }
        return false;
    }

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public void trimMemory(int level) {
    public void trimMemory(int level) {

        if (shouldDestroyEglContext(level)) {
            // Destroy all hardware surfaces and resources associated to
            // known windows
            synchronized (mLock) {
                for (int i = mRoots.size() - 1; i >= 0; --i) {
                    mRoots.get(i).destroyHardwareResources();
                }
            }
            // Force a full memory flush
            level = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
        }

        ThreadedRenderer.trimMemory(level);
        ThreadedRenderer.trimMemory(level);

        if (ThreadedRenderer.sTrimForeground) {
            doTrimForeground();
        }
    }

    public static void trimForeground() {
        if (ThreadedRenderer.sTrimForeground) {
            WindowManagerGlobal wm = WindowManagerGlobal.getInstance();
            wm.doTrimForeground();
        }
    }

    private void doTrimForeground() {
        boolean hasVisibleWindows = false;
        synchronized (mLock) {
            for (int i = mRoots.size() - 1; i >= 0; --i) {
                final ViewRootImpl root = mRoots.get(i);
                if (root.mView != null && root.getHostVisibility() == View.VISIBLE
                        && root.mAttachInfo.mThreadedRenderer != null) {
                    hasVisibleWindows = true;
                } else {
                    root.destroyHardwareResources();
                }
            }
        }
        if (!hasVisibleWindows) {
            ThreadedRenderer.trimMemory(
                    ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
        }
    }
    }


    public void dumpGfxInfo(FileDescriptor fd, String[] args) {
    public void dumpGfxInfo(FileDescriptor fd, String[] args) {
+60 −42
Original line number Original line Diff line number Diff line
@@ -47,9 +47,7 @@ import java.io.File;
import java.io.FileDescriptor;
import java.io.FileDescriptor;
import java.lang.annotation.Retention;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.RetentionPolicy;
import java.util.Optional;
import java.util.concurrent.Executor;
import java.util.concurrent.Executor;
import java.util.stream.Stream;


import sun.misc.Cleaner;
import sun.misc.Cleaner;


@@ -1141,6 +1139,16 @@ public class HardwareRenderer {
        ProcessInitializer.sInstance.setContext(context);
        ProcessInitializer.sInstance.setContext(context);
    }
    }


    /**
     * Sets whether or not the current process is a system or persistent process. Used to influence
     * the chosen memory usage policy.
     *
     * @hide
     **/
    public static void setIsSystemOrPersistent() {
        nSetIsSystemOrPersistent(true);
    }

    /**
    /**
     * Returns true if HardwareRender will produce output.
     * Returns true if HardwareRender will produce output.
     *
     *
@@ -1204,30 +1212,6 @@ public class HardwareRenderer {
    private static class ProcessInitializer {
    private static class ProcessInitializer {
        static ProcessInitializer sInstance = new ProcessInitializer();
        static ProcessInitializer sInstance = new ProcessInitializer();


        // Magic values from android/data_space.h
        private static final int INTERNAL_DATASPACE_SRGB = 142671872;
        private static final int INTERNAL_DATASPACE_DISPLAY_P3 = 143261696;
        private static final int INTERNAL_DATASPACE_SCRGB = 411107328;

        private enum Dataspace {
            DISPLAY_P3(ColorSpace.Named.DISPLAY_P3, INTERNAL_DATASPACE_DISPLAY_P3),
            SCRGB(ColorSpace.Named.EXTENDED_SRGB, INTERNAL_DATASPACE_SCRGB),
            SRGB(ColorSpace.Named.SRGB, INTERNAL_DATASPACE_SRGB);

            private final ColorSpace.Named mColorSpace;
            private final int mNativeDataspace;
            Dataspace(ColorSpace.Named colorSpace, int nativeDataspace) {
                this.mColorSpace = colorSpace;
                this.mNativeDataspace = nativeDataspace;
            }

            static Optional<Dataspace> find(ColorSpace colorSpace) {
                return Stream.of(Dataspace.values())
                        .filter(d -> ColorSpace.get(d.mColorSpace).equals(colorSpace))
                        .findFirst();
            }
        }

        private boolean mInitialized = false;
        private boolean mInitialized = false;
        private boolean mDisplayInitialized = false;
        private boolean mDisplayInitialized = false;


@@ -1296,6 +1280,7 @@ public class HardwareRenderer {
            initDisplayInfo();
            initDisplayInfo();


            nSetIsHighEndGfx(ActivityManager.isHighEndGfx());
            nSetIsHighEndGfx(ActivityManager.isHighEndGfx());
            nSetIsLowRam(ActivityManager.isLowRamDeviceStatic());
            // Defensively clear out the context in case we were passed a context that can leak
            // Defensively clear out the context in case we were passed a context that can leak
            // if we live longer than it, e.g. an activity context.
            // if we live longer than it, e.g. an activity context.
            mContext = null;
            mContext = null;
@@ -1314,26 +1299,55 @@ public class HardwareRenderer {
                return;
                return;
            }
            }


            Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
            final Display defaultDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY);
            if (display == null) {
            if (defaultDisplay == null) {
                Log.d(LOG_TAG, "Failed to find default display for display-based configuration");
                Log.d(LOG_TAG, "Failed to find default display for display-based configuration");
                return;
                return;
            }
            }


            Dataspace wideColorDataspace =
            final Display[] allDisplays = dm.getDisplays();
                    Optional.ofNullable(display.getPreferredWideGamutColorSpace())
            if (allDisplays.length == 0) {
                            .flatMap(Dataspace::find)
                Log.d(LOG_TAG, "Failed to query displays");
                            // Default to SRGB if the display doesn't support wide color
                return;
                            .orElse(Dataspace.SRGB);
            }

            final Mode activeMode = defaultDisplay.getMode();
            final ColorSpace defaultWideColorSpace =
                    defaultDisplay.getPreferredWideGamutColorSpace();
            int wideColorDataspace = defaultWideColorSpace != null
                    ? defaultWideColorSpace.getDataSpace() : 0;
            // largest width & height are used to size the default HWUI cache sizes. So find the
            // largest display resolution we could encounter & use that as the guidance. The actual
            // memory policy in play will interpret these values differently.
            int largestWidth = activeMode.getPhysicalWidth();
            int largestHeight = activeMode.getPhysicalHeight();

            for (int i = 0; i < allDisplays.length; i++) {
                final Display display = allDisplays[i];
                // Take the first wide gamut dataspace as the source of truth
                // Possibly should do per-HardwareRenderer wide gamut dataspace so we can use the
                // target display's ideal instead
                if (wideColorDataspace == 0) {
                    ColorSpace cs = display.getPreferredWideGamutColorSpace();
                    if (cs != null) {
                        wideColorDataspace = cs.getDataSpace();
                    }
                }
                Mode[] modes = display.getSupportedModes();
                for (int j = 0; j < modes.length; j++) {
                    Mode mode = modes[j];
                    int width = mode.getPhysicalWidth();
                    int height = mode.getPhysicalHeight();
                    if ((width * height) > (largestWidth * largestHeight)) {
                        largestWidth = width;
                        largestHeight = height;
                    }
                }
            }


            // Grab the physical screen dimensions from the active display mode
            nInitDisplayInfo(largestWidth, largestHeight, defaultDisplay.getRefreshRate(),
            // Strictly speaking the screen resolution may not always be constant - it is for
                    wideColorDataspace, defaultDisplay.getAppVsyncOffsetNanos(),
            // sizing the font cache for the underlying rendering thread. Since it's a
                    defaultDisplay.getPresentationDeadlineNanos());
            // heuristic we don't need to be always 100% correct.
            Mode activeMode = display.getMode();
            nInitDisplayInfo(activeMode.getPhysicalWidth(), activeMode.getPhysicalHeight(),
                    display.getRefreshRate(), wideColorDataspace.mNativeDataspace,
                    display.getAppVsyncOffsetNanos(), display.getPresentationDeadlineNanos());


            mDisplayInitialized = true;
            mDisplayInitialized = true;
        }
        }
@@ -1418,6 +1432,10 @@ public class HardwareRenderer {


    private static native void nSetIsHighEndGfx(boolean isHighEndGfx);
    private static native void nSetIsHighEndGfx(boolean isHighEndGfx);


    private static native void nSetIsLowRam(boolean isLowRam);

    private static native void nSetIsSystemOrPersistent(boolean isSystemOrPersistent);

    private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
    private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);


    private static native void nDestroy(long nativeProxy, long rootRenderNode);
    private static native void nDestroy(long nativeProxy, long rootRenderNode);
Loading