慢会话(仅限游戏)

慢会话是指速率较慢的帧占比超过 25% 的会话。如果某个帧的呈现时间比前一帧的呈现时间长 50 毫秒(相当于 20 FPS),则认为该帧的呈现速度缓慢。Android Vitals 还会报告第二个慢会话指标,其目标值为 34 毫秒(相当于 30 FPS)。通过慢会话,您可以了解游戏的帧速率性能,帧速率会影响游戏带给用户的流畅感。

Play 会在适当情况下减少展示帧速率在用户手机上无法达到 20 FPS 的游戏。请注意,只有在游戏运行时间达到 1 分钟后,Android Vitals 才会开始监控帧速率。

如需详细了解此指标,请访问我们的帮助中心

显示慢帧和非慢帧数量的饼图状图形。
图 1. Android Vitals 中的慢会话。

如何衡量 FPS 和检测慢帧

Android dumpsys surfaceflinger timestats 命令可提供正在渲染的所有图层的平均 FPS 和呈现到呈现时间直方图。帧的“呈现到呈现”时间是指当前帧与正在绘制的前一帧之间的时间间隔。以下是使用该命令收集游戏 FPS 的分步说明:

  1. 运行带有 enableclear 标志的命令,开始捕获信息:

    adb shell dumpsys SurfaceFlinger --timestats -clear -enable
    
  2. 当游戏运行足够长时间后,再次运行带有 dump 标志的命令以转储信息:

    adb shell dumpsys SurfaceFlinger --timestats -dump
    

    转储的信息会提供由 SurfaceFlinger 呈现的所有图层的总帧数和 presentToPresent 直方图。您必须通过基于 layerName 进行过滤来找到游戏的部分

    layerName = SurfaceView[com.google.test/com.devrel.MainActivity]@0(BLAST)#132833
    

    会话的帧速率过低问题可根据每个层的信息进行计算。

    例如,20 FPS 慢帧百分比 =(54 毫秒到 1000 毫秒之间的值之和)/ 总帧数 x 100

    totalFrames = 274
    ...
    presentToPresent histogram is as below:
    0ms=0 1ms=0 2ms=0 3ms=0 4ms=0 5ms=0 6ms=0 7ms=0 8ms=0 9ms=0 10ms=0 11ms=0 12ms=0
    13ms=0 14ms=0 15ms=0 16ms=1 17ms=0 18ms=0 19ms=0 20ms=0 21ms=0 22ms=0 23ms=0
    24ms=0 25ms=0 26ms=0 27ms=0 28ms=0 29ms=0 30ms=0 31ms=0 32ms=0 33ms=269 34ms=0
    36ms=0 38ms=0 40ms=0 42ms=0 44ms=0 46ms=0 48ms=0 50ms=1 54ms=0 58ms=0 62ms=0
    66ms=0 70ms=1 74ms=0 78ms=0 82ms=0 86ms=0 90ms=0 94ms=0 98ms=0 102ms=0 106ms=0
    110ms=0 114ms=0 118ms=0 122ms=0 126ms=0 130ms=0 134ms=0 138ms=0 142ms=0 146ms=0
    150ms=0 200ms=0 250ms=0 300ms=0 350ms=0 400ms=0 450ms=0 500ms=0 550ms=0 600ms=0
    650ms=0 700ms=0 750ms=0 800ms=0 850ms=0 900ms=0 950ms=0 1000ms=0
    

    转储中还会显示每个图层的平均 FPS:

    ...
    averageFPS = 30.179
    ...
    
  3. 收集完所有信息后,您应使用标志 disable 停用 timestats:

    adb shell dumpsys SurfaceFlinger --timestats -disable
    

慢帧的原因和解决方案

帧在屏幕上呈现或渲染的时间可能比开发者的目标时间长,原因有很多。游戏可能存在 CPU/GPU 瓶颈。或者设备过热并激活了受限的热状态。或者游戏帧速率与设备显示刷新率不匹配

使用 Android Frame Pacing (Swappy)VulkanADPF 来解决这些问题并提升游戏性能。

什么是 Swappy

Android Frame Pacing 库(也称为 Swappy)是 AGDK 库的一部分。Swappy 可帮助 OpenGL 和 Vulkan 游戏在 Android 上实现流畅的渲染和正确的帧同步。

帧同步是指游戏的逻辑和渲染循环与操作系统的显示子系统和底层显示硬件之间的同步。Android 显示子系统的设计可避免在显示硬件通过更新半途切换至新的帧时可能会出现的视觉伪影(称为“抖动”)。为避免出现这些伪影,显示子系统会执行以下操作:

  • 在内部缓冲之前的帧
  • 检测延迟帧的提交情况
  • 检测到延迟帧时重复显示之前的帧

了解 Mir 2 如何使用 Swappy 将慢会话比率从 40% 降至 10%

如何在原生项目中使用 Swappy

请参阅以下指南,将 Android Frame Pacing 库集成到您的游戏中:

如何在 Unity 游戏引擎中使用 Swappy

Unity 已将 Android Frame Pacing 集成至其引擎中。如需在 Unity 2019.2 或更高版本中启用此功能,请勾选 Project Settings > Player > Settings for Android > Resolution and Presentation 下的“Optimized Frame Pacing”复选框:

“项目设置”对话框。
图 2. 在 Unity 引擎中启用 Frame Pacing。

或者,在逻辑代码中以编程方式启用“Optimized Frame Pacing”选项,以允许 Unity 均匀分布帧,从而减少帧速率的变化,打造更流畅的游戏体验。

如何在 Unreal 游戏引擎中使用 Swappy

Unreal 4.25 及更高版本集成了 Android Frame Pacing 库,后者是 Android Game Development Kit 的一部分。移动设备帧同步一文介绍了如何启用 Android Frame Pacing 库,以及如何通过 C++ 代码控制帧同步。

什么是 Vulkan

Vulkan 是一种现代化跨平台 3D 图形 API,利用它可以最大限度减少设备图形硬件与您游戏之间的抽象处理。Vulkan 是 Android 上的主要底层图形 API,用于取代 OpenGL ES。OpenGL ES 在 Android 上仍受支持,但我们已不再开发其功能。

与 OpenGL ES 相比,Vulkan 具有以下优势:

  • 采用更高效的架构,图形驱动程序的 CPU 开销更低
  • 通过新的优化策略提高了 CPU 性能
  • 具有无绑定 API、光线追踪等 OpenGL ES 所不具备的全新图形功能

如何在原生 Android 项目中使用 Vulkan

开始在 Android 上使用 Vulkan Codelab 将引导您完成 Vulkan 渲染流水线的设置,然后在屏幕上渲染带纹理的旋转三角形。通过此 Codelab 了解如何渲染游戏图形。

如何在 Unity 游戏引擎中使用 Vulkan

如需在 Unity 上启用自动设备选择,请按照相关步骤配置 Auto Graphics API

“项目设置”对话框。
图 3. 启用 Unity Auto Graphics API。

或者,您也可以通过禁用自动图形 API 来手动启用 Vulkan,并将 Vulkan 放在图形 API 列表中的最高优先级。如果您使用的是 Unity 2021.1 或更低版本,这是使用 Vulkan 的唯一方式。

“项目设置”对话框。
图 4. 在 Unity 中手动选择 Vulkan 作为主要图形 API。

使用 VkQuality Unity 引擎插件,在启动时为游戏提供图形 API 建议,以便在特定设备上使用。

如何在 Unreal 游戏引擎中使用 Vulkan

如需启用 Vulkan 图形 API,请依次前往 Project Settings > Platforms > Android > Build,然后选择 Support Vulkan。如果您同时选择支持 Vulkan支持 OpenGL ES3.2,Unreal 会默认使用 Vulkan。如果设备不支持 Vulkan,Unreal 会回退到 OpenGL ES 3.2。

“项目设置”对话框。
图 5. 在 Unreal Engine 中启用 Vulkan。

如果您使用的特定 Vulkan 功能在某些设备上表现不佳,可以自定义 BaseDeviceProfile.ini 文件以排除这些设备。请参阅自定义设备配置文件和 Android 可伸缩性,了解如何自定义 BaseDeviceProfile.ini。由于新的设备驱动程序可能会修复之前已知的不良设备,请及时更新 BaseDeviceProfile.ini 文件,以获得所有优化。

什么是 ADPF

Android 动态性能框架 (ADPF) 可根据 Android 上的动态散热、CPU 和 GPU 管理功能优化游戏。这些功能侧重于游戏,但也可以用于其他性能密集型应用。

ADPF 是一组 API,可让游戏和性能密集型应用更为直接地与 Android 设备的电源和散热系统进行互动。借助这些 API,您可以监控 Android 系统上的动态行为,在不造成设备过热问题的可持续界限内优化游戏性能。

以下是主要的 ADPF 功能:

  • Thermal API:监控设备的热状态,以便应用可以在工作负载变得不可持续之前主动调整工作负载。
  • CPU 性能提示 API:提供性能提示,让 Android 为工作负载选择合适的性能设置(例如 CPU 工作点或核心)。
  • Game Mode API 和 Game State API:根据用户设置和游戏专用配置,通过确定性能或电池续航时间特征的优先级来优化游戏体验。
  • 固定性能模式:在进行基准化分析时在设备上启用固定性能模式,以获取不会因动态 CPU 时钟设置而更改的测量结果。
  • 能效模式:告知会话,性能提示会话中的线程可以安全地调度,以优先考虑能效而非性能。适用于 Android 15(API 级别 35)。

如何在原生 Android 项目中使用 ADPF

将自适应功能集成到原生游戏中 Codelab 会引导您将 ADPF 功能集成到游戏中,您可以按照自己的节奏完成这些步骤。完成此 Codelab 后,您将集成以下功能:

  • Thermal API:监听设备热状态,并在设备进入热节流状态之前做出反应。
  • Game Mode API:了解玩家的优化偏好(最大限度提升性能或节省电池),并据此进行调整。
  • Game State API:让系统了解游戏的运行状态(加载、运行、界面等),以便系统相应地调整资源(提升 I/O 或 CPU、GPU 等)。
  • Performance Hint API:让系统了解您的线程模型和工作负载,以便系统相应地分配资源。

如何在 Unity 游戏引擎中使用 ADPF

Unity 的自适应性能是一款面向游戏开发者的工具,旨在帮助开发者优化游戏在移动设备上的表现,尤其是在多样化的 Android 生态系统中。借助自适应性能,游戏可以实时适应设备的性能和散热特性,从而确保流畅高效的游戏体验。

自适应性能 Android 提供程序会引导您完成在 Unity 中实现 ADPF 的步骤。

“项目设置”对话框。
图 6. 在 Unity 引擎中集成 ADPF。

如何在 Unreal 游戏引擎中使用 ADPF

“项目设置”对话框。
图 7. 在 Unreal Engine 中集成 ADPF。
  1. 下载插件
  2. 将插件复制到项目插件文件夹中
  3. 在 Unreal 编辑器中启用 ADPF Unreal Engine 插件
  4. 重新启动 Unreal 编辑器
  5. 构建并烹饪游戏

适用于 Unreal EngineAndroid 动态性能框架(ADPF) 插件可提供稳定的性能并防止热节流。 从 GitHub 下载该插件。此插件通过设置 Unreal 控制台值来更改功能。