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