151
Layout & Animation Performance Britt Barak 13/6/2016 Wifi: GoogleGuestPSK pass: pUp3EkaP 3

Performance #3 layout&animation

Embed Size (px)

Citation preview

Layout & Animation Performance

Britt Barak13/6/2016

Wifi: GoogleGuestPSKpass: pUp3EkaP

3

First,

Britt Barak

Britt Barak

3

●Real - Android Team Leader

●Android Academy TLV

Yonatan Levin

Android Evangelist Gett

Idan FelixSenior Android &

Redhead Varonis

Jonathan Yarkoni

Android Developer & Advocate Ironsource

Android Academy Staff

Britt Barak

Android LeadReal

Muiriel Felix

Android Design

Logistics

https://www.facebook.com/groups/android.academy.ils/

What’s next?

4/7 - Yonatan- Networking, JSON, Batching, Location

10/8 - Felix- Battery & CPU

14/9 - Britt- Threading

30 / 10 / 2016New course coming

Today Will Be Awesome!- Go deep- Get practical- Important tips- Cool tools- Learn brand new stuff!

Motivation

Smooth Experience

How Is Motion Perceived?

How Is Motion Perceived?

SmoothMotion

60

No Difference

60+

Flip Book

12

Movies

Frames Per Second

Fluid Motion

24+effects

We Have A Winner!

SmoothMotion

60

No Difference

60+

Flip Book

12

Movies

Frames Per Second

Fluid Motion

24+effects

SmoothMotion

60

Colt McAnlis: https://youtu.be/CaMTIgxCSqU

60 FPS

60 Frames / Second = Frame / 16.666 Millisecond

But First Thing FirstBut First Thing FirstBut First Thing

First

How Did My Code Became Pixels?

Screen

CPU

new Button()

Scary Word Alert!!

Rasterization

From a high level object into pixels on screen (or in

texture).

https://en.wikipedia.org/wiki/Rasterisation

GPU - For The Rescue !

GPU - For The Rescue!

Screen

CPU

new Button()

GPU

Rasterization

GPU - For The Rescue!

Screen

CPU

new Button()

GPUPolygons Texture

s

Polygons Texture

sRasterization

Wait… Polygons and Textures…?

GPUPolygons Texture

s

Wait… What….?

Screen

CPU

new Button()

DisplayList

Wait… what….?

Screen

GPUPolygons Texture

s

CPU

new Button()

DisplayList

Optimizing- Reduce # object conversions- Reduce # uploading to GPU

By The Way...

By The Way...(Geek Alert)

By The Way...

For this simple button:

By The Way...

This is the Display List:

By The Way...

These are the OpenGl Commands:

Any Questions?

Reminder - GPU Profiling Tool

GPU Profiling Tool

GPU Profiling● A graph per visible app● A bar per frame● Render time corresponds height● 16 millis benchmark (green)● Crossing = skipping frame

https://developer.android.com/studio/profile/dev-options-rendering.html

16ms line

Dropped Frames :(

14

accented if >16ms

Shiney colors!

GPU Monitor (Android Studio)

VSync/Misc

Input

Animation

Measure/ Layout

Draw

Sync & Upload

Command Issue

Swap Buffers

So What Does That Mean?

Vsync / Misc Time

Misc = (vsync timestamp) - (timestamp when received) → work on the UI thread between two consecutive frames

● Choreographer log : “Missed vsync by XX ms skipping XX frames”

High? move work off UI ThreadVSync/Misc

Input

Animation

Measure/Layout

Draw

Sync & Upload

Command Issue

Swap Buffers

Input Handling

App code inside an input event callback.

High? optimize/offload processing input

VSync/Misc

Input

Animation

Measure/Layout

Draw

Sync & Upload

Command Issue

Swap Buffers

Animation

Evaluate all running animatorsOften : object animator, view property animator, and transitions

High?(2milis+) check custom animators / unintended work

VSync/Misc

Input

Animation

Measure/Layout

Draw

Sync & Upload

Command Issue

Swap Buffers

Measure / Layout

Executing layout and measure callbacks for needed view.

More on that in a few slides :)

VSync/Misc

Input

Animation

Measure/Layout

Draw

Sync & Upload

Command Issue

Swap Buffers

Draw

update (/creates) all display lists+cache.

High?

complex onDraw() logicmany views invalidated

VSync/Misc

Input

Animation

Measure/Layout

Draw

Sync & Upload

Command Issue

Swap Buffers

Sync & Upload

Upload bitmap to the GPU. High?

Too many imagesToo big of an image

VSync/Misc

Input

Animation

Measure/Layout

Draw

Sync & Upload

Command Issue

Swap Buffers

Command Issue

Execution: Android's 2D renderer issuing commands to OpenGL to draw and redraw all display lists

High?●Complex view (custom?)●Many views redrawing:

○Invalidation○animationVSync/

Misc

Input

Animation

Measure/Layout

Draw

Sync & Upload

Command Issue

Swap Buffers

Swap Buffers

CPU done rendering and wait for GPU ack.

High?

A lot of GPU work

VSync/Misc

Input

Animation

Measure/Layout

Draw

Sync & Upload

Command Issue

Swap Buffers

TOD

AY

VSync/Misc

Input

Animation

Measure/ Layout

Draw

Sync & Upload

Command Issue

Swap Buffers

So What Does That Mean?

Prev

. ta

lk

Any Questions?

So Let The Fun Begin :)

Reminder

Measure Layout Draw!

Step 1: Measure

Goal: obtain view size

REF: http://developer.android.com/reference/android/view/View.html#onMeasure(int, int)

Step 1: Measure

Goal: obtain view size, including its descendants size

REF: http://developer.android.com/reference/android/view/View.html#onMeasure(int, int)

Step 1: Measure

Goal: obtain view size, including its descendants size, agreed by its parent.

REF: http://developer.android.com/reference/android/view/View.html#onMeasure(int, int)

Step 1: Measure - What’s View SIZE?

- width & height (aka: drawing width & drawing height) - - Actual size on screen, at drawing time and after layout.

REF: http://developer.android.com/reference/android/view/View.html#onMeasure(int, int)

Step 1: Measure - What’s View SIZE?

- width & height (aka: drawing width and drawing height)

- the actual size of the view on screen, at drawing time and after layout.

- measured width & measured height- how big a view wants to be within its parent

REF: http://developer.android.com/reference/android/view/View.html#onMeasure(int, int)

Step 1: Measure - What’s View SIZE?

- Including Padding- Excluding Margins

- (supported by view groups: ViewGroupand ViewGroup.MarginLayoutParams )

REF: http://developer.android.com/reference/android/view/View.html#onMeasure(int, int)

ViewGroup.LayoutParams

How big the View wants to be For each dimension, it can specify one of:

an exact number

MATCH_PARENT

WRAP_CONTENT

*Might be subclassed, like in RelativeLayout

Multiple measure() Calls

measure() may be called more than onceFor example:

- Call once with UNSPECIFIED

- If size too big/small- evaluate- Call with exact size

Step 1: Measure - How Does It Work?

● measure(int, int) ○ → (calls onMeasure() which should be overridden)

● Set measuredWidth & measuredHeight○(can call super)

● Including for the View's descendants.

● respects parents’ constraints.

REF: http://developer.android.com/reference/android/view/View.html#onMeasure(int, int)

Step 1: Measure - Reminder

Goal: obtain view size, including its descendants size, agreed by its parent.

REF: http://developer.android.com/reference/android/view/View.html#onMeasure(int, int)

Any Questions?

The Steps

Measure Layout Draw!

Step 2: Layout

Goal : set position for view and all its children

REF: http://developer.android.com/reference/android/view/View.html#onLayout(boolean, int, int, int, int)

Step 2: Layout● layout(int, int, int, int)

○ → (calls onLayout() which should be overridden)

● Assign a size and position to a view and all of its descendants○(can call super)

● Including for the View object's descendants.

● respects parents’ constraints.

REF: http://developer.android.com/reference/android/view/View.html#onMeasure(int, int)

- View draws itself with size and position from previous steps.

- onDraw(Canvas) is called- Canvas object generates (or Updates) a list of

OpenGL-ES commands (displayList) to send to the GPU.

Step 3: Draw (AKA Update)

REF: http://developer.android.com/reference/android/view/View.html#onDraw(android.graphics.Canvas) Guide: http://developer.android.com/training/custom-views/custom-drawing.html

Plus ça change, plus c'est la même chose

When Things Change...

E.g. text, color, size, padding, margin...A view notifies the system, by calling:Invalidate - which will call the onDraw again, orrequestLayout - which will call the entire process again.

●Adds a flag●Recreate displaylist in next frame

invalidate()

requestLayout()

Bubble up to the root view. Heavy for deep view hierarchy.

Called once a frame.

When Do Request Layout?

View1 View2

When Do Request Layout?

View2View1

When Do Request Layout?

View2View1

So it seems that layout passes once... Or is it?

Root View : RelativeLayout

2 passes per change:1)By views’ requests

a)Then relativeLayout calculates by relations & weights

2)Determine the final positions for rendering.

Root View : RelativeLayout

Example:●Every view is RelativeLayout●Per Leaf change:

2*2*2 = 8 traversals

X2

X2

X2

Root View : LinearLayout

Generally issues 1 layout requestUnless:

●measureWithLargestChild(true)○Children with weights will have minimum size of largest child

●Nested weights

Root View : GridLayout

Allows relative positioning, while preprocessing the child view relationships.

Root View : GridLayout

Generally issues 1 layout requestUnless:

●Layout_gravity: fill*●Wrong weights

This is called

Double Layout Taxation

It Usually Works Fine… But...

●Root elements●Deep view hierarchy ●Too many (i.e. list)

Can hurt.

What can we do?●Flatten hierarchy :

Removing unneeded views

Merge on include

flatter layout

Beware double layout taxation

Minimize layout requests

Any Questions?

Cool Tool

Hierarchy Viewer

Hierarchy Viewer

Tools→ Android → Android Device Monitor → Hierarchy Viewer

Display complete view hierarchy

Access to all the views’ propertiesGet performance stats

Hierarchy Viewer

Hierarchy Viewer- Green dot : in the faster 50%

of all the View objects- Yellow : in the slower than 50%- Red: the slowest

- requestLayout:

Ok ok ,

but which layout should I choose??

Simple VS Complex Layouts●Simple : LinearLayout, FrameLayout, TableLayout

●Complex : RelativeLayout , GridLayout

Simple VS Complex Layouts●Simple : LinearLayout, FrameLayout, TableLayout

○→ Nesting → Performance Problems●Complex : RelativeLayout , GridLayout

○→ hard to use & maintain○→ shouldn’t be @ top hierarchy

Isn’t there anything smarter we can do??

Brand ew Alert!

Constraint Layout

Constraint Layout●Api 9+●Performance oriented:

○Reduce nesting

○Improve measure/layout

○Best practice : top level, without nesting layouts

User friendly:Expressive

New layout Editor!

The New Layout Editor

Android Studio 2.2 PreviewDesigned for ConstraintLayout - but not only!

Works with all layouts

Better with custom views (use View.isInEditMode())

More features : like editing menu resources….

Setting Up

1.Android Studio 2.2 Preview2.Android Support Repository (version 32+):3.Add the library on your build.gradle file:

dependencies {compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha3'

}

Concept

Similar to RelativeLayout : Position a view relative to other layout elements.

Yet more expressive & powerful

Getting Started

Drag a widget from Palette to the work space

Click a widget to see properties on the right

Getting Started

Design Mode

Blueprint Mode

Idea

View has 4 sides : left, top, right, bottom + baseline for textviewSo we can:

Connect view side to layoutConnect 2 view sidesAlign 2 view sidesAlign 2 textview baselines

Side Constraint Handle

Locate the view within the layout. app:layout_constraintRight_toRightOf="@+id/text_like_count"

Baseline Constraint Handle

align the baseline of multiple textviewsapp:layout_constraintBaseline_toBaselineOf="@+id/text_title"

Possible Attributes

layout_constraintX_toYOf X and Y can be replaced with:

a.Topb.Bottom c.Leftd.Righte.Startf. Endg.Baseline

Centering

constraints from both sides (ie top and bottom of view to top and bottom of layout)

And then...

Vertical Bias

Positioning relative to constrained position.app:layout_constraintVertical_bias="0.5"

Horizontal Bias

Positioning relative to constrained position.

app:layout_constraintHorizontal_bias="0.5"

Resize Handle

re-calculate the constraints that have been previously set

View Sizing

View Sizing : Any Size

match_parent and use the available space.

View Sizing :Wrap Content

as big as it needs to be.

View Sizing :Fixed Size

Autoconnect

Automatically creates constraints for a selected view Can enable/ disable at anytime.

Inference

Automatically create constraints for all of the views in your layout

Deleting Constraints

Single constraints - click the anchor point

All constraints for a viewbutton when view is selected

All constraints for layouticon on top bar

More View Properties

Properties Pane, on right hand side when clicking a view

Converting To ConstraintLayout

1.Open layout on editor2.right-click the layout → Convert <layout> to

ConstraintLayout.

Well, that about it!

Not officially released, but quite stable. Give it a try :)

https://codelabs.developers.google.com/codelabs/constraint-layout/index.html

Any Questions?

A bit about Animation

Reminder

Measure Layout Draw!Input Animate

Animation

Reminder : Changing a view property causes invalidation.

Same for animation, when changing the animated property (e.g. x coordinate, scale, alpha value etc.)

Animation

For complex views, animation may not be smooth.

What can we do?

View Layer - Hardware Acceleration

Render into an off-screen buffer (backed by Hardware)

Texture is created in the GPU for our viewChange properties without invalidatingSmoother animation

https://developer.android.com/guide/topics/graphics/hardware-accel.html#drawing-support

View Layer - Hardware Acceleration

Screen

GPUPolygons Texture

s

CPU

new Button()

DisplayList

Make Changes Here

Properties

alpha: Changes the layer's opacity

x, y, translationX, translationY: Changes the layer's position

scaleX, scaleY: Changes the layer's size

rotation, rotationX, rotationY: Changes the layer's orientation in 3D space

pivotX, pivotY: Changes the layer's transformations origin

// Using ObjectAnimatorview.setLayerType(View.LAYER_TYPE_HARDWARE, null);ObjectAnimator animator =

ObjectAnimator.ofFloat(view, "rotationY", 180);animator.addListener(new AnimatorListenerAdapter()

{ @Override public void onAnimationEnd(Animator animation)

{ view.setLayerType(View.LAYER_TYPE_NONE,

null); }});animator.start();

// Using Property animatorview.animate().rotationY(180f)

.withLayer()

.start();

Remember!

1.Clean up the space○hardware layers consume of GPU limited memory space

2.Invalidation on hardware layer has a large overhead.

Hardware Layers Updates Tool

Developer Options → Enable the “Show hardware layers updates” → Green flash when hardware layer updates

Any Questions?

Reminder

Measure Layout Draw!Input Animate

Order Is Guaranteed

What if we want the size during an

animation?

ViewTreeObserver

●Provided by the view hierarchy●Use to register listeners to view tree global

changes○For example: layout of the whole tree, beginning of the drawing,

touch mode change....

●Use with getViewTreeObserver()

https://developer.android.com/reference/android/view/ViewTreeObserver.html

onPreDrawListener

Tips During Animation

Don’t request measure / layoutBefore / After / Tree Observer

Don’t inflateexplicitly or implicitly by launching an activity

Animate properties that do not trigger layoutFor example: translationX and translationY and not LayoutParams

properties

Any Questions?

What Happened Here Today?

How Does A View Display On Screen?

Screen

GPUPolygons Texture

s

CPU

new Button()

DisplayList

What Happens Until Draw?

Measure Layout Draw!Input Animate

Talked About●Double Layout Taxation●Flatten hierarchy - why and how●Constraint layout●View tree observer●Hardware accelaration

Tools●GPU Profiling●Hierarchy Viewer●Hardware Layer Updates

Tips

1.measure() only during layout()2.No layout() during layout() 3.No layout / measure during animation4.No inflation during animation5.Minimize requestLayout()6.Invalidate regions when possible [rather than

whole view]

Tips

7. New allocations during traversal :On layout - ok-ish

On measure - avoid

On draw - no way! [called each frame!]

Tips

8. Animate without trigger layout9. Animate with hardware acceleration

Clean upDon’t invalidate on layer

LinksAndroid UI Performance:

● https://www.youtube.com/watch?v=CaMTIgxCSqU● https://www.youtube.com/watch?v=dB3_vgS-Uqo ● https://www.youtube.com/watch?v=WH9AFhgwmDw● https://www.youtube.com/watch?v=1iaHxmfZGGc● https://www.youtube.com/watch?v=we6poP0kw6E● https://youtu.be/erGJw8WDV74 ● https://medium.com/google-developers/developing-for-android-iii-2efc140167fd#.7lyadzb2a● http://blog.udinic.com/2015/09/15/speed-up-your-app● https://www.youtube.com/watch?v=sdkcuvZCh1U● https://medium.com/google-developers/developing-for-android-iii-2efc140167fd#.7lyadzb2a

How Android draws :● https://developer.android.com/guide/topics/ui/how-android-draws.html● https://blog.inovex.de/android-graphics-pipeline-from-button-to-framebuffer-part-1/● https://blog.inovex.de/android-graphics-pipeline-from-button-to-framebuffer-part-2/

LinksGPU Profiling:

● https://developer.android.com/studio/profile/dev-options-rendering.html ● https://youtu.be/VzYkVL1n4M8 ● https://developer.android.com/studio/profile/am-gpu.html

Hierarchy Viewer:● https://developer.android.com/studio/profile/optimize-ui.html● https://developer.android.com/studio/profile/hierarchy-viewer-walkthru.html

Constrain Layout:● https://www.youtube.com/watch?v=sO9aX87hq9c● http://tools.android.com/tech-docs/layout-editor● https://medium.com/exploring-android/exploring-the-new-android-constraintlayout-eed37fe8d8f1#.mzf

wdhxon● https://codelabs.developers.google.com/codelabs/constraint-layout/index.html

Will Post Notes Soon :)

Any Questions?

Thank You !