在开发或优化 Android 游戏时,了解引擎正在使用的图形流水线通常很有帮助;引擎可能会选择 Vulkan 或 GLES,但没有明确的开发者可访问信号。遗憾的是,在某些情况下,依靠 logcat 来验证游戏是否在 Vulkan 上运行或是否已静默回退到 OpenGL ES 可能并不可靠。
本指南介绍了如何使用 Android Performance Analyzer (APA) 和自定义 Perfetto SQL 查询来明确识别游戏的有效渲染 API。
基于日志的验证的限制
- 精简日志:生产 build 通常会隐藏初始化和驱动程序加载轨迹。
- 误报:某些游戏引擎在启动期间会同时加载 Vulkan 和 OpenGL ES 库,并打印两者的初始化日志,即使其中一个最终失败并触发回退也是如此。
- 静默回退:如果 Vulkan 初始化因设备特定的驱动程序问题而失败,引擎通常会回退到 OpenGL ES,而不会抛出严重错误。
使用 APA 进行衡量
借助 Android Performance Analyzer,您可以记录系统轨迹,并通过 SQL 查询精确分析帧数据。请按以下步骤操作,以衡量 Vulkan 和 GLES 的使用情况:
使用 APA 捕获轨迹:运行游戏,并使用 APA 在您要分析的细分期间(例如游戏过程中您怀疑出现掉帧的点)捕获系统轨迹。设备连接完毕且轨迹记录完成后,轨迹数据会加载到 APA 界面中。
点击 APA 中的“SQL”标签页:当轨迹分析界面打开时,在界面的导航菜单中,点击 SQL 标签页以打开轨迹处理器环境,您可以在其中直接查询数据。
在 APA SQL 标签页中粘贴以下 SQL 查询:复制以下 SQL 查询并将其粘贴到查询输入字段中。此查询会扫描轨迹,以查找绘制 API 事件,例如
eglSwapBuffers、QueuePresentKHR和vkQueuePresentKHR。它按进程名称对它们进行分组,并计算渲染 API 调用次数以及 Vulkan 与 OpenGL ES 渲染调用次数的百分比分布:WITH raw_slices AS ( -- 1. Map each slice (API call) to its corresponding process or package via UTID and UPID SELECT p.name AS process_name, s.name AS slice_name FROM slice s JOIN thread_track tt ON s.track_id = tt.id JOIN thread t USING (utid) JOIN process p USING (upid) WHERE (s.name LIKE 'eglSwapBuffers%' OR s.name IN ('QueuePresentKHR', 'vkQueuePresentKHR')) -- Optional: To isolate your game, uncomment the following and filter by package name and thread name: -- AND p.name = 'com.example.mygame' -- AND t.name = 'RenderThread' ), process_stats AS ( -- 2. Aggregate counts per individual process SELECT process_name, SUM(CASE WHEN slice_name LIKE 'eglSwapBuffers%' THEN 1 ELSE 0 END) AS egl_count, SUM(CASE WHEN slice_name IN ('QueuePresentKHR', 'vkQueuePresentKHR') THEN 1 ELSE 0 END) AS vulkan_count FROM raw_slices GROUP BY process_name ), process_totals AS ( -- 3. Calculate total counts for denominator calculation SELECT process_name, egl_count, vulkan_count, (egl_count + vulkan_count) AS total_count FROM process_stats ) -- 4. Calculate final percentage shares per row, preventing division by zero errors SELECT process_name, egl_count, vulkan_count, total_count, ROUND(CAST(egl_count AS REAL) * 100 / NULLIF(total_count, 0), 2) AS "egl_percentage(%)", ROUND(CAST(vulkan_count AS REAL) * 100 / NULLIF(total_count, 0), 2) AS "vulkan_percentage(%)" FROM process_totals ORDER BY total_count DESC;运行查询:点击输入字段附近的运行查询按钮。 查询运行后,结果窗格中会显示一个表格,其中包含进程名称 (
process_name)、OpenGL ES 呈现次数 (egl_count)、Vulkan 呈现次数 (vulkan_count)、总呈现次数 (total_count) 以及每种 API 的使用百分比(egl_percentage(%)和vulkan_percentage(%))。
屏幕截图:显示了已执行的 SQL 查询以及以表格形式显示的渲染 API 指标
常见误区
避免
SurfaceFlinger混淆:始终将搜索范围限定为游戏的应用程序线程 (RenderThread)。SurfaceFlinger等系统级合成器进程可能会显示表示系统界面渲染的 Vulkan 或 EGL 轨道,而不是游戏的内部渲染流水线。如需隔离游戏,请取消注释主 SQL 查询的WHERE子句中的可选过滤条件,并将'com.example.mygame'替换为游戏的软件包名称:-- AND p.name = 'com.example.mygame' -- AND t.name = 'RenderThread'预热期:始终在游戏的主 3D 场景完全加载后记录轨迹。在启动画面或加载过渡期间捕获可能会导致误导性的初始化。
LevelUp 豁免跟踪要求
如果您使用 Android Performance Analyzer (APA) 捕获轨迹以符合 Google Play Games LevelUp 豁免条件,则轨迹必须满足特定的硬件要求才能有效。
强烈建议您使用目标 Level Up 参考设备之一来捕获轨迹。
此外,为确保验证准确无误,您不得在使用 ANGLE GPU 的设备上获取轨迹。具体而言,您无法使用以下设备来捕获 LevelUp 豁免轨迹:
- GPU 供应商为 SLSI (Samsung) 的任何设备,这些设备使用 AMD Xclipse GPU
- Pixel 11