Lançamento:
Android 11 (nível 30 da API): API Thermal
Android 12 (nível 31 da API): API NDK
(Prévia) Android 15 (DP1): getThermalHeadroomThresholds()
A performance em potencial do app é limitada pelo estado térmico do dispositivo, que pode variar de acordo com características como clima, uso recente e o design térmico do aparelho. Os dispositivos só podem manter um alto nível de por um período limitado antes de serem restringidas térmica. Um objetivo importante da implementação precisa ser atingir as metas de performance sem exceder as limitações térmicas. Com a API Thermal, isso não é necessário para otimizações específicas do dispositivo. Além disso, ao depurar o desempenho problemas, saber se o estado térmico do dispositivo está limitando o desempenho é muito importante. Além disso, ao depurar problemas de desempenho, saber se o estado térmico do dispositivo está limitando o desempenho é muito importante.
Os mecanismos de jogo geralmente têm parâmetros de performance relacionados ao tempo de execução que podem ajustar o tanto de recursos do dispositivo usados pelo mecanismo. Por exemplo, esses parâmetros podem definir o número de linhas de execução de worker, afinidade entre linha de execução e worker para núcleos grandes e pequenos, opções de fidelidade de GPU e resoluções de framebuffer. No Unity Engine, os jogos os desenvolvedores podem ajustar a carga de trabalho alterando a Qualidade Configurações usando o plug-in Adaptive Performance. No Unreal Engine, use as configurações de escalonabilidade para ajustar os níveis de qualidade de maneira dinâmica.
Quando um dispositivo se aproxima de um estado térmico não seguro, o jogo pode evitar a limitação, reduzindo a carga de trabalho por esses parâmetros. Para evitar a limitação, monitore o estado térmico do dispositivo e ajuste de forma proativa a carga de trabalho do mecanismo de jogo. Depois que o dispositivo superaquece, a carga de trabalho precisa ficar abaixo do nível de performance sustentável para dissipar o calor. Depois a margem térmica diminuir para níveis mais seguros, o jogo pode aumentar configurações de qualidade novamente, mas mantenha um nível de qualidade sustentável para um melhor momento de jogo.
Para monitorar o estado térmico do dispositivo, pesquise o
método
getThermalHeadroom
. Esse método prevê por quanto tempo o dispositivo consegue manter
nível de desempenho sem superaquecimento. Se o tempo for menor que a quantidade
necessária para executar a carga de trabalho, o jogo vai precisar diminuir essa carga a um
nível sustentável. Por exemplo, o jogo pode mudar para núcleos menores, reduzir o
frame rate ou diminuir a fidelidade.
![Pré-integração da API Thermal ADPF](https://developer.android.google.cn/static/games/optimize/adpf/images/adpf_thermal_pre-integration.png?authuser=9&hl=pt)
![Pós-integração da API ADPF Thermal](https://developer.android.google.cn/static/games/optimize/adpf/images/adpf_thermal_post-integration.png?authuser=9&hl=pt)
Adquirir gerente térmico
Para usar a API Thermal, você precisa primeiro adquirir o gerenciador térmico
C++
AThermalManager* thermal_manager = AThermal_acquireManager();
Java
PowerManager powerManager = (PowerManager)this.getSystemService(Context.POWER_SERVICE);
Preveja a margem térmica x segundos à frente para ter mais controle
Você pode pedir ao sistema para prever a temperatura com x segundos de antecedência com o carga de trabalho atual. Assim, você tem um controle mais detalhado e mais tempo para reagem reduzindo a carga de trabalho para impedir a limitação térmica.
O resultado varia de 0,0f (sem limitação, THERMAL_STATUS_NONE
) a 1,0f
(limitação pesada, THERMAL_STATUS_SEVERE
).
Se você tiver diferentes níveis de qualidade gráfica nos seus jogos, siga nosso
Diretrizes de margem térmica.
C++
float thermal_headroom = AThermal_getThermalHeadroom(10);
ALOGI("ThermalHeadroom in 10 sec: %f", thermal_headroom);
Java
float thermalHeadroom = powerManager.getThermalHeadroom(10);
Log.d("ADPF", "ThermalHeadroom in 10 sec: " + thermalHeadroom);
Como alternativa, confie no status térmico para esclarecimento.
Cada modelo de dispositivo pode ser projetado de maneira diferente. Alguns dispositivos podem distribuir melhor o calor e ser capaz de suportar uma margem térmica maior antes de serem restringidas. Se você quiser ler um agrupamento simplificado de intervalos de margem térmica, verifique o status térmico para entender o valor da margem térmica no dispositivo atual.
C++
AThermalStatus thermal_status = AThermal_getCurrentThermalStatus(thermal_manager);
ALOGI("ThermalStatus is: %d", thermal_status);
Java
int thermalStatus = powerManager.getCurrentThermalStatus();
Log.d("ADPF", "ThermalStatus is: " + thermalStatus);
Receber notificações quando o status térmico mudar
Você também pode evitar pesquisar o thermalHeadroom
até que thermalStatus
chegue
um determinado nível (por exemplo: THERMAL_STATUS_LIGHT
).
Para isso, você pode registrar um retorno de chamada para permitir que o sistema notifique você sempre que o
foi alterado.
C++
int result = AThermal_registerThermalStatusListener(thermal_manager, callback);
if ( result != 0 ) {
// failed, check whether you have previously registered callback that
// hasn’t been unregistered
}
Java
// PowerManager.OnThermalStatusChangedListener is an interface, thus you can
// also define a class that implements the methods
PowerManager.OnThermalStatusChangedListener listener = new
PowerManager.OnThermalStatusChangedListener() {
@Override
public void onThermalStatusChanged(int status) {
Log.d("ADPF", "ThermalStatus changed: " + status);
// check the status and flip the flag to start/stop pooling when
// applicable
}
};
powerManager.addThermalStatusListener(listener);
Lembre-se de remover o listener quando terminar
C++
int result = AThermal_unregisterThermalStatusListener(thermal_manager, callback);
if ( result != 0 ) {
// failed, check whether the callback has been registered previously
}
Java
powerManager.removeThermalStatusListener(listener);
Limpeza
Quando terminar, você vai precisar limpar o termal_manager adquirido. Se você estiver usando Java, a referência do PowerManager poderá ser descartada automaticamente coletados para você. Mas, se você estiver usando a API Java pelo JNI e tiver manteve uma referência, lembre-se de limpar a referência.
C++
AThermal_releaseManager(thermal_manager);
Para ver um guia completo sobre como implementar a API Thermal em um jogo em C++ nativo usando a API C++ (API NDK) e a API Java (pela JNI), confira a página Integrar Seção da API Thermal no codelab sobre adaptabilidade. nesta seção.
Diretrizes de margem térmica
Para monitorar o estado térmico do dispositivo, pesquise o
método
getThermalHeadroom
. Esse método prevê por quanto tempo o dispositivo consegue manter
nível de performance antes de alcançar THERMAL_STATUS_SEVERE
.
Por exemplo, se getThermalHeadroom(30)
retornar 0,8, isso indica que em 30
segundos, espera-se que a margem atinja 0,8, com uma distância de 0,2
de uma limitação grave, ou seja, 1,0. Se o tempo for menor que o tempo necessário para
executar a carga de trabalho, então seu jogo deve diminuir a carga de trabalho para um
nível Por exemplo, o jogo pode reduzir o frame rate, a fidelidade menor ou
e reduzir o trabalho de conectividade de rede.
Status e significado térmico
- Se o dispositivo não estiver sendo limitado térmico:
- Pouco limitação, mas sem impacto significativo no desempenho:
- Limitação significativa que afeta o desempenho:
Limitações de dispositivo da API Thermal
Há algumas limitações conhecidas ou requisitos adicionais da API Thermal, devido a implementações da API Thermal em dispositivos mais antigos. As limitações e como e contorná-los são os seguintes:
- Não chame a API
GetThermalHeadroom()
com muita frequência. Ao fazer isso, fará com que a API retorne um NaN. Você deve chamá-lo no máximo uma vez por segundo. - Se o valor inicial de
GetThermalHeadroom()
for NaN, a API não será disponível no dispositivo - Se
GetThermalHeadroom()
retornar um valor alto (por exemplo: 0,85 ou mais) eGetCurrentThermalStatus()
ainda retornaTHERMAL_STATUS_NONE
, o status é provavelmente não foi atualizada. Usar heurística para estimar a limitação térmica correta ou apenas usargetThermalHeadroom()
semgetCurrentThermalStatus()
.
Exemplo de heurística:
- Verifique se há suporte para a API Thermal.
isAPISupported()
verifica o valor de a primeira chamada paragetThermalHeadroom
para garantir que não seja 0 ou NaN pula usando a API se o primeiro valor for 0 ou NaN. - Se
getCurrentThermalStatus()
retornar um valor diferente deTHERMAL_STATUS_NONE
, o dispositivo está sendo limitado térmico. - Se
getCurrentThermalStatus()
continuar retornandoTHERMAL_STATUS_NONE
, ele não significa necessariamente que o dispositivo não esteja sendo limitado térmico. Poderia significa quegetCurrentThermalStatus()
não é compatível com o dispositivo. Verifique o valor de retorno degetThermalHeadroom()
para garantir a condição de o dispositivo. - Se
getThermalHeadroom()
retornar um valor > 1.0, o status poderia ser deTHERMAL_STATUS_SEVERE
ou mais, reduza a carga de trabalho imediatamente manter a carga de trabalho menor até quegetThermalHeadroom()
retorne um valor menor - Se
getThermalHeadroom()
retornar um valor de 0,95, o status poderá ser deTHERMAL_STATUS_MODERATE
ou mais, reduza a carga de trabalho imediatamente e fique atento para evitar leituras mais altas - Se
getThermalHeadroom()
retornar um valor de 0,85, o status poderá serTHERMAL_STATUS_LIGHT
, mantenha a observação e reduza a carga de trabalho Se possível,
Pseudocódigo:
bool isAPISupported() {
float first_value_of_thermal_headroom = getThermalHeadroom();
if ( first_value_of_thermal_headroom == 0 ||
first_value_of_thermal_headroom == NaN ) {
// Checked the thermal Headroom API's initial return value
// it is NaN or 0,so, return false (not supported)
return false;
}
return true;
}
if (!isAPISupported()) {
// Checked the thermal Headroom API's initial return value, it is NaN or 0
// Don’t use the API
} else {
// Use thermalStatus API to check if it returns valid values.
if (getCurrentThermalStatus() > THERMAL_STATUS_NONE) {
// The device IS being thermally throttled
} else {
// The device is not being thermally throttled currently. However, it
// could also be an indicator that the ThermalStatus API may not be
// supported in the device.
// Currently this API uses predefined threshold values for thermal status
// mapping. In the future you may be able to query this directly.
float thermal_headroom = getThermalHeadroom();
if ( thermal_headroom > 1.0) {
// The device COULD be severely throttled.
} else if ( thermal_headroom > 0.95) {
// The device COULD be moderately throttled.
} else if ( thermal_headroom > 0.85) {
// The device COULD be experiencing light throttling.
}
}
}
Diagrama: