Android Frame Pacing 程式庫 (又稱為 Swappy) 是 Android Game SDK 的一部分。這個程式庫可讓 OpenGL 和 Vulkan 遊戲在 Android 裝置上流暢地呈現畫面,並修正影格同步情形。
影格同步是指遊戲的邏輯和算繪迴圈,與 OS 螢幕子系統和基礎顯示硬體的同步處理程序。Android 螢幕子系統經過特別設計,可避免特定視覺瑕疵,例如撕裂。螢幕子系統會執行下列操作,避免畫面撕裂:
- 在內部為已通過的影格預留緩衝區
- 偵測延遲提交的影格
- 偵測到影格延遲時,繼續顯示目前的影格
遊戲的算繪迴圈以與原生顯示硬體不同的速率執行時,就會導致影格顯示時間不一致。如果遊戲的算繪迴圈執行速度過慢,無法配合基礎顯示硬體,就會導致顯示時間不一致,進而產生問題。舉例來說,如果以每秒 30 個影格數執行的遊戲試圖在原生支援每秒 60 個影格數的裝置上執行,遊戲算繪迴圈就會導致重複影格額外保留在螢幕上 16 毫秒。這類中斷會造成影格時間出現大幅不一致的情況,例如 33 毫秒、16 毫秒和 49 毫秒。過度複雜的場景會導致影格遭到遺漏,使得問題更加複雜。
Frame Pacing 程式庫會執行下列工作:
- 補償因遊戲影格過短而造成的延遲。
- 加入顯示時間戳記,確保影格準時顯示,不會提早出現。
- 使用顯示時間戳記副檔名
EGL_ANDROID_presentation_time
和VK_GOOGLE_display_timing
。
- 針對導致畫面卡頓和延遲的影格過長問題,使用同步圍欄。
- 將等候插入的影格插入應用程式,該應用程式允許顯示管道擷取而不允許建構背壓。
- 使用同步處理柵欄 (
EGL_KHR_fence_sync
和VkFence
)。
- 如果裝置支援多種刷新率,可選擇刷新率,提供彈性且順暢的呈現方式。
- 使用影格統計資料提供偵錯和剖析的統計資料。
如要瞭解如何根據需求設定程式庫,使其在不同模式下運作,請參閱「支援的運作模式」。
如要使用 OpenGL 轉譯器或 Vulkan 轉譯器實作,請參閱:
詳情請參閱「Frame Pacing 程式庫」。
每秒畫格數節流干預
FPS 節流介入措施可讓遊戲僅透過平台端變更,以適當的 FPS 執行,開發人員無須採取任何行動。
FPS 節流介入措施的實作方式會使用下列元件。
GameManagerService
GameManagerService 元件會維護遊戲模式和遊戲介入措施的所有使用者和遊戲資訊。FPS 資訊會與其他干預資訊 (例如解析度縮減比例) 一起儲存在 GameManagerService 中,並以每個使用者設定檔的 <PACKAGE_NAME, Interventions>
對應項形式儲存。變更遊戲模式或更新介入措施時,系統會存取 FPS 資訊。每個 PACKAGE_NAME
和使用者都有專屬的 UID
,且可進一步轉換為 <UID, Frame Rate>
對,傳送至 SurfaceFlinger。
SurfaceFlinger
只要影格速率是螢幕重新整理頻率的除數,SurfaceFlinger 元件就支援節流應用程式的 FPS。發生 VSync 時,SurfaceFlinger 會檢查 VSync 對於受到節流的應用程式是否有效,方法是驗證 VSync 時間戳記是否與應用程式的影格速率同步。如果影格速率與 VSync 不同步,SurfaceFlinger 會保留影格,直到影格速率與 VSync 同步為止。
下圖說明 GameManagerService 與 SurfaceFlinger 之間的互動:

圖 1. GameServiceManager 和 SurfaceFlinger 之間的互動。
SurfaceFinger 會維護 <UID, Frame Rate>
對應,以設定新的影格速率節流優先順序。UID
在使用者和遊戲之間是獨一無二的,因此單一裝置上的每位使用者,都能在同一款遊戲中擁有不同的影格速率設定。如要限制遊戲的影格速率,GameServiceManager 會呼叫 SurfaceFlinger,覆寫 UID 的影格速率。透過這項機制,每當遊戲模式變更或介入措施更新時,SurfaceFlinger 就會更新對應。SurfaceFlinger 會視需要鎖定緩衝區,處理 FPS 變化。
如要進一步瞭解 FPS 節流,請參閱「 FPS 節流」。