summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Adrian Roos <roosa@google.com> 2018-02-21 15:17:07 +0100
committer Adrian Roos <roosa@google.com> 2018-02-22 13:27:31 +0100
commit8d13bf132ce2ce5533da752d56e9f578c65ebbb3 (patch)
tree71d8d9d11034bc064d294c3238270719e024c4ab
parent78cab5a5961b37d984069697dd0ba684184de6bd (diff)
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
-rw-r--r--core/java/android/view/DisplayCutout.java45
-rw-r--r--core/tests/coretests/src/android/view/DisplayCutoutTest.java28
2 files changed, 69 insertions, 4 deletions
diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java
index 272303099193..f5b7068998d6 100644
--- a/core/java/android/view/DisplayCutout.java
+++ b/core/java/android/view/DisplayCutout.java
@@ -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;
}
/**
diff --git a/core/tests/coretests/src/android/view/DisplayCutoutTest.java b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
index ee4bc34d0876..d80735326568 100644
--- a/core/tests/coretests/src/android/view/DisplayCutoutTest.java
+++ b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
@@ -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;
@@ -271,6 +275,30 @@ public class DisplayCutoutTest {
}
@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();