Date de sortie :
Android 11 (niveau d'API 30) - API thermique
Android 12 (niveau d'API 31) - API NDK
(Preview) Android 15 (DP1) - getThermalHeadroomThresholds()
Les performances potentielles de votre application sont limitées par l'état thermique de l'appareil, qui peut varier en fonction de caractéristiques telles que la météo, son utilisation récente et sa conception thermique. Les appareils ne peuvent maintenir qu'un niveau élevé pendant une durée limitée avant d'être soumis à une limitation thermique. L'un des buts ultimes de votre implémentation est d'atteindre les objectifs de performances sans dépasser les limites thermiques. Avec l'API Thermal, c'est possible sans avoir besoin pour les optimisations spécifiques à chaque appareil. De plus, lors du débogage des performances savoir si l'état thermique de votre appareil limite ses performances importantes.
Les moteurs de jeu disposent généralement de paramètres de performances d'exécution permettant d'ajuster la charge de travail qu'ils imposent à l'appareil. Par exemple, ces paramètres peuvent définir le nombre de threads de calcul, l'affinité entre les nœuds de calcul et les threads pour les cœurs de petite et de grande taille, les options de fidélité GPU et les résolutions de tampon de trame. Dans Unity Engine, le jeu les développeurs peuvent ajuster la charge de travail en modifiant la qualité Paramètres à l'aide du plug-in Adaptive Performance. Pour Unreal Engine, utilisez les paramètres d'évolutivité pour ajuster les niveaux de qualité de manière dynamique.
Lorsqu'un appareil se rapproche d'un état thermique qui n'est pas sûr, ces paramètres contribuent à réduire la charge de travail afin que votre jeu n'ait pas à en subir les conséquences. Pour éviter toute limitation, vous devez surveiller l'état thermique de l'appareil et ajuster de manière proactive la charge de travail du moteur de jeu. Lorsque l'appareil est en surchauffe, la charge de travail doit descendre en dessous des niveaux de performances durables pour dissiper la chaleur. Après la plage de température tombe à un niveau plus sûr, le jeu peut augmenter la mais veillez à trouver un niveau de qualité durable pour un temps de jeu optimal.
Pour surveiller l'état thermique de l'appareil, interrogez la méthode getThermalHeadroom
. Cette méthode permet de prédire combien de temps l'appareil peut maintenir
sans surchauffer. Si cette durée est inférieure au temps nécessaire à l'exécution de la charge de travail, le jeu doit limiter la charge de travail à un niveau durable. Par exemple, il peut basculer sur des cœurs plus petits, diminuer la fréquence de frames ou réduire la fidélité.
![Pré-intégration de l'API thermique ADPF](https://developer.android.com/static/games/optimize/adpf/images/adpf_thermal_pre-integration.png?authuser=19&hl=fr)
![Post-intégration de l'API thermique ADPF](https://developer.android.com/static/games/optimize/adpf/images/adpf_thermal_post-integration.png?authuser=19&hl=fr)
Acquérir le gestionnaire thermique
Pour utiliser l'API Thermal, vous devez d'abord vous procurer le Thermal Manager
C++
AThermalManager* thermal_manager = AThermal_acquireManager();
Java
PowerManager powerManager = (PowerManager)this.getSystemService(Context.POWER_SERVICE);
Prévoyez la marge de température dans x secondes pour avoir plus de contrôle
Vous pouvez demander au système de prévoir la température quelques secondes à l'avance avec le la charge de travail actuelle. Vous bénéficiez ainsi d'un contrôle plus précis et de plus de temps réagissent en réduisant la charge de travail pour empêcher la limitation thermique.
Le résultat est compris entre 0,0 f (aucune limitation, THERMAL_STATUS_NONE
) et 1,0 f
(ralentissement important, THERMAL_STATUS_SEVERE
).
Si vous avez différents niveaux de qualité graphique dans vos jeux, vous pouvez suivre nos
Consignes concernant la plage thermique.
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);
Vous pouvez aussi vous appuyer sur l'état thermique pour plus de précision
Chaque modèle d'appareil peut être conçu différemment. Certains appareils peuvent être une meilleure répartition de la chaleur et donc de résister à une plage de température plus élevée avant d'être limité. Si vous souhaitez lire un regroupement simplifié de plages de de température maximale, vous pouvez vérifier l'état thermique pour mieux interpréter de la plage de température de l'appareil actuel.
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);
Soyez averti en cas de changement de l'état thermique
Vous pouvez également éviter d'interroger le thermalHeadroom
jusqu'à ce que l'appel thermalStatus
soit effectué.
un certain niveau (par exemple, THERMAL_STATUS_LIGHT
) ;
Pour ce faire, vous pouvez enregistrer un rappel afin que le système vous informe chaque fois que
son état a changé.
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);
N'oubliez pas de supprimer l'écouteur lorsque vous avez terminé.
C++
int result = AThermal_unregisterThermalStatusListener(thermal_manager, callback);
if ( result != 0 ) {
// failed, check whether the callback has been registered previously
}
Java
powerManager.removeThermalStatusListener(listener);
Effectuer un nettoyage
Une fois que vous avez terminé, vous devez nettoyer le module "Thermal_manager" que vous avez obtenu. Si vous utilisez Java, la référence PowerManager peut être automatiquement collectées pour vous. Mais si vous utilisez l'API Java via JNI et avez conserver une référence, n'oubliez pas de la nettoyer !
C++
AThermal_releaseManager(thermal_manager);
Pour obtenir un guide complet sur l'implémentation de l'API Thermal dans un jeu C++ natif à l'aide de à la fois l'API C++ (API NDK) et l'API Java (via JNI), consultez le document Intégrer Section sur l'API Thermal de l'atelier de programmation sur l'adaptabilité .
Consignes concernant la plage de température
Pour surveiller l'état thermique de l'appareil, interrogez la méthode getThermalHeadroom
. Cette méthode permet de prédire combien de temps l'appareil peut maintenir
niveau de performances avant d'atteindre THERMAL_STATUS_SEVERE
.
Par exemple, si getThermalHeadroom(30)
renvoie 0,8, cela indique que dans 30
seconde, la marge de progression devrait atteindre 0,8, où la distance est de 0,2
d'un ralentissement sévère, ou 1.0. Si le temps est inférieur
à la quantité nécessaire pour
exécuter cette charge de travail, votre jeu doit alors la réduire à un niveau
d'application. Par exemple, le jeu peut réduire la fréquence d'images, diminuer la fidélité ou
à réduire les tâches de connectivité réseau.
États et signification thermiques
- Si l'appareil n'est pas soumis à une limitation thermique:
<ph type="x-smartling-placeholder">
- </ph>
THERMAL_STATUS_NONE
- Limitations, mais pas d'impact significatif sur les performances: <ph type="x-smartling-placeholder">
- Limitation importante qui affecte les performances: <ph type="x-smartling-placeholder">
Limites de l'API Thermal concernant les appareils
L'API Thermal présente des limites connues ou des exigences supplémentaires. aux implémentations de l'API thermique sur les appareils plus anciens. Les limites et le fonctionnement pour les contourner:
- N'appelez pas l'API
GetThermalHeadroom()
trop fréquemment. Cela vous l'API renvoie une valeur NaN. Vous ne devez pas l'appeler plus d'une fois par seconde. - Si la valeur initiale de
GetThermalHeadroom()
est NaN, l'API n'est pas disponibles sur l'appareil - Si
GetThermalHeadroom()
renvoie une valeur élevée (par exemple, 0,85 ou plus) etGetCurrentThermalStatus()
renvoie toujoursTHERMAL_STATUS_NONE
, l'état est probablement pas mis à jour. Utiliser des méthodes heuristiques pour estimer la limitation thermique correcte ou utilisez simplementgetThermalHeadroom()
sansgetCurrentThermalStatus()
.
Exemple heuristique:
- Vérifiez que l'API Thermal est compatible.
isAPISupported()
vérifie la valeur de le premier appel àgetThermalHeadroom
pour vous assurer que la valeur n'est pas 0 ou NaN, et ignore l'utilisation de l'API si la première valeur est 0 ou NaN. - Si
getCurrentThermalStatus()
renvoie une valeur autre queTHERMAL_STATUS_NONE
: l'appareil est soumis à une limitation thermique. - Si
getCurrentThermalStatus()
renvoie toujoursTHERMAL_STATUS_NONE
, il ne signifie pas nécessairement que l'appareil n'est pas soumis à une limitation thermique. Il pourrait signifie quegetCurrentThermalStatus()
n'est pas compatible avec l'appareil. Vérifiez la valeur renvoyée pourgetThermalHeadroom()
pour vous assurer que la condition de l'appareil. - Si
getThermalHeadroom()
renvoie une valeur > 1.0, l'état pourrait être deTHERMAL_STATUS_SEVERE
ou plus, réduire immédiatement la charge de travail maintenir une charge de travail plus faible jusqu'à ce quegetThermalHeadroom()
renvoie une valeur inférieure - Si
getThermalHeadroom()
renvoie une valeur de 0,95, l'état peut être deTHERMAL_STATUS_MODERATE
ou plus, réduire immédiatement la charge de travail et gardez l'œil pour éviter tout risque de lecture - Si
getThermalHeadroom()
renvoie une valeur de 0,85, l'état peut êtreTHERMAL_STATUS_LIGHT
, maintenir la surveillance et réduire la charge de travail si possible
Pseudo-code:
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.
}
}
}
Diagramme:
<ph type="x-smartling-placeholder">