Mecanismo VSYNC no Sistema de Exibição do Android 14

Fluxo Completo de Distribuição e Escuta do VSYNC

O VSYNC pode ser gerado pelo Hardware Composer (HWC) ou por software, com uma thread emitiendo sinais em intervalos regulares (por exemplo, a cada 16 milissegundos). Desvios são usados para permitir trabalho assíncrono entre SurfaceFlinger (SF) e aplicativos, implementando um pipeline em dois estágios.

Aplicativos solicitam VSYNC ao EventThread, indicando necessidade, e entram em dormência. Quando o EventThread recebe o sinal de hardware ou software, notifica o aplicativo, que inicia a renderização de uma nova interface. SF funciona de maneira similar, iniciando a composição após receber o sinal.

Se o tempo de renderização do aplicativo for longo, normalmente ele solicita o próximo VSYNC ao SF após concluir, garantindo que o conteúdo renderizado seja exibido no próximmo frame, mesmo que não se enquadre no atual.

Estruturas de Dados


// Exemplo simplificado de estruturas para VSYNC
struct SinalVSync {
    int64_t timestamp;
    int contador;
};

class GerenciadorEventos {
private:
    std::vector<conexao_ptr> conexoes;
    std::mutex trava;
public:
    void adicionarConexao(conexao_ptr con);
    void distribuirSinal(SinalVSync sinal);
};
</conexao_ptr>

Inicialização do VSYNC


// Inicialização principal
1. Criação do SurfaceFlinger (SF)
   - Em SurfaceFlinger.cpp: onFirstRef() inicializa a fila de mensagens.
   - MessageQueue.cpp: cria Looper e Handler.

2. SF->init()
   - Cria threads para app e SF usando DispSyncSource.
   - Exemplo: mFonteThreadApp = nova FonteDispSync(DispSync, "app");
   - Cria EventThread para gerenciar mudanças: mThreadEventos = nova EventThread(mFonteThreadApp.get(), "threadEventosApp");
   - Similar para SF: mFonteThreadSF = nova FonteDispSync(DispSync, "sf");
   - Estabelece conexões via MessageQueue.cpp, adicionando descritores de arquivo para comunicação com Looper.
   - Cria HWComposer para gerenciar VSYNC.

3. SF->run()
   - Loop principal: waitForEvent() aguarda sinais, usando mFilaEventos->esperarMensagem().

4. HWC vs. HWC2
   - HWC1 usado em versões anteriores ao Android 9; HWC2 nas versões recentes.
   - VSyncThread (para HWC1): thread dedicada para gerar VSYNC de software.
   - HwcVsync: cria thread via pthread_create para gerar sinais.

5. Inicialização do EventThread
   - Inicia thread com std::thread(&EventThread::principalThread, this).

Uso do VSYNC pelo SurfaceFlinger


1. Aplicativo notifica SF para atualização
   - Em BufferLayer.cpp: mCompositor->sinalizarAtualizacaoCamada();
   - MessageQueue.cpp: mFilaEventos->invalidar(); solicita próximo VSYNC.
   - EventThread.cpp: mThreadEventos->solicitarProximoVSync(this); acorda thread.
   - SF->run() chama waitForEvent(), que usa mLooper->pollOnce(-1) para aguardar.
   - Quando Looper dispara, callback cb_receptorEvento é chamado, levando a despacho de invalidação e tratamento em SurfaceFlinger.cpp.

2. Loop principal do EventThread
   - Em EventThread.cpp: threadPrincipal() aguarda eventos, distribuindo para conexões registradas.
   - Usa mCanal para enviar sinais via descritor de arquivo, acordando SF.

3. Loop do DispSync
   - DispSync.cpp: calcula próximo evento, coleta callbacks, e dispara notificações.
   - SurfaceFlinger.cpp recebe callbacks e acorda EventThread.

4. Recebimento de VSYNC do HWC
   - SurfaceFlinger::aoReceberVSync() é chamado quando HWC gera sinal.
   - HWComposer.cpp consulta VSYNC e atualiza modelo em DispSync, acordando thread.

Processamento de VSYNC pelo SurfaceFlinger

Transações Processadas

SF gerencia camadas (adição, atualização de conteúdo, mudanças de propriedades) e displays (adição ou remoção).

Estruturas de Dados Importantes


1. SurfaceFlinger
   - Contém estados: mCurrentEstado e mDesenhoEstado, cada um com vetores de camadas e estados de display.

2. DisplayDeviceState
   - Estrutura para estado do display, incluindo ID, tipo e superfície de buffer.

3. Camada
   - Classe com estado interno, como layerStack para identificar display associado.

Funções de Processamento Principais


1. Ponto de entrada: aoReceberMensagem() em SurfaceFlinger.cpp.
   - Sinaliza atualização de camada se frame perdido.
   - Processa transações, invalidações e refresh.

2. ProcessarTransacoes()
   - Coleta flags de transação, atualiza regiões visíveis, e comete mudanças.

3. ProcessarInvalidacao()
   - Prepara novos dados de buffer: camadas enfileiradas são verificadas, buffers travados e atualizados via consumidores de buffer.

4. SinalizarRefresh()
   - Envia mensagem de refresh para síntese final.

Introdução a Regiões

Em SurfaceFlinger, uma região representa uma área composta por retângulos (Rects), usada para otimizar síntese. Propriedades incluem opaca, transparente ou translúcida. Operações como interseção e subtração combinam retângulos.


// Exemplo de operações em regiões
enum Operacao {
    op_nand = operador_regiao<rect>::op_nand,
    op_and  = operador_regiao<rect>::op_and,
    op_or   = operador_regiao<rect>::op_or,
    op_xor  = operador_regiao<rect>::op_xor
};

class Regiao {
private:
    std::vector<rect> armazenamento;
public:
    Regiao intersecao(const Rect& rhs) const;
    Regiao subtrair(const Rect& rhs) const;
};
</rect></rect></rect></rect></rect>

T-Junctions são artefatos gráficos tratados por funções como criarRegiaoSemJuncaoT().

reconstruirPilhasCamadas

Esta função reconstrói a lista de camadas visíveis por display, determinando visibilidade e ordem para síntese. É acionada quando mRegioesSujas é definido devido a mudanças em camadas ou displays.


// Pseudo-código
reconstruirPilhasCamadas() {
    Regiao regiaoOpaca;
    Regiao regiaoSujas;
    for (display : displaysValidos) {
        computarRegioesVisiveis(display, regiaoSujas, regiaoOpaca);
        // Atualiza lista ordenada de camadas visíveis
        // Destroi camadas invisíveis se necessário
    }
    // Define regiões no display para uso posterior
}

O algoritmo percorre camadas de cima para baixo, calculando regiões visíveis, opacas, cobertas e sujas para otimizar a síntese, minimizando área de redenho.

Tags: Android 14 SurfaceFlinger VSYNC HWComposer Display

Publicado em 6-21 23:27