Frame Pacing Kitaplığı   Android Game Development Kit'in 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ına ulaşmasına yardımcı olur. Bu dokümanda kare hızlandırma tanımlanmakta, kare hızlandırmanın gerekli olduğu durumlar açıklanmakta ve kitaplığın bu durumları nasıl ele aldığı gösterilmektedir. Oyununuzda kare hızını doğrudan uygulamaya geçmek istiyorsanız Sonraki adım'a bakın.

Arka plan

Kart aralığı, bir oyunun mantığının ve oluşturma döngüsünün işletim sisteminin ekran alt sistemi ve temel ekran donanımıyla senkronize edilmesidir. Android görüntü alt sistemi, ekran donanımı bir güncellemenin ortasında yeni bir kareye geçtiğinde ortaya çıkabilecek görsel kusurları (yırtılma olarak bilinir) önlemek için tasarlanmıştır. Görüntü alt sistemi, bu kusurları önlemek için aşağıdakileri yapar:

  • Geçmiş kareleri dahili olarak arabelleğe alır.
  • Geç gönderilen kareleri algılar
  • Geç kareler algılandığında geçmiş karelerin görüntülenmesini tekrarlar

Oyun, ekran alt sistemindeki birleştirici olan SurfaceFlinger'ı bir kare için gereken tüm çizim çağrılarını gönderdiğini bilgilendirir (eglSwapBuffers veya vkQueuePresentKHR çağrısı yaparak). SurfaceFlinger, bir karenin hazır olduğunu ekran donanımına bir mandal kullanarak bildirir. Ardından ekran donanımı, belirtilen kareyi gösterir. Ekran donanımı sabit bir hızda (ör. 60 Hz) tıklıyor ve donanımın yeni bir kareye ihtiyacı olduğunda yeni bir kare yoksa önceki kareyi tekrar gösteriyor.

Tutarsız kare süreleri genellikle bir oyun oluşturma döngüsü, yerel ekran donanımından farklı bir hızda oluşturma işlemi gerçekleştirdiğinde ortaya çıkar. 30 FPS'de çalışan bir oyun, 60 FPS'yi doğal olarak destekleyen bir cihazda oluşturma işlemini denediğinde oyun oluşturma döngüsü, tekrarlanan bir karenin ekranda 16 milisaniye daha kaldığını fark etmez. Bu bağlantı kesilmesi genellikle kare sürelerinde önemli tutarsızlıklara neden olur (ör. 49 milisaniye, 16 milisaniye, 33 milisaniye). Çok karmaşık sahneler, kare atlamalarına neden olarak bu sorunu daha da artırır.

Optimum olmayan çözümler

Geçmişte oyunlarda kare hızlandırma için kullanılan aşağıdaki çözümler genellikle tutarsız kare sürelerine ve artan giriş gecikmesine neden olur.

Çerçeveleri, oluşturma API'sinin izin verdiği en hızlı şekilde gönderin.

Bu yaklaşım, oyunu değişken SurfaceFlinger etkinliğine bağlar ve ek bir kare gecikmesi getirir. Görüntüleme ardışık düzeni, genellikle 2 boyutlu bir çerçeve kuyruğu içerir. Bu kuyruk, oyun çerçeveleri çok hızlı sunmaya çalışırsa dolar. 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. Ardından oyun, ekran donanımının bir kare göstermesini beklemek zorunda kalır ve bu geri basınç, iki bileşeni senkronize eder. Bu duruma arabelleğe doldurma veya sırayla doldurma denir. Oluşturucu süreci ne olduğunu fark etmediği için kare hızı tutarsızlığı daha da kötüleşir. Oyun, girişi kareden önce örnekliyorsa giriş gecikmesi daha da kötüleşir.

Android Choreographer'ı tek başına kullanma

Oyunlar, senkronizasyon için Android Choreographer'ı da kullanır. API 16'dan itibaren Java'da ve API 24'ten itibaren C++'ta kullanılabilen bu bileşen, görüntüleme alt sistemiyle aynı sıklıkta düzenli tıklamalar sağlar. Bu işaretin gerçek donanım VSYNC'ye göre ne zaman yayınlandığıyla ilgili bazı incelikler vardır ve bu ofsetler cihaza göre değişir. Uzun karelerde arabelleğe doldurma işlemi yine de gerçekleşebilir.

Kare Hızı Kitaplığı'nın avantajları

Frame Pacing kitaplığı, senkronizasyon için Android Choreographer'ı kullanır ve tıklama yayınındaki değişkenliği sizin adınıza ele alır. Çerçevelerin doğru zamanda gösterilmesini sağlamak için sunum zaman damgalarını ve arabelleğe doldurmayı önlemek için senkronizasyon çitlerini kullanır. Kitaplık, varsa NDK Choreographer'ı kullanır ve yoksa Java Choreographer'a geri döner.

Kitaplık, cihaz tarafından destekleniyorsa birden fazla yenileme hızını işler. Bu da oyuna kare sunma konusunda daha fazla esneklik sağlar. Örneğin, 60 Hz ve 90 Hz yenileme hızını destekleyen bir cihazda, saniyede 60 kare üretemeyen bir oyunun sorunsuz kalması için kare hızı 30 FPS yerine 45 FPS'ye düşürülebilir. Kitaplık, beklenen oyun kare hızını algılar ve kare sunum sürelerini buna göre otomatik olarak ayarlar. Frame Pacing kitaplığı, gereksiz ekran güncellemelerini önlediği için pil ömrünü de artırır. Ö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. Kare Hızı Ayarlama kitaplığı, yenileme hızını cihaz tarafından desteklenen ve hedef kare hızına en yakın değere ayarlayarak bu sorunu önler.

İşleyiş şekli

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

30 Hz'de doğru kare hızlandırma

60 Hz cihazda 30 Hz'de oluşturma yapılırken Android'de ideal durum Şekil 1'de gösterilmiştir. SurfaceFlinger, varsa yeni grafik arabelleklerini sabitler (Not: Şemada "arabellek yok" olduğu ve öncekinin tekrarlandığı belirtilir).

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

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

Oyun karelerinin kısa olması takılmalara neden oluyor

Çoğu modern cihazda oyun motorları, karelerin gönderilmesini sağlamak için platform koreografının tıklama göndermesine güvenir. Ancak, Şekil 2'de görüldüğü gibi kısa kareler nedeniyle kare hızının düşük olması ihtimali vardır. Uzun karelerin ardından gelen kısa kareler, oynatıcı tarafından takılma olarak algılanır.

Kısa oyun kareleri

Şekil 2. Kısa oyun karesi C, B karesinin yalnızca bir kare göstermesine ve ardından birden fazla C karesinin gösterilmesine neden olur.

Frame Pacing kitaplığı, sunma zaman damgalarını kullanarak bu sorunu çözer. Kitaplık, karelerin erken sunulmaması için sunu zaman damgası uzantılarını EGL_ANDROID_presentation_time ve VK_GOOGLE_display_timing kullanır (Şekil 3'te gösterildiği gibi).

Sunum zaman damgaları

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

Uzun kareler takılmalara ve gecikmeye neden olur

Görüntü iş yükü, uygulama iş yükünden daha uzun sürdüğünde kuyruğa ek kareler eklenir. Bu durum, tekrar takılmalara neden olur ve arabelleğe doldurma nedeniyle ek bir kare gecikmesine de yol açabilir (bkz. şekil 4). Kitaplık hem takılmaları hem de ek gecikme çerçevesini ortadan kaldırır.

Uzun oyun kareleri

Şekil 4. Uzun B karesi, A ve B olmak üzere 2 kare için yanlış ilerleme hızı sağlar

Kitaplık, geri basıncın oluşmasına izin vermek yerine uygulamaya bekleme süreleri enjekte etmek için senkronizasyon çitleri (EGL_KHR_fence_sync ve VkFence) kullanarak bu sorunu çözer. Bu bekleme süreleri, görüntüleme ardışık düzeninin yetişmesine olanak tanır. A karesi hâlâ fazladan bir kare gösteriyor ancak B karesi artık doğru şekilde gösteriliyor (Şekil 5).

Uygulama katmanına eklenen beklemeler

Şekil 5. C ve D kareleri gösterilmeyi bekliyor.

Desteklenen çalışma modları

Kare 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ını deneyebilirsiniz ancak bunları devre dışı bırakarak ve Swappy'yi başlattıktan sonra 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ında ayıran bir ardışık düzen modeli kullanır.

Ardışık düzen modu

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

Boru hattı dışı mod

Genel olarak bu yaklaşım, giriş ekranı gecikmesinin daha düşük ve daha tahmin edilebilir olmasına neden olur. Bir oyunun kare süresinin çok düşük olduğu durumlarda hem CPU hem de GPU iş yükleri tek bir takas aralığına sığabilir. Bu durumda, ardışık düzene bağlı olmayan bir yaklaşım aslında daha düşük giriş ekranı gecikmesi sağlar.

Boru hattı dışı mod

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

Otomatik mod

Çoğu oyun, her karenin gösterildiği süre olan takas aralığını nasıl seçeceğini bilmez (örneğin, 30 Hz için 33,3 ms). Bir oyun bazı cihazlarda 60 FPS'de oluşturulabilirken başka bir cihazda daha düşük bir değere düşürülmesi gerekebilir. Otomatik mod, aşağıdakileri yapmak için CPU ve GPU sürelerini ölçer:

  • Değişim aralıklarını otomatik olarak seçin: Bazı sahnelerde 30 Hz, bazılarında 60 Hz sunan oyunlar, kitaplığın bu aralığı dinamik olarak ayarlamasına izin verebilir.
  • Ultra hızlı kareler için iş hattını devre dışı bırakma: Tüm durumlarda optimum giriş ekranı gecikmesi sağlar.

Birden fazla yenileme hızı

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

  • 60 Hz cihazlarda: 60 FPS / 30 FPS / 20 FPS
  • 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, oyun karelerinin gerçek oluşturma süresine en uygun yenileme hızını seçerek daha iyi bir görsel deneyim sunar.

Birden fazla yenileme hızı kare aralığı hakkında daha fazla bilgi için Android'de yüksek yenileme hızı oluşturma konulu blog yayınını inceleyin.

Çerçeve istatistikleri

Frame Pacing kitaplığı, hata ayıklama ve profil oluşturma amacıyla aşağıdaki istatistikleri sunar:

  • Oluşturma işlemi tamamlandıktan sonra bir karenin, birleştirici kuyruğunda beklediği ekran yenileme sayısının histogrami.
  • İstenen sunum zamanı ile gerçek mevcut zaman arasında geçen ekran yenileme sayısının histogramı.
  • İki art arda gelen kare arasında geçen ekran yenileme sayısının histogramı.
  • Bu kare için CPU çalışmasının başlangıcı ile gerçek mevcut 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 birini inceleyin:

Ek kaynaklar