O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Manuseio de hot plug no Composer HAL

Os recursos de exibição (como modos de exibição e tipos de HDR compatíveis) podem mudar dinamicamente em dispositivos com monitores conectados externamente (via HDMI ou DisplayPort), como set-top-boxes da Android TV (STB) e over-the-top (OTT) dispositivos. Essa alteração pode ocorrer como resultado de um sinal HDMI hot plug, como quando o usuário alterna de um monitor para outro ou inicializa o dispositivo sem um monitor conectado. Do Android 12 em diante, foram feitas mudanças na estrutura para lidar com recursos de hot plugging e exibição dinâmica.

Esta página aborda como lidar com hot plugs de exibição e alterações nos recursos de exibição na implementação do Composer HAL. Além disso, ele discute como gerenciar o framebuffer associado e evitar condições de corrida nessas situações.

Atualizando recursos de exibição

Esta seção descreve como a estrutura do Android lida com as mudanças nos recursos de exibição iniciados pelo Composer HAL.

Antes Android pode lidar com mudanças nas capacidades de exibição corretamente, o OEM deve implementar Compositor HAL de tal forma que ele usa um onHotplug(display, connection=CONNECTED) para notificar o quadro de quaisquer alterações aos recursos de exibição. Depois de implementado, o Android lida com as alterações para exibir os recursos da seguinte maneira:

  1. Ao detectar uma mudança na capacidade de exibição, o quadro recebe um onHotplug(display, connection=CONNECTED) notificação.
  2. Ao receber a notificação, o quadro deixa cair seu estado de exibição e recria-lo com os novos recursos do HAL usando os getActiveConfig , getDisplayConfigs , getDisplayAttribute , getColorModes , getHdrCapabilities e getDisplayCapabilities métodos.
  3. Uma vez que o quadro recria um novo estado de exibição, ele envia a onDisplayChanged chamada de retorno para os aplicativos que estão escutando para tais eventos.

O quadro realoca os framebuffers no posterior onHotplug(display, connection=CONNECTED) eventos. Veja Gerenciando memória framebuffer para mais informações sobre como lidar com isso.

Lidando com cenários de conexão comuns

Esta seção cobre como lidar adequadamente com vários cenários de conexão em suas implementações quando o monitor principal está conectado e desconectado.

Tendo sido construído para dispositivos móveis, a estrutura do Android não tem suporte integrado para uma tela principal desconectada. Em vez disso, o HAL deve substituir a tela principal por uma tela de espaço reservado em suas interações com a estrutura, no caso de uma tela primária estar fisicamente desconectada.

Os seguintes cenários podem ocorrer em decodificadores e dongles de TV que possuem monitores conectados externamente que podem ser desconectados. Para implementar o suporte para esses cenários, use as informações da tabela abaixo:

Cenário Manuseio
Nenhum monitor conectado no momento da inicialização
  • Enviar onHotplug(display, connection=CONNECTED) sinal do HAL Composer ao quadro.
  • Substitua o estado de exibição físico dentro do Composer HAL por um estado de exibição de espaço reservado.

    Nota: Recomendamos que a exibição de espaço reservado tenha um único modo compatível com resolução de 1080x1920 e taxa de atualização de 60 Hz, já que este modo de exibição é compatível com a maioria dos aplicativos.

O monitor primário está fisicamente conectado
O monitor primário está fisicamente desconectado
  • Enviar outro onHotplug(display, connection=CONNECTED) evento do HAL Composer ao quadro.
  • Substitua o estado de exibição físico dentro do Composer HAL por um estado de exibição de espaço reservado. O display espaço reservado deve ter um único modo de exibição, de modo que o quadro envia o onDisplayChanged chamada de retorno para aplicativos (uma vez que o conjunto de modos suportados mudaram). Este modo de visualização única deve corresponder ao último modo ativo da exposição física antes da desconexão, de modo que os aplicativos não recebem eventos de alteração de configuração .

Gerenciando memória framebuffer

Quando uma exibição já ligado recebe um subsequente onHotplug(display, connection=CONNECTED) evento de notificação, o quadro reallocates os framebuffers associados com esta exposição. As implementações de dispositivos devem antecipar esse comportamento e gerenciar adequadamente a memória do framebuffer. Use as seguintes diretrizes em sua implementação:

  • Antes de enviar posterior onHotplug(display, connection=CONNECTED) eventos de notificação, certifique-se de libertar alças para os framebuffers para que o sistema pode corretamente desalocar-los, antes de realocar-los. Se a desalocação não for bem-sucedida, a realocação pode falhar devido à falta de memória.

  • Recomendamos alocar um pool de memória dedicado para os framebuffers que seja separado do resto do buffer de memória gráfica.

Isso é importante porque entre a desalocação e a realocação dos framebuffers, um processo de terceiros pode tentar alocar a memória gráfica. Se o mesmo pool de memória gráfica for usado pelo framebuffer e se a memória gráfica estiver cheia, o processo de terceiros pode ocupar a memória gráfica anteriormente alocada por um framebuffer, deixando memória insuficiente para a realocação do framebuffer (ou possivelmente fragmentando o espaço de memória) .

Usando IDs de configuração sequenciais para evitar condições de corrida

Condições de corrida pode surgir se o Composer HAL atualiza as configurações de exibição compatíveis simultaneamente com o quadro chamando setActiveConfig ou setActiveConfigWithConstraints . A solução é implementar o Composer HAL para usar IDs sequenciais e evitar esse problema.

Esta seção descreve como as condições de corrida podem ocorrer, seguidas por detalhes sobre como implementar o Composer HAL para que ele use IDs sequenciais para evitar tais condições.

Considere a seguinte sequência de eventos, quando novos IDs sequenciais NÃO são atribuídos às novas configurações de exibição, causando uma condição de corrida:

  1. Os IDs de configuração de exibição suportados são:

    • ID = 1, 1080x1920 60hz
    • ID = 2, 50Hz 1080x1920
  2. A estrutura chama setActiveConfig(display, config=1) .

  3. Ao mesmo tempo, o Composer HAL processa uma mudança nas configurações de exibição e atualiza seu estado interno para um novo conjunto de configurações de exibição, mostrado a seguir:

    • ID = 1, 2160x3840 60hz
    • ID = 2, 50Hz 2160x3840
    • ID = 3, 60Hz 1080x1920
    • ID = 4, 50Hz 1080x1920
  4. Compositor HAL envia um onHotplug evento ao quadro, para notificar que o conjunto de modos suportados mudou.

  5. O HAL compositor recebe setActiveConfig(display, config=1) (a partir do passo 2).

  6. Os interpreta HAL que o quadro tenha solicitado uma mudança de configuração para 2160x3840 60Hz, embora na realidade 1080x1920 60Hz foi desejado.

O processo que usa atribuições de ID não sequenciais termina aqui com uma interpretação incorreta da alteração de configuração desejada.

Configurando o Composer HAL para usar IDs sequenciais

Para evitar tais condições de corrida, o OEM deve implementar o Composer HAL da seguinte forma:

  • Quando o Composer HAL atualiza as configurações de exibição suportadas, ele atribui novos IDs sequenciais às novas configurações de exibição.
  • Quando a estrutura chama setActiveConfig ou setActiveConfigWithConstraints com um ID de configuração inválido, o compositor HAL ignora a chamada.

Essas etapas servem para evitar condições de corrida, conforme mostrado na discussão a seguir.

Considere a seguinte sequência de eventos, quando novos IDs sequenciais são atribuídos às novas configurações de exibição:

  1. Os IDs de configuração de exibição suportados são:

    • ID = 1, 1080x1920 60hz
    • ID = 2, 50Hz 1080x1920
  2. A estrutura chama setActiveConfig(display, config=1) .

  3. Quando uma mudança nas configurações de exibição é processada, o próximo conjunto de IDs de configuração é atribuído a partir do próximo número inteiro não usado, mostrado a seguir:

    • ID = 3, 60Hz 2160x3840

    • ID = 4, 50Hz 2160x3840

    • ID = 5, 60Hz 1080x1920

    • ID = 6, 50Hz 1080x1920

  4. O HAL Compositor envia um onHotplug evento ao quadro, para notificar que o conjunto de modos suportados mudou.

  5. O HAL compositor recebe setActiveConfig(display, config=1) (a partir do passo 2).

  6. O Composer HAL ignora a chamada porque o ID não é mais válido.

  7. A estrutura recebe e processa a onHotplug evento a partir do passo 4. Ele chama o HAL Composer utilizando as funções getDisplayConfigs e getDisplayAttribute . Com essas funções, a estrutura identifica o novo ID (5) para a resolução desejada e a taxa de atualização de 1080x1920 e 60Hz.

  8. O quadro envia outro setActiveConfig evento com uma identificação atualizada de 5.

  9. O HAL compositor recebe setActiveConfig(display, config=5) a partir do passo 5.

  10. O HAL interpreta corretamente que a estrutura solicitou uma alteração de configuração para 1080x1920 60hz.

Conforme mostrado no exemplo acima, o processo usando atribuições de ID sequenciais garante que a condição de corrida seja evitada e a alteração correta da configuração do display seja atualizada.