1# SurfaceFlinger FrontEnd
2
3SurfaceFlinger FrontEnd implements the client APIs that describe how buffers should be
4composited on the screen. Layers are used to capture how the buffer should be composited
5and each buffer is associated with a Layer. Transactions contain an atomic set of changes
6to one or more of these layers. The FrontEnd consumes these transactions, maintains the
7layer lifecycle, and provides a snapshot to the composition engine every frame that
8describes how a set of buffers should be composited.
9
10
11
12## Layers
13Layers are used to describe how a buffer should be placed on the display relative to other
14buffers. They are represented as a hierarchy, similar to a scene graph. Child layers can
15inherit some properties from their parents, which allows higher-level system components to
16maintain policies at different levels without needing to understand the entire hierarchy.
17This allows control to be delegated to different parts of the system - such as SystemServer,
18SysUI and Apps.
19
20### Layer Lifecycle
21Layer is created by a client. The client receives a strong binder reference to the layer
22handle, which will keep the layer alive as long as the client holds the reference. The
23layer can also be kept alive if the layer has a parent, since the parent will hold a
24strong reference to the children. If the layer is not reachable but its handle is alive,
25the layer will be offscreen and its resources will not be freed. Clients must explicitly
26release all references to the handle as soon as it's done with the layer. It's strongly
27recommended to explicitly release the layer in Java and not rely on the GC.
28
29
30
31## Transactions
32Transactions contain a group of changes to one or more layers that are applied together.
33Transactions can be merged to apply a set of changes atomically. Merges are associative,
34meaning how you group the merges does not matter, but they are not commutative, meaning
35that the order in which you merge them does.
36For example:
37
38`Transaction a; a.setAlpha(sc, 2);`
39
40`Transaction b; b.setAlpha(sc, 4);`
41
42`a.merge(b)` is not the same as `b.merge(a)`
43
44<p>
45
46`Transaction c; c.setAlpha(sc, 6);`
47
48`a.merge(b).merge(c)` is the same as `b.merge(c); a.merge(b);`
49
50Transactions are queued in SurfaceFlinger per ApplyToken so order is only guaranteed for
51Transactions with the same applyToken. By default each process and each buffer producer
52provides a unique ApplyToken. This prevents clients from affecting one another, and possibly
53slowing each other down.
54
55
56
57## Architecture
58SurfaceFlinger FrontEnd intends to optimize for predictability and performance because state
59generation is on the hotpath. Simple buffer updates should be as fast as possible, and they
60should be consistently fast. This means avoiding contention (e.g., locks) and context
61switching. We also want to avoid doing anything that does not contribute to putting a pixel
62on the display.
63
64The pipeline can be broken down into five stages:
65- Queue and filter transactions that are ready to be committed.
66- Handle layer lifecycles and update server-side state per layer.
67- Generate and/or update the traversal trees.
68- Generate a z-ordered list of snapshots.
69- Emit callbacks back to clients
70
71
72### TransactionHandler
73TransactionHandler is responsible for queuing and filtering transactions that are ready to
74be applied. On commit, we filter the transactions that are ready. We provide an interface
75for other components to apply their own filter to determine if a transaction is ready to be
76applied.
77
78
79### LayerLifecycleManager
80RequestedLayerState is a simple data class that stores the server side layer state.
81Transactions are merged into this state, similar to how transactions can be merged on the
82client side. The states can always be reconstructed from LayerCreationArgs and a list of
83transactions. LayerLifecycleManager keeps track of Layer handle lifecycle and the layer
84lifecycle itself. It consumes a list of transactions and generates a list of server side
85states and change flags. Other components can register to listen to layer lifecycles.
86
87
88### LayerHierarchyBuilder
89LayerHierarchyBuilder consumes a list of RequestedLayerStates to generate a LayerHierarchy.
90The hierarchy provides functions for breadth-first traversal and z-order traversal of the
91entire tree or a subtree. Internally, the hierarchy is represented by a graph. Mirrored
92layers are represented by the same node in the graph with multiple parents. This allows us
93to implement mirroring without cloning Layers and maintaining complex hierarchies.
94
95
96### LayerSnapshotBuilder
97LayerSnapshotBuilder consumes a LayerHierarchy along with a list of RequestedLayerStates to
98generate a flattened z-ordered list of LayerSnapshots. LayerSnapshots contain all the data
99required for CompositionEngine and RenderEngine. It has no dependencies to FrontEnd, or the
100LayerHierarchy used to create them. They can be cloned and consumed freely. Other consumers
101like WindowInfo listeners (input and accessibility) also updated from these snapshots.
102
103Change flags are used to efficiently traverse this hierarchy where possible. This allows us
104to support short circuiting parts of the hierarchy, partial hierarchy updates and fast paths
105for buffer updates.
106
107
108While they can be cloned, the current implementation moves the snapshot from FrontEnd to
109CompositionEngine to avoid needless work in the hotpath. For snapshot consumers not critical
110to composition, the goal is to clone the snapshots and consume them on a background thread.
111