Developers
For Butter or WorseSmoothing Out Performance in Android UIs
Chet HaaseRomain GuyAndroid UI Toolkit Engineers
Developers
jank, noun
1. Choppy performance“Swiping the home screen feels janky”
2. Discontinuous, surprising experience“What's with the jank launching that app?”
butter, tasty noun
1. Smooth performance“Home screen swiping is very buttery”
2. Fattening spread and cooking ingredient“America’s obesity problem is directly proportional to the deliciousness of butter”
2. Discontinuous, surprising experience“What's with the jank launching that app?”
jank, noun
1. Choppy performance“Swiping the home screen feels janky”
Recipe
• Butter for eating is made from cream• Butter for Android is made from
- low latency- fast, consistent framerate
Latency
Event Display
Recipe
• Butter for eating is made from cream• Butter for Android is made from
- low latency- fast, consistent framerate
Latency
Event Display
Recipe
• Butter for eating is made from cream• Butter for Android is made from
- low latency- fast, consistent framerate
Latency
Event Display Event Display Event Display Event Display Event Display Event Display Event Display Event Display Event Display Event Display Event Display
Input Latency
Event
Event Queue
EventEvent
EventEvent
ProcessEvents Draw
Input Lag (What a drag)
Input Lag (What a drag)
Input Lag (What a drag)
Input Latency
a
a..c
bUser Input
Time
c d e f g h i j k l m n o p q r s t u v w x
Dispatcher
Activity Proc a..c Draw
d...j
Proc d..j Draw
k..s
Input Latency
a
a..c
bUser Input
Time
c d e f g h i j k l m n o p q r s t u v w x
Dispatcher
Activity Proc a..c Draw
d...j
Proc d..j Draw
k..s
Latency
a
d
c
j
Event Streaming
a bUser Input
Time
c d e f g h i j k l m n o p q r s t u v w x
Activity Proc a..f Draw Proc g..o Draw
VSync VSync
Event Streaming
a bUser Input
Time
c d e f g h i j k l m n o p q r s t u v w x
Activity Proc a..f Draw Proc g..o Draw
VSync VSync
Latency
a
g
f
o
Framerate
Drawing
Drawing faster is a good start
Framerate
Drawing
Drawing faster is a good start
Framerate
But that's not quite all there is to it...
Drawing
Drawing faster is a good start
Drawing: The Big Picture
Event Set PropertyValue Invalidate
Measure & Layout
PrepareDraw
UpdateDisplayList
DrawDisplayList
SwapBuffers
CompositeWindows
PostBuffer
DisplayList
DequeueBuffer
EnqueueBuffer
ActivitySurfaceFlinger
SomethingHappens Draw
Display
ActivitySurfaceFlinger
SomethingHappens Draw DisplaySomethingHappens Draw Display
Event Set PropertyValue Invalidate
SomethingHappens Draw DisplaySomethingHappens Draw Display
Measure & Layout
SomethingHappens Draw DisplaySomethingHappens Draw Display
Measure & Layout
PrepareDraw
DequeueBuffer
SomethingHappens Draw DisplaySomethingHappens Draw Display
Measure & Layout
PrepareDraw
UpdateDisplayList
DisplayList
DequeueBuffer
SomethingHappens Draw DisplaySomethingHappens Draw Display
Measure & Layout
PrepareDraw
UpdateDisplayList
DrawDisplayList
DisplayList
DequeueBuffer
SomethingHappens Draw DisplaySomethingHappens Draw Display
Measure & Layout
PrepareDraw
UpdateDisplayList
DrawDisplayList
SwapBuffers
DisplayList
DequeueBuffer
EnqueueBuffer
SomethingHappens Draw DisplaySomethingHappens Draw Display
CompositeWindows
PostBuffer
SomethingHappens Draw DisplaySomethingHappens Draw Display
Event Set PropertyValue Invalidate
Measure & Layout
PrepareDraw
UpdateDisplayList
DrawDisplayList
SwapBuffers
CompositeWindows
PostBuffer
DisplayList
DequeueBuffer
EnqueueBuffer
ActivitySurfaceFlinger
VSyncSynchronizing rendering with the display refresh
60 fpsDisplays refresh at 60 Hz, allowing apps to render at 60fps
Tearing
Getting the Pixels to the Screen
Time
CPU GPU Visible
UpdateDisplayList
DrawDisplayList Display
Drawing without VSync
1
0
1
Time
Display 1 1 2
2
2
CPU
GPU
3
VSync VSync VSync VSync
3
3
4
4
Drawing without VSync
1
0
1
Time
Display 1 1 2
2
2
CPU
GPU
3
VSync VSync VSync VSync
3
3
4
4
Jank!
Drawing with VSync
1
0
1
Time
Display 1 2 3
2
2
CPU
GPU
4
VSync VSync VSync VSync
3
3
4
4
Drawing with DisplayLists
set property invalidateset property invalidate
set property invalidateset property invalidate Update
DisplayListDraw
DisplayList
DisplayList
VSync
Drawing with DisplayList Properties
set propertyset property
set propertyset property Draw
DisplayList
DisplayList
VSync
DLProps
DisplayList Properties
• Free with ViewPropertyAnimator• Or use ObjectAnimator with View properties
- alpha- translationX/Y- scaleX/Y- rotation/X/Y
0
1
2
3
Tim
e in
ms
Frame
With DisplayList Properties Without DisplayList Properties
Parallel Processing and Double Buffering
B
A
B
Time
Display
VSync
B A B
A
A
B
B
A
A
CPU
GPU
A
VSync VSync VSync
Parallel Processing and Double Buffering
B
A
B
Time
Display A B B
A
A
CPU
GPU
A
VSync VSync VSync VSync
Jank!
Jank!
Parallel Processing and Double BufferingTriple
B
A
B
Time
Display A B C
C
A
CPU
GPU C
A B
B
A
VSync VSync VSync VSync
Jank!
Window Composition
DrawDisplayList
SwapBuffers
CompositeWindows
PostBuffer
ActivitySurfaceFlinger
Window Composition
GPU
DrawDisplayList
SwapBuffers
CompositeWindows
PostBuffer
ActivitySurfaceFlinger
Buffer
Overlay
Overlay
OverlayFB
FB
FB
Overlay
android:sdk $ cd platform-tools/
android:platform-tools $ adb shell ⏎ dumpsys gfxinfo
Demo
0
3
6
9
12
15
Tim
e in
ms
Frames
Update display lists Process display lists Swap buffers
android:sdk $ cd tools/systrace
android:systrace $ ./systrace
Demo
Captures 5 seconds
Stand-alone HTML output
android:sdk $ cd platform-tools/
android:platform-tools $ adb shell ⏎ dumpsys SurfaceFlinger
Demo
type | ... | name ----------+ ... +------- OVERLAY | ... | com...SlowListActivity OVERLAY | ... | StatusBar OVERLAY | ... | NavigationBar
type | ... | name ----------+ ... +------- OVERLAY | ... | com...SlowListActivity OVERLAY | ... | StatusBar OVERLAY | ... | NavigationBar
✔✔✔
type | ... | name ----------+ ... +------ OVERLAY | ... | com...SlowListActivity FB | ... | PopupWindow:424d4cc8 FB | ... | StatusBar FB | ... | NavigationBar
type | ... | name ----------+ ... +------ OVERLAY | ... | com...SlowListActivity FB | ... | PopupWindow:424d4cc8 FB | ... | StatusBar FB | ... | NavigationBar
✔
✘✘
✘
Caveats
traceview
HierarchyViewer
https://github.com/romainguy/ViewServer
Tracer for OpenGL ES
Allocation Tracker
Tips & Tricks
✔ Consistent frame-rate
✔ Lower latency
✔ Faster display list drawing
✔ GPU-free window composition
✔ Faster display list updates
new
new
✔ Consistent frame-rate
public void bindView(View view, Context context, Cursor c) { BookViewHolder holder = (BookViewHolder) view.getTag(); String bookId = c.getString(mInternalIdIndex); holder.bookId = bookId; holder.sortTitle = c.getString(mSortTitleIndex);
final ShelvesActivity activity = mActivity; if (activity.getScrollState() == SCROLL_STATE_FLING || activity.isPendingCoversUpdate()) { holder.title.setCompoundDrawablesWithIntrinsicBounds( null, null, null, mDefaultCover); holder.queryCover = true; } else { holder.title.setCompoundDrawablesWithIntrinsicBounds( null, null, null, ImageUtilities.getCachedCover(bookId, mDefaultCover)); holder.queryCover = false; }
final CharArrayBuffer buffer = holder.buffer; c.copyStringToBuffer(mTitleIndex, buffer); final int size = buffer.sizeCopied; if (size != 0) { holder.title.setText(buffer.data, 0, size); } }
// Do less!
✔ Consistent frame-rate
✔ Lower latency
android.view.Choreographer
// Invalidates at the next v-sync eventmyView.postInvalidateOnAnimation();
callback = new Runnable() { public void run() { setupAndStartAnimation(); }}
myView.postOnAnimation(callback);
callback = new Choreographer.FrameCallback() { public void doFrame(long frameTime) { render(frameTime); }};
Choreographer c = Choreographer.getInstance();c.postFrameCallback(callback);
✔ Consistent frame-rate
✔ Lower latency
view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
view.animate().alpha(0).withLayer();
✔ Consistent frame-rate
✔ Faster display list drawing
✂
CLIP PING
view.invalidate();
view.invalidate(left, top, right, bottom);
DisplayList
DisplayList
DisplayList DisplayList
DisplayList DisplayListDisplayList DisplayList
DisplayList
DisplayList
DisplayList DisplayList
DisplayList DisplayListDisplayList DisplayList
invalidate()
DisplayList
DisplayList
DisplayList DisplayList
DisplayList DisplayListDisplayList DisplayList
invalidate()
Draw display lists
DisplayList
DisplayList
DisplayList DisplayList
DisplayList DisplayListDisplayList DisplayList
DisplayList
DisplayList
DisplayList
DisplayList DisplayList DisplayList
DisplayList
DisplayList
invalidate()
Draw display lists
DisplayList
DisplayList
DisplayList DisplayList
DisplayList DisplayListDisplayList DisplayList
DisplayList
DisplayList
DisplayList DisplayList
DisplayList DisplayListDisplayList DisplayList
invalidate(l, t, r, b)
DisplayList
DisplayList
DisplayList DisplayList
DisplayList DisplayListDisplayList DisplayList
invalidate(l, t, r, b)
Draw display lists
DisplayList
DisplayList
DisplayList DisplayList
DisplayList DisplayListDisplayList DisplayList
DisplayList
DisplayList
DisplayList
DisplayList
invalidate(l, t, r, b)
Draw display lists
✔ Faster display list drawing
Don’t draw invisible items
@Overridepublic void onDraw(Canvas c) { c.save(); if (stacked) { c.clipRect(headerLeft, headerTop, headerRight, headerBottom); } drawHeader(c); drawContent(c); c.restore();}
clipRect
clipRect
clipRect
✔ Faster display list drawing
private void drawContent(Canvas c) { for (Item item : itemsList) { if (!c.quickReject(item.l, item.t, item.r, item.b, Canvas.EdgeType.BW)) { item.draw(c); } }}
✔ Faster display list drawing
✔ Faster display list updates
Dim layer
getWindow().addFlags( WindowManager.LayoutParams.FLAG_DIM_BEHIND);
type | ... | name ----------+ ... +------ OVERLAY | ... | com...MyActivity FB | ... | DimAnimator FB | ... | StatusBar FB | ... | NavigationBar
type | ... | name ----------+ ... +------ OVERLAY | ... | com...MyActivity FB | ... | DimAnimator FB | ... | StatusBar FB | ... | NavigationBar
✔
✘✘
✘
getWindow().addFlags( WindowManager.LayoutParams.FLAG_DIM_BEHIND);
getWindow().addFlags( WindowManager.LayoutParams.FLAG_DIM_BEHIND);getWindow().setBackground( new ColorDrawable(0x7f000000));
✔ Faster display list drawing
✔ GPU-free window composition
Users love butter
Users love butterSpread the word
For More InformationGoogle I/O 2011
Parleys.comAccelerated Android RenderingVarious Android GUI performance talks
Q&A+Chet Haase+Romain Guy
@chethaase@romainguy
Developers