Termal API

Yayınlanma tarihi:

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

Android 12 (API Düzeyi 31) - NDK API

(Ö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 olarak sınırlandırılmadan önce yalnızca sınırlı bir süre yüksek bir performans düzeyini koruyabilir. Uygulamanızın temel amacı, 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ılıyor. Ayrıca, performans sorunlarıyla ilgili hataları ayıklarken cihazınızın termal durumunun performansı sınırlayıp sınırlamadığını bilmek de önemlidir. Ayrıca, performans sorunlarıyla ilgili hataları ayıklarken cihazınızın termal durumunun performansı sınırlayıp sınırlamadığını bilmek de önemlidir.

Oyun motorları, genellikle motorun cihaza yerleştirdiği iş yükünü ayarlayabilen çalışma zamanı performans parametrelerine sahiptir. Ö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ğruluk seçeneklerini ve çerçeve arabelleği çözünürlüklerini ayarlayabilir. Oyun geliştiricileri, Unity Engine'de Uyarlanabilir Performans eklentisini kullanarak Kalite Ayarları'nı değiştirerek iş yükünü ayarlayabilir. Unreal Engine'de kalite seviyelerini dinamik olarak ayarlamak için Ölçeklenebilirlik Ayarları'nı kullanın.

Bir cihaz güvenli olmayan bir termal duruma yaklaştığında oyununuz, bu parametreler üzerinden iş yükünü azaltarak kısıtlanmaktan kaçınabilir. Kısıtlamadan kaçınmak 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 seviyesinin altına düşmesi gerekir. Termal boşluk 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 bulduğunuzdan emin olun.

getThermalHeadroom yöntemini yoklayarak cihazın termal durumunu izleyebilirsiniz. Bu yöntem, cihazın aşırı ısınmadan mevcut performans düzeyini ne kadar süreyle koruyabileceğini tahmin eder. Süre, iş yükünü çalıştırmak için gerekenden azsa oyununuzun iş yükünü sürdürülebilir bir seviyeye indirmesi gerekir. Örneğin, oyun daha küçük çekirdeklere geçiş yapabilir, kare hızını düşürebilir veya daha düşük kaliteye sahip olabilir.

ADPF Thermal API Ön Entegrasyon
Şekil 1. getThermalHeadroom'u aktif şekilde izlemeden Termal Headroom
ADPF Thermal API Entegrasyon Sonrası
Şekil 2. "getThermalHeadroom"un etkin izlemesiyle Thermal Headroom

Thermal Manager'ı edinin

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

C++

AThermalManager* thermal_manager = AThermal_acquireManager();

Java

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

Daha fazla kontrol için Termal Headroom'u x saniye önceden tahmin edin

Mevcut iş yüküyle sistemden sıcaklığı x saniye önceden tahmin etmesini isteyebilirsiniz. Bu sayede, termal kısıtlamanın devreye girmesini önlemek için iş yükünü azaltarak daha hassas bir kontrol ve daha fazla tepki verme zamanı elde edersiniz.

Sonuç, 0,0f (kısıtlama yok, THERMAL_STATUS_NONE) ile 1,0f (ağır sınırlama, THERMAL_STATUS_SEVERE) arasında değişir. Oyunlarınızda farklı grafik kalitesi seviyeleri varsa Termal Boşluk Yönergelerimizi uygulayabilirsiniz.

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

Alternatif olarak, netlik için termal duruma bakın

Her cihaz modeli farklı şekilde tasarlanabilir. Bazı cihazlar ısıyı daha iyi dağıtabilir ve böylece daraltılmadan önce daha yüksek bir termal boşluk payına dayanabilir. Termal boşluk aralığını basitleştirilmiş bir şekilde gruplandırmak isterseniz mevcut cihazdaki termal artış payını anlamak için termal duruma göz atabilirsiniz.

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 alın

Ayrıca, thermalStatus belirli bir seviyeye ulaşana kadar (örneğin: THERMAL_STATUS_LIGHT) thermalHeadroom yoklama işleminden kaçınabilirsiniz. Bunu yapmak için bir geri çağırma kaydı yaparak durum değiştiğinde sistemin sizi bilgilendirmesini sağlayabilirsiniz.

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

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

C++

AThermal_releaseManager(thermal_manager);

C++ API (NDK API) ve Java API (JNI aracılığıyla) kullanarak yerel bir C++ oyununda Thermal API'nin nasıl uygulanacağı hakkında eksiksiz bir kılavuz için Uyarlanabilirlik codelab'i bölümündeki Termal API'yi Entegre Et bölümüne göz atın.

Termal boşluk kuralları

getThermalHeadroom yöntemini yoklayarak cihazın termal durumunu izleyebilirsiniz. Bu yöntem, cihazın THERMAL_STATUS_SEVERE'e ulaşmadan önce mevcut performans düzeyini ne kadar süreyle koruyabileceğini tahmin eder. Örneğin, getThermalHeadroom(30) değeri 0,8 değerini döndürürse 30 saniyede boşluk boşluğunun 0,8'e ulaşması beklendiğini, ancak burada şiddetli kısıtlamadan 0,2 mesafe veya 1,0'ın olması beklendiğini belirtir. Süre, iş yükünü çalıştırmak için gerekenden azsa oyununuzun iş yükünü sürdürülebilir bir seviyeye indirmesi gerekir. Örneğin oyun, kare hızını ve görüntü kalitesini düşürebilir ya da ağ bağlantısı çalışmalarını azaltabilir.

Termal durumlar ve anlam

Thermal API'nin cihaz sınırlamaları

Termal API'nin eski cihazlarda uygulanmasından dolayı, Thermal API'nin bilinen bazı sınırlamaları veya ek gereksinimleri vardır. Sınırlamalar ve bunlarla ilgili çözüm şu şekildedir:

  • GetThermalHeadroom() API'yi çok sık çağırmayın. Bu işlem, API'nin NaN döndürmesine neden olur. Saniyede en fazla bir kez çağırmalısınız.
  • GetThermalHeadroom() ilk değeri NaN ise API cihazda kullanılamaz
  • GetThermalHeadroom() yüksek bir değer (ör. 0,85 veya daha yüksek) döndürüyorsa ve GetCurrentThermalStatus(), THERMAL_STATUS_NONE değerini döndürüyorsa durum muhtemelen güncellenmez. Doğru termal kısıtlama durumunu tahmin etmek için buluşsal yöntemleri kullanın veya getCurrentThermalStatus() olmadan yalnızca getThermalHeadroom() kullanın.

Sezgisel örnek:

  1. Thermal API'nin desteklendiğinden emin olun. isAPISupported(), getThermalHeadroom için yapılan ilk çağrının değerini kontrol ederek değerin 0 veya NaN olmadığından emin olur ve ilk değer 0 ya da NaN ise API'yi kullanarak atlar.
  2. getCurrentThermalStatus() işlevi, THERMAL_STATUS_NONE dışında bir değer döndürürse cihaz termal olarak kısıtlanmaktadır.
  3. getCurrentThermalStatus(), THERMAL_STATUS_NONE değerini döndürmeye devam ederse bu, cihazın termal olarak kısıtlanmadığı anlamına gelmez. Bu durum, cihazda getCurrentThermalStatus() özelliğinin desteklenmediği anlamına gelebilir. Cihazın durumundan emin olmak için getThermalHeadroom() döndürülen değerini kontrol edin.
  4. getThermalHeadroom() > 1, 0 bir değer döndürürse durum aslında THERMAL_STATUS_SEVERE veya daha yüksek olabilir, iş yükünü hemen azaltır ve getThermalHeadroom() daha düşük bir değer döndürene kadar iş yükünün azalmasını sağlar
  5. getThermalHeadroom(), 0,95 değerini döndürürse durum THERMAL_STATUS_MODERATE veya daha yüksek olabilir, iş yükünü hemen azaltır ve daha yüksek okumaları önlemek için dikkatli olun
  6. getThermalHeadroom() 0,85 değerini döndürürse durum aslında THERMAL_STATUS_LIGHT olabilir.Dikkatli olun ve mümkünse 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 Örneği
Şekil 3.Daha eski cihazlarda Thermal API desteğini belirlemek için Sezgisel örnek