O SurfaceFlinger aceita, compõe e envia buffers para a
tela. O WindowManager fornece ao SurfaceFlinger buffers e metadados de janela, que o SurfaceFlinger usa para compor superfícies na tela.
SurfaceFlinger
O SurfaceFlinger pode aceitar buffers de duas maneiras: pelo BufferQueue e
SurfaceControl ou pelo ASurfaceControl.
Uma maneira de o SurfaceFlinger aceitar buffers é usando BufferQueue e
SurfaceControl. Quando um app aparece em primeiro plano, ele solicita buffers de
WindowManager. Em seguida, o WindowManager solicita uma camada do
SurfaceFlinger. Uma camada é uma combinação de uma superfície, que contém a BufferQueue, e
uma instância SurfaceControl,
que contém os metadados da camada, como o frame de exibição.
O SurfaceFlinger cria a camada e a envia para WindowManager. WindowManager
e envia a superfície ao app, mas mantém a instância SurfaceControl para
manipular a aparência do app na tela.
O Android 10 adiciona ASurfaceControl, que é outra
maneira de o SurfaceFlinger aceitar buffers. O ASurfaceControl combina uma superfície e uma instância SurfaceControl em um pacote de transação que é enviado ao SurfaceFlinger. ASurfaceControl está associado a uma camada, que os apps
atualizam por instâncias ASurfaceTransaction. Os apps recebem informações sobre instâncias de
ASurfaceTransaction por callbacks que transmitem ASurfaceTransactionStats
com informações, como tempo de bloqueio, tempos de aquisição e assim por diante.
A tabela a seguir inclui mais detalhes sobre o ASurfaceControl e os componentes associados:
| Componente | Descrição |
|---|---|
ASurfaceControl |
Encapsula SurfaceControl e permite que um app crie instâncias de SurfaceControl que
correspondem a camadas na tela.Pode ser criado como filho de ANativeWindow ou de outra instância de ASurfaceControl. |
ASurfaceTransaction |
Encapsula Transaction para permitir que o cliente edite as propriedades descritivas
de uma camada, como geometria, e envia os buffers atualizados para
o SurfaceFlinger. |
ASurfaceTransactionStats
| Envia informações sobre transações apresentadas, como tempo de trava, tempos de aquisição e cerca de lançamento anterior, para um app por um callback pré-registrado. |
Embora os apps possam enviar buffers a qualquer momento, o SurfaceFlinger só é ativado para aceitar buffers entre as atualizações da tela, que podem variar dependendo do dispositivo. Isso minimiza o uso da memória e evita o tearing visível na tela, que pode ocorrer ao atualizar a tela no meio da atualização.
Quando a tela está entre atualizações, ela envia o sinal VSync para o SurfaceFlinger. O sinal VSync indica que a tela pode ser atualizada sem falhas. Quando o SurfaceFlinger recebe o sinal VSync, ele percorre a lista de camadas procurando novos buffers. Se o SurfaceFlinger encontrar um novo buffer, ele vai adquirir o buffer. Caso contrário, o SurfaceFlinger vai continuar usando o buffer adquirido anteriormente. O SurfaceFlinger precisa sempre mostrar algo, então ele se mantém em um buffer. Se nenhum buffer tiver sido enviado em uma camada, ela será ignorada.
Depois que o SurfaceFlinger coleta todos os buffers para camadas visíveis, ele pergunta ao Hardware Composer (HWC) como a composição deve ser realizada. Se o HWC marcar o tipo de composição da camada como composição do cliente, o SurfaceFlinger vai compor essas camadas. Em seguida, o SurfaceFlinger passa o buffer de saída para o HWC.
WindowManager
O WindowManager controla objetos Window, que são contêineres para objetos View. Os objetos Window sempre são apoiados por objetos
Surface.
WindowManager supervisiona ciclos de vida, eventos de entrada e foco, orientação da tela, transições, animações, posição, transformações, ordem Z e muitos outros aspectos de uma janela. O WindowManager envia todos os
metadados da janela para o SurfaceFlinger, para que ele possa usar esses dados para
compor superfícies na tela.
Pré-rotação
Muitas sobreposições de hardware não oferecem suporte à rotação. Mesmo que ofereçam, isso custa poder de processamento. A solução é transformar o buffer antes que ele chegue ao SurfaceFlinger. O Android oferece suporte a uma dica de consulta (NATIVE_WINDOW_TRANSFORM_HINT) em ANativeWindow para representar a transformação mais provável a ser aplicada ao buffer pelo SurfaceFlinger. Os drivers GL podem usar essa dica para pré-transformar o buffer
antes que ele chegue ao SurfaceFlinger. Assim, quando o buffer chegar, ele será transformado
corretamente.
Por exemplo, ao receber uma dica para girar 90 graus, gere e aplique uma matriz ao buffer para evitar que ele saia do fim da página. Para economizar energia, faça essa pré-rotação. Para mais detalhes, consulte a interface ANativeWindow
definida em system/core/include/system/window.h.