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: 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.