O Android 11 adiciona suporte para dispositivos com várias 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 as configurações do dispositivo 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
O suporte dedicado para troca de taxa de atualização foi adicionado ao android.hardware.graphics.composer@2.4 HAL
. É altamente recomendável usar esta versão, pois as versões anteriores do compositor HAL têm suporte limitado para alternância de taxa de atualização.
Grupos de configuração
Um novo atributo CONFIG_GROUP
foi adicionado ao IComposerClient::Attribute
que pode ser consultado usando a API getDisplayAttribute_2_4
. Este atributo permite que os fornecedores agrupem as configurações de exibição. As configurações no mesmo grupo permitem a alternância perfeita entre eles 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 de usar 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 48Hz, 60Hz, 72Hz e 90Hz, a tela opera em um modo diferente e a mudança de 60Hz para 72Hz 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. Ao agrupar 60Hz e 90Hz em um grupo de configuração e 48Hz e 72Hz em outro grupo de configuração. A plataforma sabe que pode alternar entre 60Hz e 90Hz e entre 48Hz e 72Hz, mas não entre 60Hz e 72Hz, 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 Composer
- 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 de vsync) em que a exibição opera. Isso é especialmente útil quando a transição entre a taxa de atualização e a taxa de atualização atual é necessária para a plataforma decidir quando iniciar o próximo quadro. - setActiveConfigWithConstraints
- O método
setActiveConfigWithConstraints
é uma nova extensão do métodosetActiveConfig
existente e fornece mais informações sobre a alteração de configuração. As restrições são fornecidas como parte dos parâmetrosvsyncPeriodChangeConstraints
e contêm os parâmetros a seguir. - desejadoTimeNanos
- O tempo em
CLOCK_MONOTONIC
após o qual o período vsync pode ser alterado (ou seja, o período vsync não deve ser alterado 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 com esses buffers e garante que a transição da taxa de atualização seja a mais suave possível. - sem costuraRequerido
- Se verdadeiro, exige que a alteração do período de vsync ocorra sem problemas, sem um artefato visual perceptível. Esse sinalizador é usado pela plataforma quando uma alteração da 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 certas alterações 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
seamlessRequired
estiver definido comotrue
, espera-se que a implementação retorneSEAMLESS_NOT_POSSIBLE
como o código de retorno e chame o novo retorno de chamadaonSeamlessPossible
quando a mesma alteração de configuração puder ser feita sem problemas. Após o sucesso, a implementação retorna um
VsyncPeriodChangeTimeline
que informa à plataforma quando esperar que a alteração da taxa de atualização ocorra. Os parâmetrosnewVsyncAppliedTimeNanos
precisam ser definidos para a hora emCLOCK_MONOTONIC
quando a nova exibição começará a ser atualizada no novo período vsync. Isso, juntamente com odesiredTimeNanos
, permite que a plataforma planeje antecipadamente a mudança da taxa de atualização e comece a marcar 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 erefreshTimeNanos
para indicar o primeiro vsync para o qual um quadro de atualização precisa ser enviado depois.- onVsyncPeriodTimingChanged [retorno de chamada]
- Um novo callback que pode ser chamado pelo HAL para indicar à plataforma que algum parâmetro da timeline foi alterado 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 foi perdida devido a um longo tempo de processamento no HAL ou a um quadro de atualização tardia.
Como a plataforma decide alterar a taxa de atualização?
A seleção da taxa de atualização acontece nos dois serviços do sistema a seguir:
- Gerenciador de Exibição
- 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 é a mesma que a configuração HAL do compositor. Além disso, ele define um intervalo de valores mínimos e máximos para oSurfaceFlinger
escolher como a taxa de atualização. - SurfaceFlinger
- Determina a taxa de atualização definindo uma configuração que está no mesmo grupo de configuração que a 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
- Restringir o intervalo de valores mínimo e máximo iterando sobre 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
. Esse 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
. Esse 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çãoR.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
. Esse valor pode ser alterado em tempo de execução para refletir a configuração atual do dispositivo (como 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 preferida na qual a exibição deve operar. Na maioria das condições, oDisplayManager
define a 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. - Battery Saver : A taxa de atualização é restrita a 60Hz ou inferior quando o dispositivo está no modo de baixo consumo de energia, o que é indicado em
Settings.Global.LOW_POWER_MODE.
- 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
Depois que o DisplayManager
define a política, o SurfaceFlinger
define a taxa de atualização com base nas camadas ativas (camadas que enfileiram atualizações de quadros). 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á 120Hz 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 tenha 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. O 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 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 > 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) pelo 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, confira 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.