Disable the path interpolator cache for snapshot tests
diff --git a/lottie/src/main/java/com/airbnb/lottie/L.java b/lottie/src/main/java/com/airbnb/lottie/L.java
index c88fd6e..8bfe62c 100644
--- a/lottie/src/main/java/com/airbnb/lottie/L.java
+++ b/lottie/src/main/java/com/airbnb/lottie/L.java
@@ -24,6 +24,7 @@
private static final int MAX_DEPTH = 20;
private static boolean traceEnabled = false;
private static boolean networkCacheEnabled = true;
+ private static boolean disablePathInterpolatorCache = true;
private static String[] sections;
private static long[] startTimeNs;
private static int traceDepth = 0;
@@ -130,4 +131,12 @@
}
return local;
}
+
+ public static void setDisablePathInterpolatorCache(boolean disablePathInterpolatorCache) {
+ L.disablePathInterpolatorCache = disablePathInterpolatorCache;
+ }
+
+ public static boolean getDisablePathInterpolatorCache() {
+ return disablePathInterpolatorCache;
+ }
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/Lottie.java b/lottie/src/main/java/com/airbnb/lottie/Lottie.java
index 8faaeb7..c585572 100644
--- a/lottie/src/main/java/com/airbnb/lottie/Lottie.java
+++ b/lottie/src/main/java/com/airbnb/lottie/Lottie.java
@@ -20,5 +20,7 @@
L.setCacheProvider(lottieConfig.cacheProvider);
L.setTraceEnabled(lottieConfig.enableSystraceMarkers);
L.setNetworkCacheEnabled(lottieConfig.enableNetworkCache);
+ L.setNetworkCacheEnabled(lottieConfig.enableNetworkCache);
+ L.setDisablePathInterpolatorCache(lottieConfig.disablePathInterpolatorCache);
}
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/LottieConfig.java b/lottie/src/main/java/com/airbnb/lottie/LottieConfig.java
index be426fa..b186058 100644
--- a/lottie/src/main/java/com/airbnb/lottie/LottieConfig.java
+++ b/lottie/src/main/java/com/airbnb/lottie/LottieConfig.java
@@ -19,13 +19,15 @@
@Nullable final LottieNetworkCacheProvider cacheProvider;
final boolean enableSystraceMarkers;
final boolean enableNetworkCache;
+ final boolean disablePathInterpolatorCache;
private LottieConfig(@Nullable LottieNetworkFetcher networkFetcher, @Nullable LottieNetworkCacheProvider cacheProvider,
- boolean enableSystraceMarkers, boolean enableNetworkCache) {
+ boolean enableSystraceMarkers, boolean enableNetworkCache, boolean disablePathInterpolatorCache) {
this.networkFetcher = networkFetcher;
this.cacheProvider = cacheProvider;
this.enableSystraceMarkers = enableSystraceMarkers;
this.enableNetworkCache = enableNetworkCache;
+ this.disablePathInterpolatorCache = disablePathInterpolatorCache;
}
public static final class Builder {
@@ -36,6 +38,7 @@
private LottieNetworkCacheProvider cacheProvider;
private boolean enableSystraceMarkers = false;
private boolean enableNetworkCache = true;
+ private boolean disablePathInterpolatorCache = true;
/**
* Lottie has a default network fetching stack built on {@link java.net.HttpURLConnection}. However, if you would like to hook into your own
@@ -111,9 +114,22 @@
return this;
}
+ /**
+ * When parsing animations, Lottie has a path interpolator cache. This cache allows Lottie to reuse PathInterpolators
+ * across an animation. This is desirable in most cases. However, when shared across screenshot tests, it can cause slight
+ * deviations in the rendering due to underlying approximations in the PathInterpolator.
+ *
+ * The cache is enabled by default and should probably only be disabled for screenshot tests.
+ */
+ @NonNull
+ public Builder setDisablePathInterpolatorCache(boolean disable) {
+ disablePathInterpolatorCache = disable;
+ return this;
+ }
+
@NonNull
public LottieConfig build() {
- return new LottieConfig(networkFetcher, cacheProvider, enableSystraceMarkers, enableNetworkCache);
+ return new LottieConfig(networkFetcher, cacheProvider, enableSystraceMarkers, enableNetworkCache, disablePathInterpolatorCache);
}
}
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/KeyframeParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/KeyframeParser.java
index 4f0bd87..219b554 100644
--- a/lottie/src/main/java/com/airbnb/lottie/parser/KeyframeParser.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/KeyframeParser.java
@@ -8,6 +8,8 @@
import androidx.collection.SparseArrayCompat;
import androidx.core.view.animation.PathInterpolatorCompat;
+import com.airbnb.lottie.L;
+import com.airbnb.lottie.Lottie;
import com.airbnb.lottie.LottieComposition;
import com.airbnb.lottie.parser.moshi.JsonReader;
import com.airbnb.lottie.utils.MiscUtils;
@@ -332,7 +334,7 @@
cp2.x = MiscUtils.clamp(cp2.x, -1f, 1f);
cp2.y = MiscUtils.clamp(cp2.y, -MAX_CP_VALUE, MAX_CP_VALUE);
int hash = Utils.hashFor(cp1.x, cp1.y, cp2.x, cp2.y);
- WeakReference<Interpolator> interpolatorRef = getInterpolator(hash);
+ WeakReference<Interpolator> interpolatorRef = L.getDisablePathInterpolatorCache() ? null : getInterpolator(hash);
if (interpolatorRef != null) {
interpolator = interpolatorRef.get();
}
@@ -350,13 +352,15 @@
interpolator = new LinearInterpolator();
}
}
- try {
- putInterpolator(hash, new WeakReference<>(interpolator));
- } catch (ArrayIndexOutOfBoundsException e) {
- // It is not clear why but SparseArrayCompat sometimes fails with this:
- // https://github.com/airbnb/lottie-android/issues/452
- // Because this is not a critical operation, we can safely just ignore it.
- // I was unable to repro this to attempt a proper fix.
+ if (!L.getDisablePathInterpolatorCache()) {
+ try {
+ putInterpolator(hash, new WeakReference<>(interpolator));
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // It is not clear why but SparseArrayCompat sometimes fails with this:
+ // https://github.com/airbnb/lottie-android/issues/452
+ // Because this is not a critical operation, we can safely just ignore it.
+ // I was unable to repro this to attempt a proper fix.
+ }
}
}
return interpolator;
diff --git a/snapshot-tests/src/androidTest/java/com/airbnb/lottie/snapshots/LottieSnapshotTest.kt b/snapshot-tests/src/androidTest/java/com/airbnb/lottie/snapshots/LottieSnapshotTest.kt
index 9af9410..8dfd190 100644
--- a/snapshot-tests/src/androidTest/java/com/airbnb/lottie/snapshots/LottieSnapshotTest.kt
+++ b/snapshot-tests/src/androidTest/java/com/airbnb/lottie/snapshots/LottieSnapshotTest.kt
@@ -11,7 +11,9 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.rule.GrantPermissionRule
+import com.airbnb.lottie.Lottie
import com.airbnb.lottie.LottieAnimationView
+import com.airbnb.lottie.LottieConfig
import com.airbnb.lottie.model.LottieCompositionCache
import com.airbnb.lottie.snapshots.tests.ApplyOpacityToLayerTestCase
import com.airbnb.lottie.snapshots.tests.AssetsTestCase
@@ -67,6 +69,11 @@
@Before
fun setup() {
LottieCompositionCache.getInstance().resize(1)
+ Lottie.initialize(
+ LottieConfig.Builder()
+ .setDisablePathInterpolatorCache(true)
+ .build()
+ )
val context = ApplicationProvider.getApplicationContext<Context>()
snapshotter = HappoSnapshotter(context) { name, variant ->
snapshotActivityRule.scenario.onActivity { activity ->