the road to 60 fps
TRANSCRIPT
![Page 1: The Road to 60 FPS](https://reader031.vdocuments.us/reader031/viewer/2022022412/58f176e21a28abee388b457f/html5/thumbnails/1.jpg)
The Road to 60 FPS
Jason Sendros
![Page 2: The Road to 60 FPS](https://reader031.vdocuments.us/reader031/viewer/2022022412/58f176e21a28abee388b457f/html5/thumbnails/2.jpg)
Why care?
![Page 3: The Road to 60 FPS](https://reader031.vdocuments.us/reader031/viewer/2022022412/58f176e21a28abee388b457f/html5/thumbnails/3.jpg)
Android Frame Rendering Deep Dive
![Page 4: The Road to 60 FPS](https://reader031.vdocuments.us/reader031/viewer/2022022412/58f176e21a28abee388b457f/html5/thumbnails/4.jpg)
What happens on the UI thread?
VSync
Input
Animation
Draw
Frame 1 Frame 2 Frame 3
Get used to this guy
![Page 5: The Road to 60 FPS](https://reader031.vdocuments.us/reader031/viewer/2022022412/58f176e21a28abee388b457f/html5/thumbnails/5.jpg)
60FPS is inaccurate
Galaxy Core 2 33fps
Nexus 5 60fps 55fps
Nexus 4 60fps 49fps
![Page 6: The Road to 60 FPS](https://reader031.vdocuments.us/reader031/viewer/2022022412/58f176e21a28abee388b457f/html5/thumbnails/6.jpg)
How do you measure a skipped frame?
![Page 7: The Road to 60 FPS](https://reader031.vdocuments.us/reader031/viewer/2022022412/58f176e21a28abee388b457f/html5/thumbnails/7.jpg)
Choreographer
▪ FrameCallback
▪ Delivered during the next frame’s animation callback
▪ Measure the difference between two inputs
VSync
Input
Animation
Draw
17ms 17ms 17ms
![Page 8: The Road to 60 FPS](https://reader031.vdocuments.us/reader031/viewer/2022022412/58f176e21a28abee388b457f/html5/thumbnails/8.jpg)
Choreographer
VSync
Input
Animation
Draw
17ms 33ms 17ms
draw draw draw drop draw
17ms
![Page 9: The Road to 60 FPS](https://reader031.vdocuments.us/reader031/viewer/2022022412/58f176e21a28abee388b457f/html5/thumbnails/9.jpg)
public interface FrameCallback { /** * @param frameTimeNanos The time in nanoseconds when the frame started being rendered */ void doFrame(long frameTimeNanos); }
![Page 10: The Road to 60 FPS](https://reader031.vdocuments.us/reader031/viewer/2022022412/58f176e21a28abee388b457f/html5/thumbnails/10.jpg)
mFPSMeasuringCallback = new Choreographer.FrameCallback() { @Override public void doFrame(long frameTimeNanos) { long frameTimeMs = nsToMs(frameTimeNanos);
if (mLastFrameTimeMs == FIRST_FRAME) { mLastFrameTimeMs = frameTimeMs; mChoreographer.postFrameCallback(mFPSMeasuringCallback); return; }
long milliSecondDelay = frameTimeMs -‐ mLastFrameTimeMs; mLastFrameTimeMs = frameTimeMs; onFrameRendered(milliSecondDelay); mChoreographer.postFrameCallback(mFPSMeasuringCallback); } };
First frame!
Report time between frames Always post the callback
![Page 11: The Road to 60 FPS](https://reader031.vdocuments.us/reader031/viewer/2022022412/58f176e21a28abee388b457f/html5/thumbnails/11.jpg)
An FPS measuring API
public void enable() { mLastFrameTimeMs = FIRST_FRAME; mChoreographer.postFrameCallback(mFPSMeasuringCallback); }
public void disable() { mChoreographer.removeFrameCallback(mFPSMeasuringCallback); report(); }
![Page 12: The Road to 60 FPS](https://reader031.vdocuments.us/reader031/viewer/2022022412/58f176e21a28abee388b457f/html5/thumbnails/12.jpg)
A Reasonable Metric
![Page 13: The Road to 60 FPS](https://reader031.vdocuments.us/reader031/viewer/2022022412/58f176e21a28abee388b457f/html5/thumbnails/13.jpg)
Percent time spent dropping 2+ frames*
VSync
Input
Animation
Draw
0
<2 dropped frames = 6/11 = 55% 2+ dropped frames = 5/11 = 45%
4 dropped* 1 dropped 0 0 0 *rendered on the 5th frame
*…reasonable?
![Page 14: The Road to 60 FPS](https://reader031.vdocuments.us/reader031/viewer/2022022412/58f176e21a28abee388b457f/html5/thumbnails/14.jpg)
How does Facebook blame jank?
![Page 15: The Road to 60 FPS](https://reader031.vdocuments.us/reader031/viewer/2022022412/58f176e21a28abee388b457f/html5/thumbnails/15.jpg)
AutoBlame
▪ Must be lightweight
▪ High level
▪ Will not blame every slow frame
▪ Not perfect
VSync
Input
Animation
Draw
Expensive Work Marker
![Page 16: The Road to 60 FPS](https://reader031.vdocuments.us/reader031/viewer/2022022412/58f176e21a28abee388b457f/html5/thumbnails/16.jpg)
AutoBlame*
Year Class Slow time GC getView notifyDSC
2012 16% 6% 50% 16%
2014 22% 12% 44% 12%
*surprisingly accurate
![Page 17: The Road to 60 FPS](https://reader031.vdocuments.us/reader031/viewer/2022022412/58f176e21a28abee388b457f/html5/thumbnails/17.jpg)
AutoProfiler
VSync
Input
Animation
Draw
Expensive Work
![Page 18: The Road to 60 FPS](https://reader031.vdocuments.us/reader031/viewer/2022022412/58f176e21a28abee388b457f/html5/thumbnails/18.jpg)
AutoProfiler*
Method Time
com/android/widget/RecyclerView.onScrolled 16%
> com/facebook/logging/FeedLogger.onScroll 10%
> com/facebook/feed/NewsFeedFragment.maybeFetch 3.3%
>> com/facebook/feed/NewsFeedRecyclerView.notifyDataSetChange 3%
>> com/facebook/feed/FetchController.shouldFetch .3%
> com/facebook/prefetch/ImagePrefetcher.onScroll 2.7%
*totally made up shit
![Page 19: The Road to 60 FPS](https://reader031.vdocuments.us/reader031/viewer/2022022412/58f176e21a28abee388b457f/html5/thumbnails/19.jpg)
AutoProfiler
for i in range(20): time.sleep(1) device.drag((start_x, start_y), (stop_x, stop_y), 0.1, 15)
Traceview sample based profiling
MonkeyRunner Script
Left as an exercise to the developer Post-process Traceview file
![Page 20: The Road to 60 FPS](https://reader031.vdocuments.us/reader031/viewer/2022022412/58f176e21a28abee388b457f/html5/thumbnails/20.jpg)
Systrace
▪ Add your own markers
▪ Sample base profiling
VSync
Input
Animation
Draw
Expensive Work
Marker
![Page 21: The Road to 60 FPS](https://reader031.vdocuments.us/reader031/viewer/2022022412/58f176e21a28abee388b457f/html5/thumbnails/21.jpg)
How can I quickly improve performance?
▪ Ideal Profiling Device
▪ Nexus 4
▪ KitKat
▪ Systrace
▪ Custom markers for problem areas
▪ Sample based profiling
▪ Find an interaction or event which consistently causes lag or jitter and profile it
![Page 22: The Road to 60 FPS](https://reader031.vdocuments.us/reader031/viewer/2022022412/58f176e21a28abee388b457f/html5/thumbnails/22.jpg)
Questions? jsendros