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