Çerçeve İlerleme Hızı Kitaplığı Android Oyun Geliştirme Kiti'nin bir parçasıdır.

Swappy olarak da bilinen Android Frame Pacing kitaplığı AGDK Kitaplıkları'nın bir parçasıdır. OpenGL ve Vulkan oyunlarının Android'de sorunsuz oluşturma ve doğru kare hızı elde etmesine yardımcı olur. Bu belgede kare hızı tanımlanır, kare hızının gerekli olduğu durumlar açıklanır ve kitaplığın bu durumları nasıl ele aldığı gösterilmektedir. Doğrudan oyununuzda kare hızını uygulamaya atlamak istiyorsanız Sonraki adım'a bakın.

Arka plan

Kare hızı, bir oyunun mantığı ve oluşturma döngüsünün, işletim sisteminin ekran alt sistemi ve temel ekran donanımı ile senkronize edilmesidir. Android ekran alt sistemi, bir güncelleme sırasında ekran donanımı yeni bir kareye geçtiğinde oluşabilecek görsel kusurları (yırtılma olarak bilinir) önlemek için tasarlanmıştır. Bu yapıları önlemek için ekran alt sistemi aşağıdakileri yapar:

  • Geçmiş kareleri dahili olarak arabelleğe alır
  • Geç kare gönderimlerini algılar
  • Geç kareler algılandığında geçmiş karelerin gösterilmesini tekrar eder

Bir oyun, görüntü alt sistemindeki birleştirici olan SurfaceFlinger'a, bir kare için gereken tüm çizim çağrılarını gönderdiğini bildirir (eglSwapBuffers veya vkQueuePresentKHR yöntemini çağırarak). SurfaceFlinger, bir karenin kullanılabilirliğini bir mandal kullanarak ekran donanımına bildirir. Ekran donanımı daha sonra verilen çerçeveyi gösterir. Ekran donanımı, 60 Hz gibi sabit bir hızda ilerler. Donanıma ihtiyaç duyduğunda yeni bir kare yoksa donanım tekrar önceki kareyi görüntüler.

Oyun oluşturma döngüsü, yerel görüntü donanımından farklı bir hızda oluşturulduğunda genellikle tutarsız kare süreleri ortaya çıkar. 30 FPS hızında çalışan bir oyun, yerel olarak 60 FPS'yi destekleyen bir cihazda oluşturmayı denediğinde, oyun oluşturma döngüsü, tekrarlanan bir karenin ekranda fazladan 16 milisaniye boyunca kaldığını fark etmez. Bu bağlantı kesilmesi, genellikle 49 milisaniye, 16 milisaniye ve 33 milisaniye gibi kare sürelerinde önemli ölçüde tutarsızlıklara neden olur. Aşırı karmaşık sahneler, eksik karelere neden olduğu için bu sorunu daha da karmaşık hale getirir.

Optimum olmayan çözümler

Kare hızıyla ilgili aşağıdaki çözümler geçmişte oyunlar tarafından kullanılmıştı. Bu çözümler genellikle tutarsız kare sürelerine ve daha fazla giriş gecikmesine yol açıyor.

Kareleri oluşturma API'sinin izin verdiği kadar hızlı gönderin

Bu yaklaşım, bir oyunu değişken SurfaceFlinger etkinliğine bağlar ve fazladan bir gecikme çerçevesi sunar. Görüntüleme ardışık düzeni, genellikle 2 boyutunda bir kare sırası içerir. Oyun, kareleri çok hızlı sunmaya çalıştığında bu sırada doldurulur. Sırada yer kalmadığında oyun döngüsü (veya en azından oluşturma iş parçacığı) bir OpenGL veya Vulkan çağrısı tarafından engellenir. Daha sonra oyun, ekran donanımının bir kare göstermesini beklemeye zorlanır ve bu karşı basınç iki bileşeni senkronize eder. Bu durum, arabellek doldurma veya sıra doldurma olarak bilinir. Oluşturucu işlemi neler olup bittiğini algılamaz, bu yüzden kare hızı tutarsızlığı daha da kötüleşir. Oyun, kareden önce örnek girişi yaparsa giriş gecikmesi kötüleşir.

Android Choreographer'ı tek başına kullanma

Oyunlar ayrıca senkronizasyon için Android Choreographer'ı kullanır. API'de API 16'dan itibaren Java'da, API 24'ten C++'ta kullanılabilen bu bileşen, görüntüleme alt sistemiyle aynı sıklıkta normal onay işaretleri sağlar. Bu onay işaretinin, gerçek donanım VSYNC'sine göre ne zaman teslim edileceğine dair hâlâ incelikler vardır ve bu ofsetler cihaza göre değişir. Uzun karelerde arabellek doldurma işlemi devam edebilir.

Frame Pacing kitaplığının avantajları

Frame Pacing kitaplığı, senkronizasyon için Android Choreographer'ı kullanır ve onay işareti teslimindeki değişkenlikle ilgili işlemleri sizin için yapar. Karelerin doğru zamanda sunulduğundan emin olmak için sunum zaman damgalarını ve arabellek dolmasını önlemek için sınırları senkronize eder. Kitaplık, varsa NDK Choreographer'ı kullanır. Mevcut değilse Java Choreographer'a geri döner.

Kitaplık, cihaz tarafından destekleniyorsa birden fazla yenileme hızını işleyebilir, bu da bir oyuna kare sunma konusunda daha fazla esneklik sağlar. Örneğin, hem 60 Hz hem de 90 Hz yenileme hızını destekleyen bir cihazda, saniyede 60 kare üretemeyen bir oyun, sorunsuz kalması için 30 FPS yerine 45 FPS'ye düşebilir. Kitaplık beklenen oyun kare hızını algılar ve kare sunma sürelerini buna göre otomatik olarak ayarlar. Frame Pacing kitaplığı da gereksiz ekran güncellemelerinden kaçındığı için pil ömrünü iyileştirir. Örneğin, bir oyun 60 FPS'de oluşturuluyorsa ancak ekran 120 Hz'de güncelleniyorsa ekran her kare için iki kez güncellenir. Çerçeve İlerleme Hızı kitaplığı, yenileme hızını hedef kare hızına en yakın olan cihaz tarafından desteklenen değere ayarlayarak bunu önler.

Nasıl çalışır?

Aşağıdaki bölümlerde, doğru kare hızına ulaşmak için Frame Pacing kitaplığının uzun ve kısa oyun kareleriyle nasıl ilgilendiği gösterilmektedir.

30 Hz'de doğru kare hızı

60 Hz'lik bir cihazda 30 Hz'de oluşturma yaparken Android'deki ideal durum Şekil 1'de gösterilmiştir. SurfaceFlinger, varsa yeni grafik arabellekleri kilitler (şemadaki NB'de "arabellek yok" ifadesi bulunur ve bir önceki tekrarlanır).

60 Hz'lik bir cihazda 30 Hz'de ideal kare hızı

Şekil 1. 60 Hz'lik bir cihazda 30 Hz'de ideal kare hızı

Kısa oyun kareleri takılmaya neden oluyor

Modern cihazların çoğunda, oyun motorları, karelerin gönderilmesini sağlamak için tik gönderen platform koreografına güvenir. Bununla birlikte, Şekil 2'de gösterildiği gibi kısa kareler nedeniyle düşük kare hızı söz konusu olabilir. Kısa karelerin ardından gelen uzun kareler oyuncu tarafından takılma olarak algılanır.

Kısa oyun çerçeveleri

2. Şekil. Kısa oyun çerçevesi C karesi, B karesinin yalnızca bir kare göstermesine neden oluyor ve ardından birden fazla C karesi var

Frame Pacing kitaplığı, sunum zaman damgalarını kullanarak bu sorunu çözer. Kitaplıkta, sunum zaman damgası uzantıları EGL_ANDROID_presentation_time ile VK_GOOGLE_display_timing kullanılır. Böylece, Şekil 3'te gösterildiği gibi kareler erkenden sunulmaz.

Sunu zaman damgaları

3. Şekil. Daha akıcı bir görüntü için iki kez gösterilen oyun çerçevesi B

Uzun kareler takılmaya ve gecikmeye neden olur

Görüntülü reklam iş yükü uygulama iş yükünden daha uzun sürerse ekstra kareler sıraya eklenir. Bu durum bir kez daha takılmaya yol açar ve arabellek doldurma nedeniyle fazladan bir gecikme çerçevesine de yol açabilir (Şekil 4'e bakın). Kitaplık hem takılmayı hem de fazladan gecikme çerçevesini ortadan kaldırır.

Uzun oyun kareleri

4. Şekil. Uzun kare B, 2 kare (A ve B) için yanlış ilerleme hızı veriyor

Kitaplık bu sorunu çözmek için geri basınçların birikmesine izin vermek yerine görüntülü reklam ardışık düzeninin yetişmesini sağlamak üzere uygulamaya beklemeler eklemek için senkronizasyon çitlerini (EGL_KHR_fence_sync ve VkFence) kullanır. A çerçevesi hâlâ ekstra bir kare sunmakla birlikte, Şekil 5'te görüldüğü gibi B çerçevesi artık doğru bir şekilde sunulmaktadır.

Uygulama katmanına bekleme sayısı eklendi

5.Şekil C ve D kareleri sunmak için bekler

Desteklenen işletim modları

Çerçeve İlerleme Hızı kitaplığını aşağıdaki üç moddan birinde çalışacak şekilde yapılandırabilirsiniz:

  • Otomatik mod kapalı + Ardışık düzen
  • Otomatik mod açık + Ardışık düzen
  • Otomatik mod açık + Otomatik ardışık düzen modu (Ardışık düzen/Ardışık düzen olmayan)

Otomatik mod ve ardışık düzen modlarıyla denemeler yapabilirsiniz. Ancak, Swappy'yi başlattıktan sonra bunları devre dışı bırakıp aşağıdakileri ekleyerek başlarsınız:

  swappyAutoSwapInterval(false);
  swappyAutoPipelineMode(false);
  swappyEnableStats(false);
  swappySwapIntervalNS(1000000000L/yourPreferredFrameRateInHz);

Ardışık düzen modu

Kitaplık, motor iş yüklerini koordine etmek için genellikle CPU ve GPU iş yüklerini VSYNC sınırları arasında ayıran bir ardışık düzen modeli kullanır.

Ardışık düzen modu

6.Şekil Ardışık düzen modu

Ardışık düzen olmayan mod

Genel olarak bu yaklaşım, daha düşük ve daha tahmin edilebilir giriş ekranı gecikmesiyle sonuçlanır. Bir oyunun kare süresinin çok düşük olduğu durumlarda, hem CPU hem de GPU iş yükleri tek bir değiştirme aralığına sığabilir. Bu durumda, ardışık düzene sahip olmayan bir yaklaşım gerçekte daha düşük giriş ekranı gecikmesi sağlar.

Ardışık düzen olmayan mod

7. Şekil. Ardışık düzen olmayan mod

Otomatik mod

Çoğu oyun, her karenin sunulduğu süre olan değiştirme aralığını nasıl seçeceğini bilmez (örneğin, 30 Hz için 33,3 ms). Bazı cihazlarda 60 FPS'de oluşturulabilen bir oyunun bazı cihazlarda daha düşük bir değere düşmesi gerekebilir. Otomatik mod, aşağıdakileri yapmak için CPU ve GPU sürelerini ölçer:

  • Değişiklik aralıklarını otomatik olarak seç: Bazı sahnelerde 30 Hz, bazılarında ise 60 Hz sağlayan oyunlar, kitaplığın bu aralığı dinamik olarak ayarlamasına izin verebilir.
  • Ultra hızlı kareler için ardışık düzeni devre dışı bırakın: Her durumda optimum giriş ekranı gecikmesini sağlar.

Birden fazla yenileme hızı

Birden çok yenileme hızını destekleyen cihazlar, sorunsuz görünen bir değiştirme aralığı seçerken daha fazla esneklik sağlar:

  • 60 Hz cihazlarda: 60 FPS / 30 FPS / 20FPS
  • 60 Hz + 90 Hz cihazlarda: 90 FPS / 60 FPS / 45 FPS / 30 FPS
  • 60 Hz + 90 Hz + 120 Hz cihazlarda: 120 FPS / 90 FPS / 60 FPS / 45 FPS / 40 FPS / 30 FPS

Kitaplık, oyunun karelerinin gerçek oluşturma süresine en uygun yenileme hızını seçerek daha iyi bir görsel deneyim sunar.

Çoklu yenileme hızı kare hızı hakkında daha fazla bilgi için Android'de yüksek yenileme hızıyla oluşturma blog yayınına bakın.

Kare istatistikleri

Frame Pacing kitaplığı hata ayıklama ve profil çıkarma amaçları için aşağıdaki istatistikleri sunar:

  • Oluşturma tamamlandıktan sonra birleştirici sırasında bekleyen bir karenin yenilenme sayısına dair bir histogram.
  • İstenen sunu zamanı ile gerçek şimdiki zaman arasında geçen ekran yenileme sayısının histogramı.
  • Ardışık iki kare arasında geçen ekran yenilemelerinin sayısının histogramı.
  • Bu kare için CPU çalışmasının başlangıcı ile gerçek şimdiki zaman arasında geçen ekran yenileme sayısının histogramı.

Sonraki adım

Android Frame Pacing kitaplığını oyununuza entegre etmek için aşağıdaki kılavuzlardan birine bakın: