Taxa de atualização múltipla

O Android 11 adiciona suporte para dispositivos com múltiplas taxas de atualização. Existem três componentes principais para esse recurso:

  • Novas APIs HAL introduzidas em android.hardware.graphics.composer@2.4 .
  • Código da plataforma para analisar configurações de dispositivos para diferentes taxas de atualização e definir a taxa de atualização desejada
  • Novas APIs SDK e NDK para permitir que os aplicativos definam a taxa de quadros desejada

Implementação

Suporte dedicado para troca de taxa de atualização foi adicionado a android.hardware.graphics.composer@2.4 HAL . Recomendamos fortemente o uso desta versão, pois as versões anteriores do compositor HAL têm suporte limitado para troca de taxa de atualização.

Grupos de configuração

Um novo atributo CONFIG_GROUP foi adicionado a IComposerClient::Attribute que pode ser consultado usando a API getDisplayAttribute_2_4 . Este atributo permite que os fornecedores agrupem configurações de exibição. As configurações no mesmo grupo permitem alternar perfeitamente entre elas na maioria dos casos. O grupo de configuração é usado pela plataforma para diferenciar quais configurações podem ser alternadas entre elas para alternar a taxa de atualização e não outros atributos de uma configuração.

Considere o exemplo a seguir que demonstra os benefícios do uso de grupos de configuração com um dispositivo que oferece suporte a quatro configurações de exibição:

  • 1080p@60Hz
  • 1080p@90Hz
  • 1080i@72Hz
  • 1080i@48Hz

Embora o dispositivo suporte taxas de atualização de 48 Hz, 60 Hz, 72 Hz e 90 Hz, a tela opera em um modo diferente e mudar de 60 Hz para 72 Hz altera a configuração da tela de 1080p para 1080i, o que pode não ser o comportamento desejado. Isso é resolvido usando grupos de configuração. Agrupando 60 Hz e 90 Hz em um grupo de configuração e 48 Hz e 72 Hz em outro grupo de configuração. A plataforma sabe que pode alternar entre 60 Hz e 90 Hz e entre 48 Hz e 72 Hz, mas não entre 60 Hz e 72 Hz, pois isso resultará em uma alteração de configuração em vez de simplesmente alterar a taxa de atualização.

Atualizações da API do compositor

getDisplayVsyncPeriod
Para melhor controle e previsibilidade ao alterar as taxas de atualização, foi adicionado getDisplayVsyncPeriod . getDisplayVsyncPeriod retorna a taxa de atualização atual (em termos de período vsync) em que o display opera. Isso é especialmente útil durante a transição entre a taxa de atualização e a taxa de atualização atual, necessária para que a plataforma decida quando iniciar o próximo quadro.
setActiveConfigWithConstraints
O método setActiveConfigWithConstraints é uma nova extensão do método setActiveConfig existente e fornece mais informações sobre a alteração da configuração. As restrições são fornecidas como parte dos parâmetros vsyncPeriodChangeConstraints e contêm os parâmetros a seguir.
    desejadoTimeNanos
    O tempo em CLOCK_MONOTONIC após o qual o período vsync pode mudar (ou seja, o período vsync não deve mudar antes desse horário). Isso é útil quando a plataforma deseja planejar com antecedência uma alteração na taxa de atualização, mas já possui alguns buffers na fila para apresentar. A plataforma define esse tempo de acordo para levar em conta esses buffers e garantir que a transição da taxa de atualização seja a mais suave possível.
    perfeitoObrigatório
    Se for verdade, exige que a alteração do período vsync ocorra perfeitamente, sem um artefato visual perceptível. Este sinalizador é usado pela plataforma quando uma alteração na taxa de atualização é necessária como resultado de uma alteração de conteúdo (por exemplo, o dispositivo está ocioso e a animação é iniciada). Isso dá ao fornecedor a oportunidade de não permitir determinadas alterações de configuração quando elas podem resultar em um artefato visual perceptível. Se as configurações não puderem ser alteradas perfeitamente e seamlessRequired estiver definido como true , espera-se que a implementação retorne SEAMLESS_NOT_POSSIBLE como o código de retorno e chame o novo retorno de chamada onSeamlessPossible quando a mesma alteração de configuração puder ser feita perfeitamente.

Após o sucesso, a implementação retorna um VsyncPeriodChangeTimeline que informa à plataforma quando esperar que a alteração na taxa de atualização ocorra. Os parâmetros newVsyncAppliedTimeNanos precisam ser definidos para o horário em CLOCK_MONOTONIC quando a nova exibição começará a ser atualizada no novo período de vsync. Isso, junto com desiredTimeNanos permite que a plataforma planeje com antecedência a mudança da taxa de atualização e comece a marcar os aplicativos para a nova taxa de atualização com antecedência. Isso permite uma transição perfeita da taxa de atualização.

Algumas implementações exigem que um quadro de atualização seja enviado antes que a taxa de atualização possa ser enviada. Para isso, o HAL possui o parâmetro refreshRequired para indicar que um quadro de atualização é necessário e refreshTimeNanos para indicar o primeiro vsync para onde um quadro de atualização precisa ser enviado posteriormente.

onVsyncPeriodTimingChanged [retorno de chamada]
Um novo callback que pode ser chamado pelo HAL para indicar à plataforma que algum parâmetro da timeline mudou e a plataforma precisa ajustar sua timeline. Espera-se que esse retorno de chamada seja chamado se, por algum motivo, a linha do tempo antiga for perdida devido a um longo tempo de processamento no HAL ou a um quadro de atualização tardio.

Como a plataforma decide alterar a taxa de atualização?

A seleção da taxa de atualização ocorre nos dois serviços do sistema a seguir:

DisplayManager
O DisplayManager define a política de alto nível em torno da taxa de atualização. Ele define uma configuração de exibição padrão, que é igual à configuração HAL do compositor. Além disso, ele define um intervalo de valores mínimos e máximos para SurfaceFlinger escolher como taxa de atualização.
SurfaceFlinger
Determina a taxa de atualização definindo uma configuração que está no mesmo grupo de configurações da configuração padrão e com uma taxa de atualização dentro do intervalo mínimo/máximo.

O Display Manager executa as seguintes etapas para determinar a política:

  • Encontra o ID de configuração padrão consultando a configuração ativa do SurfaceFlinger
  • Restringindo o intervalo de valores mínimos e máximos iterando as condições do sistema
    • Configuração de taxa de atualização padrão : o valor da taxa de atualização padrão é definido na sobreposição de configuração R.integer.config_defaultRefreshRate . Este valor é usado para determinar a taxa de atualização padrão do dispositivo para animações e interações de toque.
    • Configuração da taxa de atualização de pico : O valor da taxa de atualização de pico é lido em Settings.System.PEAK_REFRESH_RATE . Este valor é alterado em tempo de execução para refletir a configuração atual do dispositivo (como em uma opção de menu). O valor padrão é definido na sobreposição de configuração R.integer.config_defaultPeakRefreshRate .
    • Configuração da taxa de atualização mínima : O valor da taxa de atualização mínima é lido em Settings.System.MIN_REFRESH_RATE . Este valor pode ser alterado em tempo de execução para refletir a configuração atual do dispositivo (como em uma opção de menu). O valor padrão é 0, portanto não há mínimo padrão.
    • ModeId solicitado pelo aplicativo : os aplicativos podem definir WindowManager.LayoutParams.preferredDisplayModeId para refletir uma configuração preferencial na qual a exibição deve operar. Na maioria das condições, o DisplayManager define o ID de configuração padrão de acordo e define a taxa de atualização mínima e máxima para corresponder à taxa de atualização da configuração.
    • Economia de bateria : A taxa de atualização é restrita a 60 Hz ou menos quando o dispositivo está no modo de baixo consumo de energia, o que é indicado em Settings.Global.LOW_POWER_MODE.

Depois que DisplayManager define a política, SurfaceFlinger define a taxa de atualização com base nas camadas ativas (camadas que enfileiram as atualizações do quadro). Se o proprietário da camada definir uma taxa de quadros , o SurfaceFlinger tentará definir a taxa de atualização para algo que seja um multiplicador dessa taxa. Por exemplo, se duas camadas ativas definirem sua taxa de quadros para 24 e 60, o SurfaceFlinger escolherá 120 Hz se estiver disponível. Se essa taxa de atualização não estiver disponível para o SurfaceFlinger, ele tentará escolher a taxa de atualização que apresenta o erro mínimo para a taxa de quadros. Para obter mais informações, consulte a documentação do desenvolvedor em developer.android.com

SurfaceFlinger mantém os seguintes sinalizadores para controlar como a taxa de atualização é decidida:

  • ro.surface_flinger.use_content_detection_for_refresh_rate: Se definida, a taxa de atualização é decidida com base nas camadas ativas, mesmo que uma taxa de quadros não tenha sido definida. SurfaceFlinger mantém uma heurística onde encontra o fps médio que a camada está postando buffers, observando o carimbo de data / hora da apresentação anexado ao buffer.
  • ro.surface_flinger.set_touch_timer_ms : se > 0, a taxa de atualização padrão será usada quando um usuário tocar na tela durante o tempo limite configurado. Essa heurística é feita para estar pronta com a taxa de atualização padrão para animações.
  • ro.surface_flinger.set_idle_timer_ms : se > 0, a taxa de atualização mínima será usada quando não houver atualizações de tela para o tempo limite configurado.
  • ro.surface_flinger.set_display_power_timer_ms : se > 0, a taxa de atualização padrão será usada ao ligar o display (ou ao sair do AOD) para o tempo limite configurado.

API de taxa de quadros

A API de taxa de quadros permite que os aplicativos informem a plataforma Android sobre a taxa de quadros pretendida e está disponível em aplicativos direcionados ao Android 11. Para saber mais sobre a API de taxa de quadros, consulte a documentação do desenvolvedor em developer.android.com .

Opções de desenvolvedor

Uma nova opção de desenvolvedor foi adicionada ao menu que alterna uma sobreposição na tela com a taxa de atualização atual. A nova opção está em Configurações > Sistema > Opções do desenvolvedor > Mostrar taxa de atualização.