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: por BufferQueue e SurfaceControl ou por ASurfaceControl.
Uma maneira de o SurfaceFlinger aceitar buffers é por meio de BufferQueue e SurfaceControl. Quando um app aparece em primeiro plano, ele solicita buffers do WindowManager. O WindowManager solicita uma camada do SurfaceFlinger. Uma camada é uma combinação de uma superfície, que contém a BufferQueue, e um SurfaceControl, que contém os metadados da camada, como o frame de exibição. O SurfaceFlinger cria a camada e a envia para o WindowManager. O WindowManager envia a superfície para o app, mas mantém o SurfaceControl para manipular a aparência do app na tela.
O Android 10 adiciona o ASurfaceControl, que é outra maneira de o SurfaceFlinger aceitar buffers. ASurfaceControl combina uma superfície e um SurfaceControl em um pacote de transação que é enviado para SurfaceFlinger. Um ASurfaceControl é associado a uma camada que os apps atualizam usando ASurfaceTransactions. Os apps recebem informações sobre ASurfaceTransactions por meio de callbacks que transmitem ASurfaceTransactionStats com informações, como tempo de trava, 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 | Envolve o SurfaceControl e permite que um app crie SurfaceControls que
correspondem a camadas na tela. Pode ser criado como uma criança de ANativeWindow ou como uma criança de outro ASurfaceControl. |
ASurfaceTransaction | Envolve a transação para permitir que o cliente edite as propriedades descritivas de uma camada, como a geometria, e envia os buffers atualizados para o SurfaceFlinger. |
ASurfaceTransactionStats | Envia informações sobre transações que foram apresentadas, como tempo de trava, tempos de aquisição e cerca de lançamento anterior, para um app usando um callback pré-registrado. |
Embora os apps possam enviar buffers a qualquer momento, o SurfaceFlinger só é ativado para aceitar buffers entre as atualizações de exibição, que podem ser diferentes dependendo do dispositivo. Isso minimiza o uso de memória e evita a fragmentação visível na tela, que pode ocorrer ao atualizar a tela durante a atualização.
Quando a tela está entre as atualizações, ela envia o sinal VSYNC para o SurfaceFlinger. O sinal VSYNC indica que a tela pode ser atualizada sem rasgos. Quando o SurfaceFlinger recebe o sinal VSYNC, ele procura na lista de camadas em busca de novos buffers. Se o SurfaceFlinger encontrar um novo buffer, ele será adquirido. Caso contrário, o SurfaceFlinger continuará usando o buffer adquirido anteriormente. O SurfaceFlinger precisa sempre mostrar algo, então ele fica preso a 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 compositor de hardware (HWC) como a composição deve ser realizada. Se o HWC marcar o tipo de composição de camada como composição de cliente, o SurfaceFlinger vai compor essas camadas. Em seguida, o SurfaceFlinger transmite o buffer de saída para o HWC.
WindowManager
O WindowManager controla objetos janela, que são contêineres de objetos visualização. Os objetos de janela são sempre apoiados por objetos de superfície. O 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, que pode usar esses dados para compor superfícies na tela.
Pré-rotação
Muitas sobreposições de hardware não oferecem suporte à rotação (e, 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 sugestão 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 final da página. Para economizar
bateria, faça essa pré-rotação. Para saber mais, consulte a interface ANativeWindow
definida em system/core/include/system/window.h
.