Skip to content

Commit

Permalink
Added more systrace markers and made LottieTrace multi-thread compati…
Browse files Browse the repository at this point in the history
…ble (#2275)
  • Loading branch information
gpeal committed Apr 9, 2023
1 parent cb72e02 commit bb777e8
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 34 deletions.
50 changes: 16 additions & 34 deletions lottie/src/main/java/com/airbnb/lottie/L.java
Expand Up @@ -12,6 +12,7 @@
import com.airbnb.lottie.network.LottieNetworkFetcher;
import com.airbnb.lottie.network.NetworkCache;
import com.airbnb.lottie.network.NetworkFetcher;
import com.airbnb.lottie.utils.LottieTrace;

import java.io.File;

Expand All @@ -21,20 +22,16 @@ public class L {
public static boolean DBG = false;
public static final String TAG = "LOTTIE";

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;
private static int depthPastMaxDepth = 0;

private static LottieNetworkFetcher fetcher;
private static LottieNetworkCacheProvider cacheProvider;

private static volatile NetworkFetcher networkFetcher;
private static volatile NetworkCache networkCache;
private static ThreadLocal<LottieTrace> lottieTrace;

private L() {
}
Expand All @@ -44,9 +41,8 @@ public static void setTraceEnabled(boolean enabled) {
return;
}
traceEnabled = enabled;
if (traceEnabled) {
sections = new String[MAX_DEPTH];
startTimeNs = new long[MAX_DEPTH];
if (traceEnabled && lottieTrace == null) {
lottieTrace = new ThreadLocal<>();
}
}

Expand All @@ -58,34 +54,23 @@ public static void beginSection(String section) {
if (!traceEnabled) {
return;
}
if (traceDepth == MAX_DEPTH) {
depthPastMaxDepth++;
return;
}
sections[traceDepth] = section;
startTimeNs[traceDepth] = System.nanoTime();
TraceCompat.beginSection(section);
traceDepth++;
getTrace().beginSection(section);
}

public static float endSection(String section) {
if (depthPastMaxDepth > 0) {
depthPastMaxDepth--;
return 0;
}
if (!traceEnabled) {
return 0;
}
traceDepth--;
if (traceDepth == -1) {
throw new IllegalStateException("Can't end trace section. There are none.");
}
if (!section.equals(sections[traceDepth])) {
throw new IllegalStateException("Unbalanced trace call " + section +
". Expected " + sections[traceDepth] + ".");
return getTrace().endSection(section);
}

private static LottieTrace getTrace() {
LottieTrace trace = lottieTrace.get();
if (trace == null) {
trace = new LottieTrace();
lottieTrace.set(trace);
}
TraceCompat.endSection();
return (System.nanoTime() - startTimeNs[traceDepth]) / 1000000f;
return trace;
}

public static void setFetcher(LottieNetworkFetcher customFetcher) {
Expand Down Expand Up @@ -121,11 +106,8 @@ public static NetworkCache networkCache(@NonNull final Context context) {
synchronized (NetworkCache.class) {
local = networkCache;
if (local == null) {
networkCache = local = new NetworkCache(cacheProvider != null ? cacheProvider : new LottieNetworkCacheProvider() {
@Override @NonNull public File getCacheDir() {
return new File(appContext.getCacheDir(), "lottie_network_cache");
}
});
networkCache = local = new NetworkCache(cacheProvider != null ? cacheProvider :
() -> new File(appContext.getCacheDir(), "lottie_network_cache"));
}
}
}
Expand Down
Expand Up @@ -46,7 +46,9 @@ public void addUpdateListener(AnimationListener listener) {
}

public void setProgress(@FloatRange(from = 0f, to = 1f) float progress) {
L.beginSection("BaseKeyframeAnimation#setProgress");
if (keyframesWrapper.isEmpty()) {
L.endSection("BaseKeyframeAnimation#setProgress");
return;
}
if (progress < getStartDelayProgress()) {
Expand All @@ -56,18 +58,22 @@ public void setProgress(@FloatRange(from = 0f, to = 1f) float progress) {
}

if (progress == this.progress) {
L.endSection("BaseKeyframeAnimation#setProgress");
return;
}
this.progress = progress;
if (keyframesWrapper.isValueChanged(progress)) {
notifyListeners();
}
L.endSection("BaseKeyframeAnimation#setProgress");
}

public void notifyListeners() {
L.beginSection("BaseKeyframeAnimation#notifyListeners");
for (int i = 0; i < listeners.size(); i++) {
listeners.get(i).onValueChanged();
}
L.endSection("BaseKeyframeAnimation#notifyListeners");
}

protected Keyframe<K> getCurrentKeyframe() {
Expand Down
12 changes: 12 additions & 0 deletions lottie/src/main/java/com/airbnb/lottie/model/layer/BaseLayer.java
Expand Up @@ -571,22 +571,34 @@ private void setVisible(boolean visible) {
}

void setProgress(@FloatRange(from = 0f, to = 1f) float progress) {
L.beginSection("BaseLayer#setProgress");
// Time stretch should not be applied to the layer transform.
L.beginSection("BaseLayer#setProgress.transform");
transform.setProgress(progress);
L.endSection("BaseLayer#setProgress.transform");
if (mask != null) {
L.beginSection("BaseLayer#setProgress.mask");
for (int i = 0; i < mask.getMaskAnimations().size(); i++) {
mask.getMaskAnimations().get(i).setProgress(progress);
}
L.endSection("BaseLayer#setProgress.mask");
}
if (inOutAnimation != null) {
L.beginSection("BaseLayer#setProgress.inout");
inOutAnimation.setProgress(progress);
L.endSection("BaseLayer#setProgress.inout");
}
if (matteLayer != null) {
L.beginSection("BaseLayer#setProgress.matte");
matteLayer.setProgress(progress);
L.endSection("BaseLayer#setProgress.matte");
}
L.beginSection("BaseLayer#setProgress.animations." + animations.size());
for (int i = 0; i < animations.size(); i++) {
animations.get(i).setProgress(progress);
}
L.endSection("BaseLayer#setProgress.animations." + animations.size());
L.endSection("BaseLayer#setProgress");
}

private void buildParentLayerListIfNeeded() {
Expand Down
Expand Up @@ -4,6 +4,7 @@
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.Log;

import androidx.annotation.FloatRange;
import androidx.annotation.Nullable;
Expand Down Expand Up @@ -142,6 +143,7 @@ public void setClipToCompositionBounds(boolean clipToCompositionBounds) {
}

@Override public void setProgress(@FloatRange(from = 0f, to = 1f) float progress) {
L.beginSection("CompositionLayer#setProgress");
super.setProgress(progress);
if (timeRemapping != null) {
// The duration has 0.01 frame offset to show end of animation properly.
Expand All @@ -162,6 +164,7 @@ public void setClipToCompositionBounds(boolean clipToCompositionBounds) {
for (int i = layers.size() - 1; i >= 0; i--) {
layers.get(i).setProgress(progress);
}
L.endSection("CompositionLayer#setProgress");
}

public boolean hasMasks() {
Expand Down
42 changes: 42 additions & 0 deletions lottie/src/main/java/com/airbnb/lottie/utils/LottieTrace.java
@@ -0,0 +1,42 @@
package com.airbnb.lottie.utils;

import androidx.core.os.TraceCompat;

public class LottieTrace {
private static final int MAX_DEPTH = 20;

private final String[] sections = new String[MAX_DEPTH];
private final long[] startTimeNs = new long[MAX_DEPTH];
private int traceDepth = 0;
private int depthPastMaxDepth = 0;

public void beginSection(String section) {
if (traceDepth == MAX_DEPTH) {
depthPastMaxDepth++;
return;
}
sections[traceDepth] = section;
startTimeNs[traceDepth] = System.nanoTime();
//noinspection deprecation
TraceCompat.beginSection(section);
traceDepth++;
}

public float endSection(String section) {
if (depthPastMaxDepth > 0) {
depthPastMaxDepth--;
return 0;
}
traceDepth--;
if (traceDepth == -1) {
throw new IllegalStateException("Can't end trace section. There are none.");
}
if (!section.equals(sections[traceDepth])) {
throw new IllegalStateException("Unbalanced trace call " + section +
". Expected " + sections[traceDepth] + ".");
}
//noinspection deprecation
TraceCompat.endSection();
return (System.nanoTime() - startTimeNs[traceDepth]) / 1000000f;
}
}

0 comments on commit bb777e8

Please sign in to comment.