Termal API

Yayın tarihi:

Android 11 (API düzeyi 30) - Thermal API

Android 12 (API düzeyi 31) - NDK API'si

(Önizleme) Android 15 (DP1) - getThermalHeadroomThresholds()

Uygulamanızın potansiyel performansı, cihazın termal durumuyla sınırlıdır. Bu durum; hava durumu, son kullanım ve cihazın termal tasarımı gibi özelliklere göre değişebilir. Cihazlar, termal kısıtlamaya tabi tutulmadan önce yalnızca sınırlı bir süre boyunca yüksek performans seviyesini koruyabilir. Uygulamanızın temel hedeflerinden biri, termal sınırlamaları aşmadan performans hedeflerine ulaşmak olmalıdır. Thermal API, cihaza özel optimizasyonlara gerek kalmadan bunu mümkün kılar. Ayrıca, performans sorunlarını ayıklarken cihazınızın termal durumunun performansı sınırlayıp sınırlamadığını bilmek önemlidir.

Oyun motorlarında genellikle, motorun cihaza yüklediği iş yükünü ayarlayabilen çalışma zamanı performans parametreleri bulunur. Örneğin, bu parametreler çalışan iş parçacığı sayısını, büyük ve küçük çekirdekler için çalışan iş parçacığı yakınlığını, GPU doğruluğu seçeneklerini ve çerçeve arabelleği çözünürlüklerini ayarlayabilir. Unity Engine'de oyun geliştiriciler, Adaptive Performance eklentisini kullanarak Kalite Ayarları'nı değiştirerek iş yükünü ayarlayabilir. Unreal Engine'de kalite düzeylerini dinamik olarak ayarlamak için Ölçeklenebilirlik Ayarları'nı kullanın.

Bir cihaz güvenli olmayan bir sıcaklık durumuna yaklaştığında oyununuz, bu parametreler aracılığıyla iş yükünü azaltarak performans kısıtlamasıyla karşılaşmayı önleyebilir. Kısıtlamayı önlemek için cihazın termal durumunu izlemeniz ve oyun motoru iş yükünü proaktif olarak ayarlamanız gerekir.

Cihaz aşırı ısındığında ısıyı dağıtmak için iş yükünün sürdürülebilir performans düzeyinin altına düşmesi gerekir. Isı payı daha güvenli seviyelere düştükten sonra oyun, kalite ayarlarını tekrar yükseltebilir. Ancak optimum oyun süresi için sürdürülebilir bir kalite seviyesi belirlemeyi unutmayın.

getThermalHeadroom yöntemini yoklayarak cihazın termal durumunu izleyebilirsiniz. Bu yöntem, cihazın aşırı ısınmadan mevcut performans seviyesini ne kadar süre koruyabileceğini tahmin eder. Süre, iş yükünü çalıştırmak için gereken süreden kısaysa oyununuz iş yükünü sürdürülebilir bir seviyeye düşürmelidir. Örneğin, oyun daha küçük çekirdeklere geçebilir, kare hızını düşürebilir veya kaliteyi azaltabilir.

ADPF Thermal API Ön Entegrasyonu
Şekil 1. getThermalHeadroom'u
etkin olarak izlemeden termal headroom
ADPF Thermal API Entegrasyonu Sonrası
Şekil 2. "getThermalHeadroom"un etkin şekilde izlenmesiyle termal headroom

Acquire Thermal Manager'ı edinme

Thermal API'yi kullanmak için önce Thermal Manager'ı edinmeniz gerekir.

C++

AThermalManager* thermal_manager = AThermal_acquireManager();

Java

PowerManager powerManager = (PowerManager)this.getSystemService(Context.POWER_SERVICE);

Daha fazla kontrol için x saniye öncesinden termal boşluğu tahmin edin

Sistemden, mevcut iş yüküyle x saniye sonraki sıcaklığı tahmin etmesini isteyebilirsiniz. Bu sayede, termal kısıtlamanın devreye girmesini önlemek için iş yükü azaltılarak daha ayrıntılı kontrol ve daha fazla tepki süresi elde edersiniz.

Sonuç 0,0f (kısıtlama yok, THERMAL_STATUS_NONE) ile

1,0f'ye (yoğun sınırlama, THERMAL_STATUS_SEVERE) düşürülür. Oyunlarınızda farklı grafik kalitesi seviyeleri varsa Termal Boşluk Yönergelerimizi uygulayabilirsiniz.

C++

float thermal_headroom = AThermal_getThermalHeadroom(0);
ALOGI("ThermalHeadroom: %f", thermal_headroom);

Java

float thermalHeadroom = powerManager.getThermalHeadroom(0);
Log.d("ADPF", "ThermalHeadroom: " + thermalHeadroom);

Alternatif olarak, netlik için termal durumdan yararlanabilirsiniz.

Her cihaz modeli farklı şekilde tasarlanabilir. Bazı cihazlar ısıyı daha iyi dağıtabilir ve bu nedenle, performansları kısıtlanmadan önce daha yüksek termal boşluğa dayanabilir. Isı payı aralıklarının basitleştirilmiş bir gruplandırmasını okumak istiyorsanız mevcut cihazdaki ısı payı değerini anlamak için ısı durumunu kontrol edebilirsiniz.

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);

Termal durum değiştiğinde bildirim alma

Ayrıca, thermalHeadroom belirli bir düzeye ulaşana kadar (örneğin, THERMAL_STATUS_LIGHT) yoklamayı da önleyebilirsiniz. Bunu yapmak için, durum her değiştiğinde sistemin sizi bilgilendirmesi için bir geri çağırma kaydı oluşturabilirsiniz.thermalStatus

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);

İşiniz bittiğinde dinleyiciyi kaldırmayı unutmayın.

C++

int result = AThermal_unregisterThermalStatusListener(thermal_manager, callback);
if ( result != 0 ) {
  // failed, check whether the callback has been registered previously
}

Java

powerManager.removeThermalStatusListener(listener);

Temizle

İşlemi tamamladığınızda edindiğiniz thermal_manager'ı temizlemeniz gerekir. Java kullanıyorsanız PowerManager referansı sizin için otomatik olarak çöp toplanabilir. Ancak Java API'yi JNI üzerinden kullanıyorsanız ve bir referansı sakladıysanız referansı temizlemeyi unutmayın.

C++

AThermal_releaseManager(thermal_manager);

Hem C++ API'yi (NDK API) hem de Java API'yi (JNI aracılığıyla) kullanarak yerel bir C++ oyununda Thermal API'yi uygulama hakkında eksiksiz bir kılavuz için Adaptability codelab bölümündeki Integrate Thermal API bölümüne göz atın.

Isı payı yönergeleri

getThermalHeadroom yöntemini yoklayarak cihazın termal durumunu izleyebilirsiniz. Bu yöntem, cihazın THERMAL_STATUS_SEVERE'a ulaşmadan önce mevcut performans düzeyini ne kadar süreyle koruyabileceğini tahmin eder. Örneğin, getThermalHeadroom(30) 0, 8 değerini döndürürse 30 saniye içinde headroom'un 0, 8'e ulaşmasının beklendiği ve 1, 0'dan 0, 2 uzaklıkta ciddi kısıtlama olduğu anlamına gelir. Süre, iş yükünü çalıştırmak için gereken süreden kısaysa oyununuz iş yükünü sürdürülebilir bir düzeye düşürmelidir. Örneğin, oyun kare hızını düşürebilir, kaliteyi azaltabilir veya ağ bağlantısı çalışmasını azaltabilir.

Termal durumlar ve anlamları

Thermal API'nin cihaz sınırlamaları

Eski cihazlarda Thermal API'nin uygulanması nedeniyle Thermal API'nin bazı bilinen sınırlamaları veya ek gereksinimleri vardır. Sınırlamalar ve bu sınırlamaları aşma yöntemleri aşağıda açıklanmıştır:

  • GetThermalHeadroom() API'sini çok sık çağırmayın. Bu durumda API, NaN değerini döndürür. Bu işlevi 10 saniyede birden fazla çağırmamalısınız.
  • Birden fazla iş parçacığından arama yapmaktan kaçının. Arama sıklığını sağlamak daha zordur ve API'nin NaN döndürmesine neden olabilir.
  • GetThermalHeadroom() başlangıç değeri NaN ise API cihazda kullanılamaz.
  • GetThermalHeadroom() yüksek bir değer (ör. 0, 85 veya daha fazla) döndürürse ve GetCurrentThermalStatus() hâlâ THERMAL_STATUS_NONE değerini döndürüyorsa durum güncellenmemiş olabilir. Doğru termal sınırlama durumunu tahmin etmek için sezgisel yöntemler kullanın veya getThermalHeadroom()'yı getCurrentThermalStatus() olmadan kullanın.

Sezgisel yöntem örneği:

  1. Thermal API'nin desteklendiğini kontrol edin. isAPISupported(), getThermalHeadroom için yapılan ilk çağrının değerini kontrol ederek 0 veya NaN olmadığından emin olur ve ilk değer 0 ya da NaN ise API'nin kullanılmasını atlar.
  2. getCurrentThermalStatus(), THERMAL_STATUS_NONE dışında bir değer döndürürse cihazın termal kısıtlamaya tabi olduğu anlaşılır.
  3. getCurrentThermalStatus() sürekli olarak THERMAL_STATUS_NONE değerini döndürüyorsa bu, cihazın termal kısıtlamaya tabi olmadığı anlamına gelmez. Bu, getCurrentThermalStatus() özelliğinin cihazda desteklenmediği anlamına gelebilir. Cihazın durumunu kontrol etmek için getThermalHeadroom() öğesinin dönüş değerini kontrol edin.
  4. getThermalHeadroom() değeri > 1,0 ise durum aslında THERMAL_STATUS_SEVERE veya daha yüksek olabilir. İş yükünü hemen azaltın ve getThermalHeadroom() daha düşük bir değer döndürene kadar iş yükünü düşük tutun.
  5. getThermalHeadroom() 0,95 değerini döndürürse durum aslında THERMAL_STATUS_MODERATE veya daha yüksek olabilir. İş yükünü hemen azaltın ve daha yüksek değerleri önlemek için dikkatli olun.
  6. getThermalHeadroom() 0,85 değerini döndürürse durum aslında THERMAL_STATUS_LIGHT olabilir. Gerekirse izlemeye devam edin ve iş yükünü azaltın.

Sözde kod:

  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.
      }
    }
  }

Diyagram:

ADPF Sezgisel Yöntemi
Örnek
Şekil 3. Eski cihazlarda Thermal API desteğini belirlemeye yönelik bir sezgisel yöntem örneği