Biblioteka Android Frame Pacing, znana też jako Swappy, jest częścią pakietu Android Game SDK. Pomaga to grom w OpenGL i Vulkanie płynnie renderować i prawidłowo dobierać tempo wyświetlania klatek na Androidzie.
Ustawianie szybkości wyświetlania klatek to synchronizacja logiki gry i pętli renderowania z podsystemem wyświetlania systemu operacyjnego oraz z podstawowym sprzętem wyświetlacza. Podsystem wyświetlania Androida został zaprojektowany tak, aby unikać pewnych artefaktów wizualnych, takich jak rozrywanie obrazu. Podsystem wyświetlania zapobiega rozdarciom, wykonując te czynności:
- buforowanie wewnętrzne poprzednich klatek,
- Wykrywanie spóźnionych przesyłek klatek
- wyświetlanie bieżącej klatki, gdy zostanie wykryta spóźniona klatka;
Niespójne czasy wyświetlania klatek są spowodowane tym, że pętla renderowania gry działa z inną częstotliwością niż obsługuje sprzęt wyświetlacza. Problemy pojawiają się, gdy pętla renderowania gry działa zbyt wolno w stosunku do podrzędnego sprzętu wyświetlacza, co powoduje niespójny czas wyświetlania. Jeśli na przykład gra działająca z szybkością 30 fps próbuje renderować na urządzeniu, które obsługuje 60 fps, pętla renderowania gry powoduje, że powtórna klatka pozostaje na ekranie przez dodatkowe 16 ms. Ten typ rozłączenia powoduje znaczne niespójności w czasie wyświetlania klatek, np. 33 ms, 16 ms, 49 ms itd. Problem ten pogłębiają zbyt skomplikowane sceny, ponieważ powodują one pominięcie klatek.
Biblioteka Frame Pacing wykonuje te zadania:
- Wyrównuje zacięcia spowodowane krótkimi klatkami w grze.
- Dodaje sygnatury czasowe prezentacji, aby klatki były wyświetlane w odpowiednim czasie, a nie za wcześnie.
- Używa rozszerzeń z sygnaturą czasową prezentacji
EGL_ANDROID_presentation_time
iVK_GOOGLE_display_timing
.
- Używa ograniczeń synchronizacji w przypadku długich klatek, które powodują zacinanie i opóźnienia.
- Wstrzykuje opóźnienia do aplikacji. Pozwala to strumieniowi wyświetlania nadrobić zaległości, zamiast dopuścić do wzrostu ciśnienia wstecznego.
- Używa zabezpieczeń synchronizacji (
EGL_KHR_fence_sync
iVkFence
).
- Wybiera częstotliwość odświeżania, aby zapewnić elastyczność i płynność prezentacji, jeśli urządzenie obsługuje różne częstotliwości odświeżania.
- Udostępnia statystyki do debugowania i profilowania za pomocą statystyk klatek.
Aby dowiedzieć się, jak skonfigurować bibliotekę do działania w różnych trybach w zależności od potrzeb, zapoznaj się z artykułem Obsługiwane tryby działania.
Aby zaimplementować renderowanie za pomocą mechanizmu OpenGL lub Vulkan, zapoznaj się z artykułem
- Integracja funkcji Android Frame Pacing z renderowaniem OpenGL
- Integracja Android Frame Pacing z renderowaniem Vulkana
Więcej informacji znajdziesz w artykule Prawidłowe dopasowywanie klatek.
Interwencja polegająca na ograniczeniu liczby klatek na sekundę
Interwencja polegająca na ograniczeniu liczby klatek na sekundę (FPS) umożliwia prowadzenie rozgrywki z odpowiednią liczbą FPS tylko dzięki zmianom po stronie platformy i bez konieczności podejmowania żadnych działań przez deweloperów.
Wdrożenie interwencji polegającej na ograniczeniu liczby klatek na sekundę wykorzystuje te komponenty:
GameManagerService
Komponent
GameManagerService przechowuje wszystkie informacje o użytkownikach i grach dotyczące trybu gry oraz interwencji w grze. Informacje o FPS są przechowywane w GameManagerService wraz z innymi informacjami o interwencji, takimi jak współczynnik zmniejszania rozdzielczości, w mapowaniu <PACKAGE_NAME, Interventions>
dla każdego profilu użytkownika.
Informacje o FPS są dostępne po zmianie trybu gry lub aktualizacji interwencji. UID
jest unikalny dla każdego PACKAGE_NAME
i użytkownika. Można go przekształcić w parę <UID, Frame Rate>
, aby wysłać do SurfaceFlingera.
SurfaceFlinger
Komponent SurfaceFlinger obsługuje już ograniczanie liczby klatek na sekundę aplikacji, o ile liczba klatek jest dzielnikiem częstotliwości odświeżania wyświetlacza. W przypadku sygnału vsync SurfaceFlinger sprawdza ważność sygnału vsync dla aplikacji z ograniczeniem, weryfikując, czy sygnatura czasowa vsync jest zsynchronizowana z częstotliwością klatek aplikacji. Jeśli częstotliwość klatek nie jest zsynchronizowana z synchronizacją pionową, SurfaceFlinger zatrzymuje ramkę, dopóki częstotliwość klatek i synchronizacja pionowa nie zostaną zsynchronizowane.
Na rysunku poniżej przedstawiono interakcję usługi GameManagerService z usługą SurfaceFlinger:

Rysunek 1. Interakcja między GameServiceManager a SurfaceFlinger
Interfejs SurfaceFinger zachowuje parę mapowania <UID, Frame Rate>
, aby ustawić nowy priorytet ograniczania liczby klatek na sekundę. UID
jest unikalny dla poszczególnych użytkowników i gier, dzięki czemu każdy użytkownik na jednym urządzeniu może mieć inne ustawienia częstotliwości klatek w tej samej grze. Aby ograniczyć liczbę klatek na sekundę w grze, GameServiceManager wywołuje SurfaceFlinger, aby zastąpić liczbę klatek na sekundę w identyfikatorze UID. Dzięki temu mechanizmowi SurfaceFlinger aktualizuje mapowanie za każdym razem, gdy zmienia się tryb gry lub interwencja. Komponent SurfaceFlinger obsługuje zmianę liczby klatek na sekundę, odpowiednio przełączając bufory.
Więcej informacji o ograniczaniu liczby klatek na sekundę znajdziesz w artykule wprowadzającym na ten temat.