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
O suporte dedicado à troca de taxa de atualização foi adicionado a …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
Mesmo que 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, e 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 esse problema. 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 mudar 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 taxas 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 para considerar esses buffers e 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 é igual à 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 mínimo da taxa de atualização é 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 a taxa 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.