SurfaceFlinger e WindowManager

O SurfaceFlinger aceita, compõe e envia buffers para a tela. 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 é por meio de BufferQueue e SurfaceControl. Quando um app aparece em primeiro plano, ele solicita buffers do WindowManager. Em seguida, WindowManager solicita uma camada do SurfaceFlinger. Uma camada é uma combinação de uma superfície, que contém a BufferQueue, e uma instância de 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 envia a superfície para o 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. ASurfaceControl combina uma superfície e uma instância SurfaceControl em um pacote de transação que é enviado para SurfaceFlinger. ASurfaceControl está associado a uma camada que os apps atualizam por instâncias ASurfaceTransaction. Em seguida, os apps recebem informações sobre instâncias de ASurfaceTransaction por 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 ASurfaceControl e os componentes associados:

Componente Descrição
ASurfaceControl Envolve SurfaceControl e permite que um app crie instâncias de SurfaceControl que correspondem a camadas na tela.

Pode ser criado como uma criança de ANativeWindow ou como uma criança de outra instância de ASurfaceControl.
ASurfaceTransaction Envolve Transaction 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 da tela, que podem variar de acordo com o 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 de 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 do cliente, o SurfaceFlinger vai compor essas camadas. Em seguida, o SurfaceFlinger transmite o buffer de saída para o HWC.

WindowManager

WindowManager controla objetos Window, que são contêineres para objetos View. Os objetos Window são sempre apoiados por objetos Surface. 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. 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.