幀同步

Android Frame Pacing 庫,也稱為 Swappy,是Android Game SDK的一部分。它幫助OpenGLVulkan遊戲在 Android 上實現流暢的渲染和正確的幀同步。

幀同步是遊戲邏輯和渲染循環與操作系統的顯示子系統和底層顯示硬件的同步。 Android 顯示子系統旨在避免某些視覺偽影,例如撕裂。顯示子系統通過執行以下操作避免撕裂:

  • 在內部緩衝過去的幀
  • 檢測延遲幀提交
  • 檢測到延遲幀時繼續顯示當前幀

幀顯示時間不一致是由於遊戲的渲染循環以不同於本機顯示硬件支持的速率運行。當遊戲的渲染循環對於底層顯示硬件運行速度太慢時,就會出現問題,從而導致顯示時間不一致。例如,當以 30 fps 運行的遊戲嘗試在本機支持 60 fps 的設備上渲染時,遊戲的渲染循環會導致重複的幀在屏幕上多保留 16 毫秒。這種類型的斷開連接會在幀時間(例如 33 毫秒、16 毫秒、49 毫秒等)中造成嚴重的不一致。過於復雜的場景進一步加劇了這個問題,因為它們會導致丟失幀的發生。

Frame Pacing 庫執行以下任務:

  • 補償由於短遊戲幀造成的卡頓。
  • 對導致卡頓和延遲的長幀使用同步柵欄。
    • 將等待注入應用程序。這些允許顯示管道趕上,而不是讓背壓積聚。
    • 使用同步柵欄( EGL_KHR_fence_syncVkFence )。
  • 如果您的設備支持多種刷新率,則選擇刷新率以提供靈活性和流暢的演示。
  • 使用frame stats提供用於調試和分析的統計信息。

要了解如何配置磁帶庫以根據您的需要以不同模式運行,請參閱支持的運行模式

要使用 OpenGL 渲染器或 Vulkan 渲染器實現,請參見

要了解更多信息,請參閱實現適當的幀同步

每秒幀數 (FPS) 節流乾預

FPS 節流乾預使遊戲能夠僅使用平台方面的更改以適當的 FPS 進行調整,而無需開發人員採取任何行動。

FPS 節流乾預的實施使用以下組件:

遊戲管理服務

GameManagerService組件維護遊戲模式和遊戲干預的所有每個用戶和每個遊戲的信息。 FPS 信息與其他干預信息一起存儲在 GameManagerService 中,例如分辨率縮小因子,在每個用戶配置文件的<PACKAGE_NAME, Interventions>映射中。當改變遊戲模式或更新干預時訪問FPS信息。 UID對於每個PACKAGE_NAME和用戶都是唯一的,並且可以進一步轉換為<UID, Frame Rate>對以發送到 SurfaceFlinger。

SurfaceFlinger

只要幀速率是顯示刷新率的約數, SurfaceFlinger組件就已經支持限制應用程序的 FPS。在發生 vsync 時,SurfaceFlinger 通過驗證 vsync 時間戳是否與應用程序的幀速率同相來檢查受限應用程序的 vsync 的有效性。如果幀速率與 vsync 不同相,則 SurfaceFlinger 會保持幀直到幀速率和 vsync 同相。

下圖描述了GameManagerService和SurfaceFlinger的交互:

GameManagerService 和 SurfaceFlinger 之間的交互

圖 1. GameServiceManager 和 SurfaceFlinger 之間的交互

SurfaceFinger 維護一個<UID, Frame Rate>對映射以設置新的幀速率節流優先級。 UID在用戶和遊戲之間是唯一的,這樣單個設備上的每個用戶在同一個遊戲上可以有不同的幀率設置。為了限制遊戲的幀速率,GameServiceManager 調用 SurfaceFlinger 來覆蓋 UID 的幀速率。使用此機制,只要遊戲模式更改或乾預更新,SurfaceFlinger 就會更新映射。 SurfaceFlinger 通過相應地鎖存緩衝區來處理 FPS 變化。

要了解有關 FPS 限制的更多信息,請參閱FPS 限制介紹