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.
A partir do Android 10, o ASurfaceControl oferece 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 o SurfaceFlinger recebe. 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 e de aquisição, por exemplo.
A tabela a seguir descreve ASurfaceControl e os componentes associados:
| Componente | Descrição |
|---|---|
ASurfaceControl |
Encapsula SurfaceControl e permite que um app crie instâncias SurfaceControl que
correspondem a camadas na tela.Pode ser criado como filho de ANativeWindow ou de outra instância 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 ele pode atualizar a tela sem tearing. Quando o SurfaceFlinger recebe o sinal VSync, ele percorre a lista de camadas procurando novos buffers. Se ele encontrar um novo buffer, o SurfaceFlinger vai adquiri-lo. Caso contrário, ele 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, o SurfaceFlinger vai ignorá-la.
Depois que o SurfaceFlinger coleta todos os buffers para camadas visíveis, ele pergunta ao Hardware Composer (HWC) como realizar a composição. 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 que o SurfaceFlinger vai aplicar ao buffer.
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.