2025년 3월 27일부터 AOSP를 빌드하고 기여하려면 aosp-main
대신 android-latest-release
를 사용하는 것이 좋습니다. 자세한 내용은 AOSP 변경사항을 참고하세요.
프레임 속도
컬렉션을 사용해 정리하기
내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.
Swappy라고도 하는 Android 프레임 페이싱 라이브러리는 Android 게임 SDK의 일부입니다. 이 라이브러리는 OpenGL 및 Vulkan 게임이 Android에서 원활한 렌더링 및 올바른 프레임 페이싱을 구현하는 데 도움이 됩니다.
프레임 페이싱은 게임의 로직 및 렌더링 루프를 OS의 디스플레이 하위 시스템 및 기본 디스플레이 하드웨어와 동기화하는 것입니다. Android 디스플레이 하위 시스템은 테어링과 같은 특정 시각적 아티팩트를 방지하도록 설계되었습니다. 디스플레이 하위 시스템은 다음을 실행하여 테어링을 방지합니다.
- 내부적으로 이전 프레임 버퍼링
- 지연된 프레임 제출 감지
- 지연된 프레임이 감지될 때 현재 프레임을 계속 표시
일관되지 않은 프레임 표시 시간은 게임의 렌더링 루프가 네이티브 디스플레이 하드웨어에서 지원하는 것과 다른 속도로 실행되어 발생합니다. 게임의 렌더링 루프가 기본 디스플레이 하드웨어에서 너무 느리게 실행될 때 발생하는 문제로 표시 시간이 일관되지 않게 됩니다. 예를 들어 30fps로 실행되는 게임이 기본적으로 60fps를 지원하는 기기에서 렌더링하려고 하면 게임의 렌더링 루프가 반복되는 프레임을 화면에 16ms 동안 추가로 유지되게 합니다. 이러한 유형의 연결 해제로 인해 33ms, 16ms, 49ms 등과 같은 프레임 시간에 상당한 불일치가 발생합니다. 지나치게 복잡한 장면은 이 문제를 더 악화시킵니다. 이러한 장면으로 인해 프레임이 누락되기 때문입니다.
프레임 페이싱 라이브러리는 다음 작업을 실행합니다.
- 짧은 게임 프레임으로 인한 끊김 현상을 보정합니다.
- 끊김 현상과 지연 시간을 유발하는 긴 프레임에 동기화 펜스를 사용합니다.
- 기기에서 여러 화면 재생 빈도를 지원하면 화면 재생 빈도를 선택하여 유연성과 원활한 프레젠테이션을 제공합니다.
- 프레임 통계를 사용하여 디버깅 및 프로파일링 통계를 제공합니다.
필요에 따라 다양한 모드에서 작동하도록 라이브러리를 구성하는 방법은 지원되는 작동 모드를 참고하세요.
OpenGL 렌더기나 Vulkan 렌더기를 사용하여 구현하려면 다음을 참고하세요.
자세한 내용은 올바른 프레임 페이싱 알아보기를 참고하세요.
초당 프레임 수 제한 개입
초당 프레임 수(FPS) 제한 개입을 사용하면 개발자가 아무런 조치를 취하지 않아도 플랫폼 측 변경사항만 사용하여 게임이 적절한 FPS로 진행될 수 있습니다.
FPS 제한 개입 구현에는 다음 구성요소가 사용됩니다.
GameManagerService
GameManagerService 구성요소는 게임 모드와 게임 개입에 관한 모든 사용자별 및 게임별 정보를 유지합니다. FPS 정보는 각 사용자 프로필의 <PACKAGE_NAME, Interventions>
매핑에 있는 다른 개입 정보(예: 해상도 축소 계수)와 함께 GameManagerService에 저장됩니다.
게임 모드가 변경되거나 개입이 업데이트될 때 FPS 정보에 액세스합니다. UID
는 각 PACKAGE_NAME
및 사용자에 고유하며 SurfaceFlinger로 전송하기 위해 <UID, Frame Rate>
쌍으로 추가로 변환될 수 있습니다.
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 제한 소개를 참고하세요.
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2024-08-07(UTC)
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["필요한 정보가 없음","missingTheInformationINeed","thumb-down"],["너무 복잡함/단계 수가 너무 많음","tooComplicatedTooManySteps","thumb-down"],["오래됨","outOfDate","thumb-down"],["번역 문제","translationIssue","thumb-down"],["샘플/코드 문제","samplesCodeIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2024-08-07(UTC)"],[],[],null,["# Frame pacing\n\nThe Android Frame Pacing library, also known as Swappy, is part of the [Android Game SDK](https://android.googlesource.com/platform/frameworks/opt/gamesdk/). It helps [OpenGL](/docs/core/graphics/arch-egl-opengl) and [Vulkan](/docs/core/graphics/arch-vulkan) games achieve smooth rendering\nand correct frame pacing on Android.\n\nFrame pacing is the synchronization of a game's logic and rendering loop with\nan OS's display subsystem and underlying display hardware. The Android display\nsubsystem was designed to avoid certain visual artifacts, such as tearing. The\ndisplay subsystem avoids tearing by doing the following:\n\n- Buffering past frames internally\n- Detecting late frame submissions\n- Continuing to display the current frame when a late frame is detected\n\nInconsistent frame display times are caused by a game's render loop running at\na different rate than what the native display hardware supports. Problems arise\nwhen a game's render loop runs too slowly for the underlying display hardware,\nleading to inconsistent display times. For example, when a game running at\n30 fps attempts to render on a device that natively supports 60 fps,\nthe game's render loop causes a repeated frame to remain on the screen for an\nextra 16 ms. This type of disconnect creates substantial inconsistencies in frame times\nsuch as 33 ms, 16 ms, and 49 ms. Overly complex scenes further compound\nthis problem because they cause missed frames to occur.\n\nThe Frame Pacing library performs these tasks:\n\n- Compensates for stuttering due to short game frames.\n - Adds presentation timestamps so that frames are presented on time, not early.\n - Uses presentation timestamp extensions [`EGL_ANDROID_presentation_time`](https://www.khronos.org/registry/EGL/extensions/ANDROID/EGL_ANDROID_presentation_time.txt) and [`VK_GOOGLE_display_timing`](https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VK_GOOGLE_display_timing.html).\n- Uses sync fences for long frames that lead to stuttering and latency.\n - Injects waits into the app. These allow the display pipeline to catch up, rather than allowing back pressure to build up.\n - Uses sync fences ([`EGL_KHR_fence_sync`](https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_fence_sync.txt) and [`VkFence`](https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkFence.html)).\n- Chooses a refresh rate to provide flexibility and a smooth presentation, if your device supports multiple refresh rates.\n- Provides stats for debugging and profiling using [frame\n stats](https://developer.android.com/games/sdk/frame-pacing/#frame_stats).\n\nTo learn how to configure the library to operate in different modes according\nto what you need, see [Supported operating modes](https://developer.android.com/games/sdk/frame-pacing/#supported_operating_modes).\n\nTo implement using OpenGL renderer or Vulkan renderer, see:\n\n- [Integrate Android Frame Pacing into your OpenGL renderer](https://developer.android.com//games/sdk/frame-pacing/opengl/)\n- [Integrate Android Frame Pacing into your Vulkan renderer](https://developer.android.com/games/sdk/frame-pacing/vulkan/)\n\nTo read more, see [Frame Pacing library](https://developer.android.com/games/sdk/frame-pacing/).\n\nFrames per second throttling intervention\n-----------------------------------------\n\nFrames per second (FPS) throttling intervention enables games to pace at an appropriate FPS\nusing only platform side\nchanges and without requiring any action on the developers' part.\n\nThe implementation of the FPS throttling intervention uses the following components.\n\n#### GameManagerService\n\nThe [GameManagerService](https://cs.android.com/android/platform/superproject/+/android-latest-release:frameworks/base/services/core/java/com/android/server/app/GameManagerService.java) component maintains all per-user and\nper-game information of game mode and game intervention. The FPS information is stored in the\nGameManagerService with other intervention information, such as the resolution downscaling factor,\nin a `\u003cPACKAGE_NAME, Interventions\u003e` mapping for each user profile.\nThe FPS information is accessed when the game mode is changed or the intervention is updated. A\n`UID` is unique to each `PACKAGE_NAME` and user, and can further be translated\ninto a `\u003cUID, Frame Rate\u003e` pair to send to the SurfaceFlinger.\n\n#### SurfaceFlinger\n\n[SurfaceFlinger](/docs/core/graphics/surfaceflinger-windowmanager) component already supports\nthrottling the FPS of an application as long as the frame rate is a divisor of the display refresh rate.\nIn the event of a VSync, the SurfaceFlinger checks the validity of the VSync for the throttled\napplication by verifying whether the VSync timestamp is in phase with the frame rate of the\napplication. If the frame rate is not in phase with the VSync, then the SurfaceFlinger holds the\nframe until the frame rate and VSync are in phase.\n\nThe following figure describes the interaction between the GameManagerService and the SurfaceFlinger:\n\n**Figure 1.** Interaction between the GameServiceManager and SurfaceFlinger.\n\nThe SurfaceFinger maintains a `\u003cUID, Frame Rate\u003e` pair mapping to set a new\nframe rate throttling priority. The `UID` is unique between users and games, so that each\nuser on a single device can have different settings of frame rate on the same game. To throttle the\nframe rate of a game, the GameServiceManager calls the SurfaceFlinger to override the frame rate for\na UID. With this mechanism, the SurfaceFlinger updates the mapping whenever\nthe game mode is changed or the intervention is updated. The SurfaceFlinger handles the FPS change\nby latching buffers accordingly.\n\nTo understand more about FPS throttling, see\n[FPS throttling](https://developer.android.com/games/optimize/adpf/gamemode/fps-throttling)."]]