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

Commit 8d13bf13 authored by Adrian Roos's avatar Adrian Roos
Browse files

DisplayCutout: Cache inflations from resources

Caches inflations from resources if the parameters did  not
change. This increases the hitrate of the rotation variants
cache in window manager, and avoids unnecessairy reinflations
whenever the display changes.

Change-Id: I2ed9a2c259158bf1a6b551b3422534efbfec99c9
Bug: 72444324
Test: atest DisplayCutoutTest
parent 78cab5a5
Loading
Loading
Loading
Loading
+41 −4
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ import static android.view.Surface.ROTATION_180;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;

import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;

import android.content.res.Resources;
import android.graphics.Matrix;
import android.graphics.Path;
@@ -38,6 +40,7 @@ import android.util.Size;
import android.util.proto.ProtoOutputStream;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;

import java.util.Objects;
@@ -73,6 +76,17 @@ public final class DisplayCutout {
    public static final DisplayCutout NO_CUTOUT = new DisplayCutout(ZERO_RECT, EMPTY_REGION,
            new Size(0, 0));


    private static final Object CACHE_LOCK = new Object();
    @GuardedBy("CACHE_LOCK")
    private static String sCachedSpec;
    @GuardedBy("CACHE_LOCK")
    private static int sCachedDisplayWidth;
    @GuardedBy("CACHE_LOCK")
    private static float sCachedDensity;
    @GuardedBy("CACHE_LOCK")
    private static DisplayCutout sCachedCutout;

    private final Rect mSafeInsets;
    private final Region mBounds;
    private final Size mFrameSize;
@@ -350,10 +364,26 @@ public final class DisplayCutout {
     * @hide
     */
    public static DisplayCutout fromResources(Resources res, int displayWidth) {
        String spec = res.getString(R.string.config_mainBuiltInDisplayCutout);
        return fromSpec(res.getString(R.string.config_mainBuiltInDisplayCutout),
                displayWidth, res.getDisplayMetrics().density);
    }

    /**
     * Creates an instance according to the supplied {@link android.util.PathParser.PathData} spec.
     *
     * @hide
     */
    @VisibleForTesting(visibility = PRIVATE)
    public static DisplayCutout fromSpec(String spec, int displayWidth, float density) {
        if (TextUtils.isEmpty(spec)) {
            return null;
        }
        synchronized (CACHE_LOCK) {
            if (spec.equals(sCachedSpec) && sCachedDisplayWidth == displayWidth
                    && sCachedDensity == density) {
                return sCachedCutout;
            }
        }
        spec = spec.trim();
        final boolean inDp = spec.endsWith(DP_MARKER);
        if (inDp) {
@@ -370,12 +400,19 @@ public final class DisplayCutout {

        final Matrix m = new Matrix();
        if (inDp) {
            final float dpToPx = res.getDisplayMetrics().density;
            m.postScale(dpToPx, dpToPx);
            m.postScale(density, density);
        }
        m.postTranslate(displayWidth / 2f, 0);
        p.transform(m);
        return fromBounds(p);

        final DisplayCutout result = fromBounds(p);
        synchronized (CACHE_LOCK) {
            sCachedSpec = spec;
            sCachedDisplayWidth = displayWidth;
            sCachedDensity = density;
            sCachedCutout = result;
        }
        return result;
    }

    /**
+28 −0
Original line number Diff line number Diff line
@@ -18,10 +18,14 @@ package android.view;

import static android.view.DisplayCutout.NO_CUTOUT;
import static android.view.DisplayCutout.fromBoundingRect;
import static android.view.DisplayCutout.fromSpec;

import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.sameInstance;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

import android.graphics.Rect;
@@ -270,6 +274,30 @@ public class DisplayCutoutTest {
        assertEquals(posAfterWrite, p.dataPosition());
    }

    @Test
    public void fromSpec_caches() {
        DisplayCutout cached = fromSpec("L1,0 L1,1 L0,1 z", 200, 1f);
        assertThat(fromSpec("L1,0 L1,1 L0,1 z", 200, 1f), sameInstance(cached));
    }

    @Test
    public void fromSpec_wontCacheIfSpecChanges() {
        DisplayCutout cached = fromSpec("L1,0 L1000,1000 L0,1 z", 200, 1f);
        assertThat(fromSpec("L1,0 L1,1 L0,1 z", 200, 1f), not(sameInstance(cached)));
    }

    @Test
    public void fromSpec_wontCacheIfScreenWidthChanges() {
        DisplayCutout cached = fromSpec("L1,0 L1,1 L0,1 z", 2000, 1f);
        assertThat(fromSpec("L1,0 L1,1 L0,1 z", 200, 1f), not(sameInstance(cached)));
    }

    @Test
    public void fromSpec_wontCacheIfDensityChanges() {
        DisplayCutout cached = fromSpec("L1,0 L1,1 L0,1 z", 200, 2f);
        assertThat(fromSpec("L1,0 L1,1 L0,1 z", 200, 1f), not(sameInstance(cached)));
    }

    @Test
    public void parcel_unparcel_nocutout() {
        Parcel p = Parcel.obtain();