diff options
| author | 2023-05-17 21:29:46 +0000 | |
|---|---|---|
| committer | 2023-05-17 21:29:46 +0000 | |
| commit | 0f0d7b0309822efaa83f16a5a9fc7a070f94a3b5 (patch) | |
| tree | 55b24cf8b60485dd89041009d0c70757eb997e29 | |
| parent | 5796a17668e65625bd364ff917ecc52dcf1a5a75 (diff) | |
| parent | 6ba61eb54c70218394de22913baa55d610fb97a4 (diff) | |
Merge "[sf] Add readme for surfaceflinger frontend" into udc-dev
| -rw-r--r-- | services/surfaceflinger/FrontEnd/readme.md | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/services/surfaceflinger/FrontEnd/readme.md b/services/surfaceflinger/FrontEnd/readme.md new file mode 100644 index 0000000000..e5f51a5773 --- /dev/null +++ b/services/surfaceflinger/FrontEnd/readme.md @@ -0,0 +1,110 @@ +# SurfaceFlinger FrontEnd + +SurfaceFlinger FrontEnd implements the client APIs that describe how buffers should be +composited on the screen. Layers are used to capture how the buffer should be composited +and each buffer is associated with a Layer. Transactions contain an atomic set of changes +to one or more of these layers. The FrontEnd consumes these transactions, maintains the +layer lifecycle, and provides a snapshot to the composition engine every frame that +describes how a set of buffers should be composited. + + + +## Layers +Layers are used to describe how a buffer should be placed on the display relative to other +buffers. They are represented as a hierarchy, similar to a scene graph. Child layers can +inherit some properties from their parents, which allows higher-level system components to +maintain policies at different levels without needing to understand the entire hierarchy. +This allows control to be delegated to different parts of the system - such as SystemServer, +SysUI and Apps. + +### Layer Lifecycle +Layer is created by a client. The client receives a strong binder reference to the layer +handle, which will keep the layer alive as long as the client holds the reference. The +layer can also be kept alive if the layer has a parent, since the parent will hold a +strong reference to the children. If the layer is not reachable but its handle is alive, +the layer will be offscreen and its resources will not be freed. Clients must explicitly +release all references to the handle as soon as it's done with the layer. It's strongly +recommended to explicitly release the layer in Java and not rely on the GC. + + + +## Transactions +Transactions contain a group of changes to one or more layers that are applied together. +Transactions can be merged to apply a set of changes atomically. Merges are associative, +meaning how you group the merges does not matter, but they are not commutative, meaning +that the order in which you merge them does. +For example: + +`Transaction a; a.setAlpha(sc, 2);` + +`Transaction b; b.setAlpha(sc, 4);` + +`a.merge(b)` is not the same as `b.merge(a)` + +<p> + +`Transaction c; c.setAlpha(sc, 6);` + +`a.merge(b).merge(c)` is the same as `b.merge(c); a.merge(b);` + +Transactions are queued in SurfaceFlinger per ApplyToken so order is only guaranteed for +Transactions with the same applyToken. By default each process and each buffer producer +provides a unique ApplyToken. This prevents clients from affecting one another, and possibly +slowing each other down. + + + +## Architecture +SurfaceFlinger FrontEnd intends to optimize for predictability and performance because state +generation is on the hotpath. Simple buffer updates should be as fast as possible, and they +should be consistently fast. This means avoiding contention (e.g., locks) and context +switching. We also want to avoid doing anything that does not contribute to putting a pixel +on the display. + +The pipeline can be broken down into five stages: +- Queue and filter transactions that are ready to be committed. +- Handle layer lifecycles and update server-side state per layer. +- Generate and/or update the traversal trees. +- Generate a z-ordered list of snapshots. +- Emit callbacks back to clients + + +### TransactionHandler +TransactionHandler is responsible for queuing and filtering transactions that are ready to +be applied. On commit, we filter the transactions that are ready. We provide an interface +for other components to apply their own filter to determine if a transaction is ready to be +applied. + + +### LayerLifecycleManager +RequestedLayerState is a simple data class that stores the server side layer state. +Transactions are merged into this state, similar to how transactions can be merged on the +client side. The states can always be reconstructed from LayerCreationArgs and a list of +transactions. LayerLifecycleManager keeps track of Layer handle lifecycle and the layer +lifecycle itself. It consumes a list of transactions and generates a list of server side +states and change flags. Other components can register to listen to layer lifecycles. + + +### LayerHierarchyBuilder +LayerHierarchyBuilder consumes a list of RequestedLayerStates to generate a LayerHierarchy. +The hierarchy provides functions for breadth-first traversal and z-order traversal of the +entire tree or a subtree. Internally, the hierarchy is represented by a graph. Mirrored +layers are represented by the same node in the graph with multiple parents. This allows us +to implement mirroring without cloning Layers and maintaining complex hierarchies. + + +### LayerSnapshotBuilder +LayerSnapshotBuilder consumes a LayerHierarchy along with a list of RequestedLayerStates to +generate a flattened z-ordered list of LayerSnapshots. LayerSnapshots contain all the data +required for CompositionEngine and RenderEngine. It has no dependencies to FrontEnd, or the +LayerHierarchy used to create them. They can be cloned and consumed freely. Other consumers +like WindowInfo listeners (input and accessibility) also updated from these snapshots. + +Change flags are used to efficiently traverse this hierarchy where possible. This allows us +to support short circuiting parts of the hierarchy, partial hierarchy updates and fast paths +for buffer updates. + + +While they can be cloned, the current implementation moves the snapshot from FrontEnd to +CompositionEngine to avoid needless work in the hotpath. For snapshot consumers not critical +to composition, the goal is to clone the snapshots and consume them on a background thread. |