summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt42
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt3
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt10
4 files changed, 22 insertions, 36 deletions
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt
index 7e1bfb921ca9..addabcc0282a 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt
@@ -21,7 +21,6 @@ import android.graphics.fonts.FontVariationAxis
import android.util.Log
import android.util.LruCache
import android.util.MathUtils
-import android.util.MathUtils.abs
import androidx.annotation.VisibleForTesting
import java.lang.Float.max
import java.lang.Float.min
@@ -30,8 +29,6 @@ private const val TAG_WGHT = "wght"
private const val TAG_ITAL = "ital"
private const val FONT_WEIGHT_DEFAULT_VALUE = 400f
-private const val FONT_WEIGHT_ANIMATION_FRAME_COUNT = 100
-
private const val FONT_ITALIC_MAX = 1f
private const val FONT_ITALIC_MIN = 0f
private const val FONT_ITALIC_ANIMATION_STEP = 0.1f
@@ -39,11 +36,12 @@ private const val FONT_ITALIC_DEFAULT_VALUE = 0f
// Benchmarked via Perfetto, difference between 10 and 50 entries is about 0.3ms in
// frame draw time on a Pixel 6.
-@VisibleForTesting const val FONT_CACHE_MAX_ENTRIES = 10
+@VisibleForTesting const val DEFAULT_FONT_CACHE_MAX_ENTRIES = 10
/** Provide interpolation of two fonts by adjusting font variation settings. */
-class FontInterpolator {
-
+class FontInterpolator(
+ numberOfAnimationSteps: Int? = null,
+) {
/**
* Cache key for the interpolated font.
*
@@ -88,8 +86,9 @@ class FontInterpolator {
// Font interpolator has two level caches: one for input and one for font with different
// variation settings. No synchronization is needed since FontInterpolator is not designed to be
// thread-safe and can be used only on UI thread.
- private val interpCache = LruCache<InterpKey, Font>(FONT_CACHE_MAX_ENTRIES)
- private val verFontCache = LruCache<VarFontKey, Font>(FONT_CACHE_MAX_ENTRIES)
+ val cacheMaxEntries = numberOfAnimationSteps?.let { it * 2 } ?: DEFAULT_FONT_CACHE_MAX_ENTRIES
+ private val interpCache = LruCache<InterpKey, Font>(cacheMaxEntries)
+ private val verFontCache = LruCache<VarFontKey, Font>(cacheMaxEntries)
// Mutable keys for recycling.
private val tmpInterpKey = InterpKey(null, null, 0f)
@@ -128,18 +127,12 @@ class FontInterpolator {
val newAxes =
lerp(startAxes, endAxes) { tag, startValue, endValue ->
when (tag) {
- // TODO: Good to parse 'fvar' table for retrieving default value.
- TAG_WGHT -> {
- adaptiveAdjustWeight(
- MathUtils.lerp(
- startValue ?: FONT_WEIGHT_DEFAULT_VALUE,
- endValue ?: FONT_WEIGHT_DEFAULT_VALUE,
- progress
- ),
+ TAG_WGHT ->
+ MathUtils.lerp(
startValue ?: FONT_WEIGHT_DEFAULT_VALUE,
endValue ?: FONT_WEIGHT_DEFAULT_VALUE,
+ progress
)
- }
TAG_ITAL ->
adjustItalic(
MathUtils.lerp(
@@ -175,9 +168,9 @@ class FontInterpolator {
val newFont = Font.Builder(start).setFontVariationSettings(newAxes.toTypedArray()).build()
interpCache.put(InterpKey(start, end, progress), newFont)
verFontCache.put(VarFontKey(start, newAxes), newFont)
- if (DEBUG) {
- Log.d(LOG_TAG, "[$progress] Cache MISS for $tmpInterpKey / $tmpVarFontKey")
- }
+
+ // Cache misses are likely to create memory leaks, so this is logged at error level.
+ Log.e(LOG_TAG, "[$progress] Cache MISS for $tmpInterpKey / $tmpVarFontKey")
return newFont
}
@@ -225,15 +218,6 @@ class FontInterpolator {
return result
}
- // For the performance reasons, we animate weight with adaptive step. This helps
- // Cache hit ratio in the Skia glyph cache.
- // The reason we don't use fix step is because the range of weight axis is not normalized,
- // some are from 50 to 100, others are from 0 to 1000, so we cannot give a constant proper step
- private fun adaptiveAdjustWeight(value: Float, start: Float, end: Float): Float {
- val step = max(abs(end - start) / FONT_WEIGHT_ANIMATION_FRAME_COUNT, 1F)
- return coerceInWithStep(value, min(start, end), max(start, end), step)
- }
-
// For the performance reasons, we animate italic with FONT_ITALIC_ANIMATION_STEP. This helps
// Cache hit ratio in the Skia glyph cache.
private fun adjustItalic(value: Float) =
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
index 16ddf0c36d9d..b555fa583588 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
@@ -108,7 +108,8 @@ class TextAnimator(
}
// Following two members are for mutable for testing purposes.
- public var textInterpolator: TextInterpolator = TextInterpolator(layout, typefaceCache)
+ public var textInterpolator: TextInterpolator =
+ TextInterpolator(layout, typefaceCache, numberOfAnimationSteps)
public var animator: ValueAnimator =
ValueAnimator.ofFloat(1f).apply {
duration = DEFAULT_ANIMATION_DURATION
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
index 8ed8d8fb61fd..02caeeddd774 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
@@ -31,6 +31,7 @@ import java.lang.Math.max
class TextInterpolator(
layout: Layout,
var typefaceCache: TypefaceVariantCache,
+ numberOfAnimationSteps: Int? = null,
) {
/**
* Returns base paint used for interpolation.
@@ -85,7 +86,7 @@ class TextInterpolator(
private class Line(val runs: List<Run>)
private var lines = listOf<Line>()
- private val fontInterpolator = FontInterpolator()
+ private val fontInterpolator = FontInterpolator(numberOfAnimationSteps)
// Recycling object for glyph drawing and tweaking.
private val tmpPaint = TextPaint()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt
index 57a355f4e127..5e1a8e1432dd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt
@@ -37,7 +37,7 @@ class FontInterpolatorTest : SysuiTestCase() {
private fun assertSameAxes(expect: Font, actual: Font) {
val expectAxes = expect.axes?.also { it.sortBy { axis -> axis.tag } }
val actualAxes = actual.axes?.also { it.sortBy { axis -> axis.tag } }
- assertThat(expectAxes).isEqualTo(actualAxes)
+ assertThat(actualAxes).isEqualTo(expectAxes)
}
private fun assertSameAxes(expectVarSettings: String, actual: Font) {
@@ -46,7 +46,7 @@ class FontInterpolatorTest : SysuiTestCase() {
it.sortBy { axis -> axis.tag }
}
val actualAxes = actual.axes?.also { it.sortBy { axis -> axis.tag } }
- assertThat(expectAxes).isEqualTo(actualAxes)
+ assertThat(actualAxes).isEqualTo(expectAxes)
}
@Test
@@ -61,7 +61,7 @@ class FontInterpolatorTest : SysuiTestCase() {
val interp = FontInterpolator()
assertSameAxes(startFont, interp.lerp(startFont, endFont, 0f))
assertSameAxes(endFont, interp.lerp(startFont, endFont, 1f))
- assertSameAxes("'wght' 496, 'ital' 0.5, 'GRAD' 450", interp.lerp(startFont, endFont, 0.5f))
+ assertSameAxes("'wght' 500, 'ital' 0.5, 'GRAD' 450", interp.lerp(startFont, endFont, 0.5f))
}
@Test
@@ -74,7 +74,7 @@ class FontInterpolatorTest : SysuiTestCase() {
.build()
val interp = FontInterpolator()
- assertSameAxes("'wght' 249, 'ital' 0.5", interp.lerp(startFont, endFont, 0.5f))
+ assertSameAxes("'wght' 250, 'ital' 0.5", interp.lerp(startFont, endFont, 0.5f))
}
@Test
@@ -118,7 +118,7 @@ class FontInterpolatorTest : SysuiTestCase() {
.setFontVariationSettings("'wght' 1")
.build()
val resultFont = interp.lerp(startFont, endFont, 0.5f)
- for (i in 0..FONT_CACHE_MAX_ENTRIES + 1) {
+ for (i in 0..interp.cacheMaxEntries + 1) {
val f1 = Font.Builder(sFont)
.setFontVariationSettings("'wght' ${i * 100}")
.build()