O Android 11 adiciona suporte a dispositivos com várias taxas de atualização. Esse recurso tem três componentes principais:
- Novas APIs HAL introduzidas no
android.hardware.graphics.composer@2.4. - Código da plataforma para analisar configurações de dispositivos com diferentes taxas de atualização e definir a taxa de atualização desejada
- Novas APIs de SDK e NDK para permitir que os apps definam o frame rate desejado
Implementação
Adicionamos suporte dedicado à troca de taxa de atualização em …Recomendamos usar essa versão porque as anteriores do HAL do compositor 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. Com esse atributo, os fornecedores podem agrupar configurações de exibição. As configurações no mesmo grupo permitem
alternar entre elas sem problemas na maioria dos casos. A plataforma usa o grupo de configuração para diferenciar quais configurações podem ser alternadas para mudar a taxa de atualização e não outros atributos de uma configuração.
Considere o exemplo a seguir, que demonstra os benefícios de usar grupos de configuração com um dispositivo que oferece suporte a quatro configurações de tela:
- 1080p a 60 Hz
- 1080p a 90 Hz
- 1080i a 72 Hz
- 1080i a 48 Hz
Embora o dispositivo seja compatível com taxas de atualização de 48 Hz, 60 Hz, 72 Hz e 90 Hz, a tela opera em um modo diferente. A troca de 60 Hz para 72 Hz muda a configuração da tela de 1080p para 1080i, o que pode não ser o comportamento desejado. Os grupos de configuração resolvem isso. Ao agrupar 60 Hz e 90 Hz em um grupo de configuração e 48 Hz e 72 Hz em outro, 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, porque isso resulta em uma mudança de configuração em vez de apenas alterar a taxa de atualização.
Atualizações da API Composer
- getDisplayVsyncPeriod
- Para melhorar o controle e a previsibilidade ao mudar as taxas de atualização, o
getDisplayVsyncPeriodfoi adicionado.getDisplayVsyncPeriodretorna a taxa de atualização atual (em termos de período de vsync) em que a tela opera. Isso é especialmente útil durante a transição entre a taxa de atualização, e a plataforma precisa da taxa de atualização atual para decidir quando iniciar o próximo frame. - setActiveConfigWithConstraints
- O método
setActiveConfigWithConstraintsé uma nova extensão do métodosetActiveConfigatual e fornece mais informações sobre a mudança de configuração. As restrições são fornecidas como parte dos parâmetrosvsyncPeriodChangeConstraintse contêm os seguintes parâmetros. - desiredTimeNanos
- O tempo em
CLOCK_MONOTONICapós o qual o período de vsync pode mudar (ou seja, o período de vsync não pode mudar antes desse horário). Isso é útil quando a plataforma quer planejar uma mudança na taxa de atualização, mas já tem alguns buffers na fila para apresentar. A plataforma define esse tempo de acordo com esses buffers para garantir que a transição da taxa de atualização seja a mais suave possível. - seamlessRequired
- Se for verdadeiro, exige que a mudança no período de vsync aconteça sem problemas
e sem um artefato visual perceptível. A plataforma usa essa flag quando uma mudança na taxa de atualização é necessária como resultado de uma mudança de conteúdo (por exemplo, o dispositivo está inativo e uma animação é iniciada). Isso dá ao fornecedor a oportunidade de
não permitir determinadas mudanças de configuração quando elas podem resultar em um artefato
visual perceptível. Se as configurações não puderem ser alteradas sem problemas e
seamlessRequiredestiver definido comotrue, espera-se que a implementação retorneSEAMLESS_NOT_POSSIBLEcomo o código de retorno e chame o novo callbackonSeamlessPossiblequando a mesma mudança de configuração puder ser feita sem problemas. Em caso de sucesso, a implementação retorna um
VsyncPeriodChangeTimelineque informa à plataforma quando esperar a mudança na taxa de atualização. Os parâmetrosnewVsyncAppliedTimeNanosprecisam ser definidos para o tempo emCLOCK_MONOTONICquando a nova tela começar a ser atualizada no novo período de vsync. Isso, junto comdesiredTimeNanos, permite que a plataforma planeje com antecedência a troca da taxa de atualização e comece a marcar os apps 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 o envio de um frame de atualização antes da taxa de atualização. Para isso, a HAL tem o parâmetro
refreshRequired, que indica que um frame de atualização é necessário, erefreshTimeNanos, que indica o primeiro vsync em que um frame de atualização precisa ser enviado depois.- onVsyncPeriodTimingChanged [callback]
- Um novo callback que o HAL pode chamar para indicar à plataforma que algum parâmetro da linha do tempo mudou e que a plataforma precisa ajustar a linha do tempo. Espera-se que esse callback seja chamado se, por algum motivo, a linha do tempo antiga não for encontrada devido a um longo tempo de processamento no HAL ou a um frame de atualização atrasado.
Como a plataforma decide mudar a taxa de atualização?
A seleção da taxa de atualização acontece nos dois serviços do sistema a seguir:
- DisplayManager
- O
DisplayManagerdefine 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 é a mesma da configuração do HAL do compositor. Além disso, ele define um intervalo de valores mínimo e máximo paraSurfaceFlingerescolher como taxa de atualização. - SurfaceFlinger
- Determina a taxa de atualização definindo uma configuração que está no mesmo grupo da configuração padrão e com uma taxa de atualização dentro do intervalo mínimo/máximo.
O Display Manager passa pelas seguintes etapas para determinar a política:
- Encontra o ID da configuração padrão consultando a configuração ativa de
SurfaceFlinger - Restringir o intervalo de valores mínimo e máximo iterando nas condições do sistema.
- Configuração da taxa de atualização padrão: o valor padrão da taxa de atualização
é definido na sobreposição de configuração
R.integer.config_defaultRefreshRate. Esse valor é usado para determinar a taxa de atualização padrão do dispositivo para animações e interações por toque. - Configuração da taxa de atualização máxima: o valor da taxa de atualização máxima
é lido de
Settings.System.PEAK_REFRESH_RATE. Esse valor é alterado no ambiente de execução para refletir a configuração atual do dispositivo (como uma opção de menu). O valor padrão é definido na sobreposição de configuraçãoR.integer.config_defaultPeakRefreshRate. - Configuração de taxa de atualização mínima: o valor da taxa de atualização mínima é lido de
Settings.System.MIN_REFRESH_RATE. Esse valor pode ser mudado durante a execução para refletir a configuração atual do dispositivo (por exemplo, em uma opção de menu). O valor padrão é 0, então não há um mínimo padrão. - ModeId solicitado pelo aplicativo: os apps podem definir
WindowManager.LayoutParams.preferredDisplayModeIdpara refletir uma configuração preferida em que a tela deve operar. Na maioria das condições, oDisplayManagerdefine 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, indicado por
Settings.Global.LOW_POWER_MODE.
- Configuração da taxa de atualização padrão: o valor padrão da taxa de atualização
é definido na sobreposição de configuração
Depois que DisplayManager define a política, SurfaceFlinger define a taxa de atualização com base nas camadas ativas (camadas que enfileiram atualizações de frames). Se o proprietário da camada definir uma taxa de frames, o SurfaceFlinger
tentará definir a taxa de atualização como um múltiplo dessa taxa.
Por exemplo, se duas camadas ativas definirem as taxas de frames como 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 com o menor
erro para a taxa de frames. Para mais informações, consulte a documentação para desenvolvedores em developer.android.com.
SurfaceFlinger mantém as seguintes flags para controlar como a taxa de atualização é decidida:
ro.surface_flinger.use_content_detection_for_refresh_rate:Se definido, a taxa de atualização será decidida com base nas camadas ativas, mesmo que uma taxa de frames não tenha sido definida. O SurfaceFlinger mantém uma heurística em que encontra o fps médio que a camada está postando buffers analisando o carimbo de data/hora de apresentação anexado ao buffer.ro.surface_flinger.set_touch_timer_ms: se for > 0, a taxa de atualização padrão será usada quando um usuário tocar na tela pelo 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 for > 0, a taxa mínima de atualização será usada quando não houver atualizações de tela durante o tempo limite configurado.ro.surface_flinger.set_display_power_timer_ms: se for > 0, a taxa de atualização padrão será usada ao ligar a tela (ou ao sair do AOD) para o tempo limite configurado.
API Frame Rate
A API de frame rate permite que os apps informem à plataforma Android o frame rate pretendido e está disponível em apps direcionados ao Android 11. Para saber mais sobre a API de taxa de frames, consulte a documentação para desenvolvedores em developer.android.com.
Opções do 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.