• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.airbnb.lottie;
2 
3 import android.util.Log;
4 
5 import androidx.collection.ArraySet;
6 import androidx.core.util.Pair;
7 
8 import com.airbnb.lottie.utils.MeanCalculator;
9 
10 import java.util.ArrayList;
11 import java.util.Collections;
12 import java.util.Comparator;
13 import java.util.HashMap;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.Set;
17 
18 public class PerformanceTracker {
19 
20   public interface FrameListener {
onFrameRendered(float renderTimeMs)21     void onFrameRendered(float renderTimeMs);
22   }
23 
24   private boolean enabled = false;
25   private final Set<FrameListener> frameListeners = new ArraySet<>();
26   private final Map<String, MeanCalculator> layerRenderTimes = new HashMap<>();
27   private final Comparator<Pair<String, Float>> floatComparator =
28       new Comparator<Pair<String, Float>>() {
29         @Override public int compare(Pair<String, Float> o1, Pair<String, Float> o2) {
30           float r1 = o1.second;
31           float r2 = o2.second;
32           if (r2 > r1) {
33             return 1;
34           } else if (r1 > r2) {
35             return -1;
36           }
37           return 0;
38         }
39       };
40 
setEnabled(boolean enabled)41   void setEnabled(boolean enabled) {
42     this.enabled = enabled;
43   }
44 
recordRenderTime(String layerName, float millis)45   public void recordRenderTime(String layerName, float millis) {
46     if (!enabled) {
47       return;
48     }
49     MeanCalculator meanCalculator = layerRenderTimes.get(layerName);
50     if (meanCalculator == null) {
51       meanCalculator = new MeanCalculator();
52       layerRenderTimes.put(layerName, meanCalculator);
53     }
54     meanCalculator.add(millis);
55 
56     if (layerName.equals("__container")) {
57       for (FrameListener listener : frameListeners) {
58         listener.onFrameRendered(millis);
59       }
60     }
61   }
62 
addFrameListener(FrameListener frameListener)63   public void addFrameListener(FrameListener frameListener) {
64     frameListeners.add(frameListener);
65   }
66 
removeFrameListener(FrameListener frameListener)67   @SuppressWarnings("unused") public void removeFrameListener(FrameListener frameListener) {
68     frameListeners.remove(frameListener);
69   }
70 
clearRenderTimes()71   public void clearRenderTimes() {
72     layerRenderTimes.clear();
73   }
74 
logRenderTimes()75   public void logRenderTimes() {
76     if (!enabled) {
77       return;
78     }
79     List<Pair<String, Float>> sortedRenderTimes = getSortedRenderTimes();
80     Log.d(L.TAG, "Render times:");
81     for (int i = 0; i < sortedRenderTimes.size(); i++) {
82       Pair<String, Float> layer = sortedRenderTimes.get(i);
83       Log.d(L.TAG, String.format("\t\t%30s:%.2f", layer.first, layer.second));
84     }
85   }
86 
getSortedRenderTimes()87   public List<Pair<String, Float>> getSortedRenderTimes() {
88     if (!enabled) {
89       return Collections.emptyList();
90     }
91     List<Pair<String, Float>> sortedRenderTimes = new ArrayList<>(layerRenderTimes.size());
92     for (Map.Entry<String, MeanCalculator> e : layerRenderTimes.entrySet()) {
93       sortedRenderTimes.add(new Pair<>(e.getKey(), e.getValue().getMean()));
94     }
95     Collections.sort(sortedRenderTimes, floatComparator);
96     return sortedRenderTimes;
97   }
98 }
99