SurfaceFlinger e WindowManager

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.