The Road to 60 FPS
Jason Sendros
Why care?
Android Frame Rendering Deep Dive
What happens on the UI thread?
VSync
Input
Animation
Draw
Frame 1 Frame 2 Frame 3
Get used to this guy
60FPS is inaccurate
Galaxy Core 2
33fps
Nexus 5
60fps
55fps
Nexus 4
60fps
49fps
How do you measure a skipped frame?
Choreographer
▪  FrameCallback
▪  Delivered during the next
frame’s animation callback
▪  Measure the difference
between two inputs
VSync
Input
Animation
Draw
17ms 17ms17ms
Choreographer
VSync
Input
Animation
Draw
17ms 33ms17ms
draw draw drawdrop draw
17ms
public	
  interface	
  FrameCallback	
  {	
  
	
  	
  	
  	
  /**	
  
	
  	
  	
  	
  	
  *	
  @param	
  frameTimeNanos	
  The	
  time	
  in	
  nanoseconds	
  when	
  the	
  frame	
  started	
  being	
  rendered	
  
	
  	
  	
  	
  	
  */	
  
	
  	
  	
  	
  void	
  doFrame(long	
  frameTimeNanos);	
  
}	
  
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
An FPS measuring API
public	
  void	
  enable()	
  {	
  
	
  	
  	
  	
  mLastFrameTimeMs	
  =	
  FIRST_FRAME;	
  
	
  	
  	
  	
  mChoreographer.postFrameCallback(mFPSMeasuringCallback);	
  
}	
  
public	
  void	
  disable()	
  {	
  
	
  	
  	
  	
  mChoreographer.removeFrameCallback(mFPSMeasuringCallback);	
  
	
  	
  	
  	
  report();	
  
}	
  
A Reasonable Metric
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?
How does Facebook blame jank?
AutoBlame
▪  Must be lightweight
▪  High level
▪  Will not blame every slow frame
▪  Not perfect
VSync
Input
Animation
Draw
Expensive Work Marker
AutoBlame*
Year Class Slow time GC getView notifyDSC
2012 16% 6% 50% 16%
2014 22% 12% 44% 12%
*surprisingly accurate
AutoProfiler
VSync
Input
Animation
Draw
Expensive Work
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
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
Systrace
▪  Add your own markers
▪  Sample base profiling
VSync
Input
Animation
Draw
Expensive Work
Marker
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
Questions?
jsendros

The Road to 60 FPS

  • 1.
    The Road to60 FPS Jason Sendros
  • 2.
  • 3.
  • 4.
    What happens onthe UI thread? VSync Input Animation Draw Frame 1 Frame 2 Frame 3 Get used to this guy
  • 5.
    60FPS is inaccurate GalaxyCore 2 33fps Nexus 5 60fps 55fps Nexus 4 60fps 49fps
  • 6.
    How do youmeasure a skipped frame?
  • 7.
    Choreographer ▪  FrameCallback ▪  Deliveredduring the next frame’s animation callback ▪  Measure the difference between two inputs VSync Input Animation Draw 17ms 17ms17ms
  • 8.
  • 9.
    public  interface  FrameCallback  {          /**            *  @param  frameTimeNanos  The  time  in  nanoseconds  when  the  frame  started  being  rendered            */          void  doFrame(long  frameTimeNanos);   }  
  • 10.
    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
  • 11.
    An FPS measuringAPI public  void  enable()  {          mLastFrameTimeMs  =  FIRST_FRAME;          mChoreographer.postFrameCallback(mFPSMeasuringCallback);   }   public  void  disable()  {          mChoreographer.removeFrameCallback(mFPSMeasuringCallback);          report();   }  
  • 12.
  • 13.
    Percent time spentdropping 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?
  • 14.
    How does Facebookblame jank?
  • 15.
    AutoBlame ▪  Must belightweight ▪  High level ▪  Will not blame every slow frame ▪  Not perfect VSync Input Animation Draw Expensive Work Marker
  • 16.
    AutoBlame* Year Class Slowtime GC getView notifyDSC 2012 16% 6% 50% 16% 2014 22% 12% 44% 12% *surprisingly accurate
  • 17.
  • 18.
    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
  • 19.
    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
  • 20.
    Systrace ▪  Add yourown markers ▪  Sample base profiling VSync Input Animation Draw Expensive Work Marker
  • 21.
    How can Iquickly 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
  • 22.