Upgrade to Pro — share decks privately, control downloads, hide ads and more …

View To Pixel 2.0 (Droidcon SF 17')

Britt Barak
November 05, 2017

View To Pixel 2.0 (Droidcon SF 17')

On what's going on in the Android system when it created pixels on the screen, out of the Views that we write in code.

Also here: https://docs.google.com/presentation/d/1__ezgkz5DzFWxHGy4p0wx5NLr96aML5_asskM6OsEJM/present#slide=id.g299bece29b_1_927

Presented in Droidcon SF 2017.

Britt Barak

November 05, 2017
Tweet

More Decks by Britt Barak

Other Decks in Technology

Transcript

  1. • Knows all surfaces • Only service that can modify

    display’s content SurfaceFlinger
  2. Main Thread (UI Thread) Looper Message queue Handler1 Handle MSG

    Send MSG Process Handler2 Handle MSG Send MSG
  3. Choreographer.java private final class FrameHandler extends Handler { @Override public

    void handleMessage(Message msg) { switch (msg.what) { case MSG_DO_FRAME: doFrame(System.nanoTime(), 0); break; case MSG_DO_SCHEDULE_VSYNC: doScheduleVsync(); break; case MSG_DO_SCHEDULE_CALLBACK: doScheduleCallback(msg.arg1); break; } } }
  4. 1. Order is guaranteed. 2. Steps happen up to once

    Choreographer.java void doFrame(long frameTimeNanos, int frame) { //... doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos); doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos); doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos); doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos); //…
  5. Choreographer.java void doCallbacks(int callbackType, long frameTimeNanos) { callbacks = mCallbackQueues[callbackType]

    .extractDueCallbacksLocked(now / TimeUtils.NANOS_PER_MS); for (CallbackRecord c = callbacks; c != null; c = c.next) { //… c.run(frameTimeNanos);
  6. What can we do? • Flatten hierarchy • <Merge> on

    <include> • Avoid when near the hierarchy top • Avoid when many layouts • Minimize requestLayout() • ConstrainLayout
  7. //Step 1: draw background drawBackground(canvas); // Step 2, save the

    canvas' layers (prepare Fading, optional) canvas.saveLayer(…) //Step 3, draw view's content onDraw(canvas); public void draw(Canvas canvas) {
  8. // Step 4, draw children dispatchDraw(canvas); // Step 5, draw

    the fade effect and restore layers (optional) final Shader fade = scrollabilityCache.shader; paint.setShader(fade); canvas.drawRect(left, top, right, top , paint); public void draw(Canvas canvas) {
  9. // Step 6, draw decorations (foreground, scrollbars) onDrawForeground(canvas); // Step

    7, draw the default focus highlight drawDefaultFocusHighlight(canvas); public void draw(Canvas canvas) {
  10. public void draw(Canvas canvas) { //... // Step 4, draw

    children dispatchDraw(canvas); // Step 5, draw the fade effect and restore layers (optional) final Shader fade = scrollabilityCache.shader; paint.setShader(fade); canvas.drawRect(left, top, right, top , paint);
  11. 5. Transfer How to transfer color to destination Bitmap paint.setXfermode()

    Source Image Destination Image Transfer Mode Defaults to : PorterDuffXferMode (SRC_OVER) https://developer.android.com/reference/android/graphics/PorterDuffXfermode.html
  12. GPU Profiling Tool • A graph per visible app •

    A bar per frame • 16ms benchmark • Crossing = skipping frame https://developer.android.com/studio/profile/dev-options-rendering.html
  13. Frame Metrics On Android N+ - Per-Frame data: - Window.OnFrameMetricsAvailableListener()

    - Aggregated data: - FrameMetricsAggregator (Support lib v26) https://developer.android.com/reference/android/view/FrameMetrics.html