Drawing
Transcription
Drawing
Developers For Butter or Worse Smoothing Out Performance in Android UIs Chet Haase Romain Guy Android 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” jank, noun 1. Choppy performance “Swiping the home screen feels janky” 2. Discontinuous, surprising experience “What's with the jank launching that app?” 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 Event Event Event Event Queue Process Events Draw Input Lag (What a drag) Input Lag (What a drag) Input Lag (What a drag) Input Latency User Input Dispatcher Activity a b c d e f g h i j k l m n o p q r s d...j a..c Proc a..c t u v w x k..s Draw Time Proc d..j Draw Input Latency User Input Dispatcher Activity a b c d e f g h i j k l m n o p q r s d...j a..c Proc a..c k..s Draw Proc d..j a c Latency t u v w x d j Time Draw Event Streaming VSync User Input Activity a b c d e f g h VSync i j Proc a..f k l m n o p q r s Draw Time Proc g..o t u v w x Draw Event Streaming VSync User Input Activity a b c d e f g h VSync i j k Proc a..f l m n o p q r s Draw t u v w x Proc g..o a f Latency g o Time Draw Framerate Drawing faster is a good start Drawing Framerate Drawing faster is a good start Drawing Framerate Drawing faster is a good start Drawing But that's not quite all there is to it... Drawing: The Big Picture Set Property Value Event Measure & Layout Invalidate Prepare Draw Update DisplayList Display List Draw DisplayList Swap Buffers Activity SurfaceFlinger Dequeue Buffer Enqueue Buffer Composite Windows Post Buffer Something Happens Draw Activity SurfaceFlinger Display Something Happens Event Set Property Value Invalidate Draw Display Something Happens Measure & Layout Draw Display Something Happens Measure & Layout Prepare Draw Dequeue Buffer Draw Display Something Happens Display List Measure & Layout Prepare Draw Dequeue Buffer Update DisplayList Draw Display Something Happens Display List Measure & Layout Prepare Draw Dequeue Buffer Update DisplayList Draw DisplayList Draw Display Something Happens Draw Display List Measure & Layout Prepare Draw Dequeue Buffer Update DisplayList Draw DisplayList Swap Buffers Enqueue Buffer Display Something Happens Composite Windows Post Buffer Draw Display Something Happens Set Property Value Event Measure & Layout Invalidate Prepare Draw Update DisplayList Draw Display List Draw DisplayList Swap Buffers Activity SurfaceFlinger Dequeue Buffer Enqueue Buffer Composite Windows Post Buffer Display VSync Synchronizing rendering with the display refresh 60 fps Displays refresh at 60 Hz, allowing apps to render at 60fps Tearing Getting the Pixels to the Screen CPU Update DisplayList GPU Draw DisplayList Time Visible Display Drawing without VSync VSync Display 0 GPU CPU VSync 1 1 1 1 VSync 2 2 2 3 3 Time VSync 3 4 4 Drawing without VSync k! n Ja VSync Display 0 GPU CPU VSync 1 1 1 1 VSync 2 2 2 3 3 Time VSync 3 4 4 Drawing with VSync VSync Display 0 GPU 1 CPU 1 VSync VSync 1 2 2 VSync 2 3 3 4 3 Time 4 4 Drawing with DisplayLists Display List set property set property set property set property invalidate invalidate invalidate invalidate Update DisplayList VSync Draw DisplayList Drawing with DisplayList Properties DLProps Display List set property set property set property set property Draw DisplayList VSync DisplayList Properties • Free with ViewPropertyAnimator • Or use ObjectAnimator with View properties - alpha - translationX/Y - scaleX/Y - rotation/X/Y With DisplayList Properties Without DisplayList Properties 3 Time in ms 2 1 0 Frame Parallel Processing and Double Buffering Display A GPU CPU B B B A A A VSync VSync VSync VSync B B B Time A A A Parallel Processing and Double Buffering k! n Ja k! n Ja VSync Display A GPU CPU VSync VSync A B B B A B A Time VSync A Parallel Processing and Double Buffering e l p i r T k! n Ja VSync Display A GPU CPU VSync A B B B C C C A A Time VSync VSync A B B Window Composition Draw DisplayList Swap Buffers Activity SurfaceFlinger Composite Windows Post Buffer Window Composition Draw DisplayList Swap Buffers Activity SurfaceFlinger Composite Windows Overlay GPU Overlay Buffer FB Overlay FB Overlay FB Post Buffer android:sdk $ cd platform-tools/ android:platform-tools $ adb shell dumpsys gfxinfo Demo Update display lists Process display lists 15 Time in ms 12 9 6 3 0 Frames 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 | ----------+ OVERLAY | OVERLAY | OVERLAY | ... ... ... ... ... | name +------| com...SlowListActivity | StatusBar | NavigationBar ✔ ✔ ✔ type | ----------+ OVERLAY | OVERLAY | OVERLAY | ... ... ... ... ... | name +------| com...SlowListActivity | StatusBar | NavigationBar type | ----------+ OVERLAY | FB | FB | FB | ... ... ... ... ... ... | name +-----| com...SlowListActivity | PopupWindow:424d4cc8 | StatusBar | NavigationBar ✔ ✘ ✘ ✘ type | ----------+ OVERLAY | FB | FB | FB | ... ... ... ... ... ... | name +-----| com...SlowListActivity | PopupWindow:424d4cc8 | StatusBar | 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 Faster display list updates GPU-free window composition 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 event myView.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 DisplayList DisplayList DisplayList invalidate() DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList Draw display lists invalidate() DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList Draw display lists invalidate() DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList invalidate(l, t, r, b) DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList Draw display lists invalidate(l, t, r, b) DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList Draw display lists invalidate(l, t, r, b) DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList DisplayList ✔ Faster display list drawing Don’t draw invisible items @Override public 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 | ----------+ OVERLAY | FB | FB | FB | ... ... ... ... ... ... | name +-----| com...MyActivity | DimAnimator | StatusBar | NavigationBar ✔ ✘ ✘ ✘ type | ----------+ OVERLAY | FB | FB | FB | ... ... ... ... ... ... | name +-----| com...MyActivity | DimAnimator | StatusBar | 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 butter Spread the word For More Information Google I/O 2011 Parleys.com Accelerated Android Rendering Various Android GUI performance talks Q&A +Chet Haase +Romain Guy @chethaase @romainguy Developers