我想计算FPS来检测基于现有Android评测工具的应用程序的性能问题。
我注意到在Systrace上,它可以记录performTraversals的长度。据我所知,performTraversals执行测量、布局和绘制,其中包括更新框架时的大多数作业。那么performTraversals是否具有足够的代表性来衡量一个帧是否需要60毫秒才能更新?
我还注意到Systrace记录了在SurfaceFlinger上花费的时间。我知道SurfaceFlinger是用来渲染的,但我不知道帧的确切起点和终点。我是否应该将在SurfaceFlinger上花费的时间也考虑到帧速率?(尽管我确实观察到SurfaceFlinger的执行频率高于performTraversals,这意味着SurfaceFlnger可能不一定遵循performTraversals.它也会在其他情况下触发。)
附言:我知道sysdump gfxinfo,但它只能记录128帧(约2秒),而我想要的可能会持续更长时间。
Systrace对于测量FPS总体而言并不有用,但您可以使用帧计数器和System.nanoTime()
来轻松完成这项工作。不过,如果你没有达到目标帧速率,它可以帮助你找出为什么没有。
官方文档提供了一些有用的指针,但有很多信息,交互可能很复杂。要知道的关键是:
- 设备显示面板生成vsync信号。你可以在VSYNC线上看到。每次在1和0之间转换都是一次刷新
- vsync唤醒surfaceflinger,它收集各种窗口的传入缓冲区并对其进行合成(可以使用OpenGL ES本身,也可以通过硬件生成器)
- 如果你的应用程序运行速度快于面板刷新率(通常为60fps),它将阻止等待surfaceflinger(例如
eglSwapBuffers()
)。一旦surfaceflinger获得缓冲区,应用程序就可以自由地继续并生成另一帧 - 除非你在屏幕外渲染,否则你不能比surfaceflinger更快
从Android 4.3(API 18)开始,您可以使用Android.os.Trace类将自己的事件添加到systrace输出中。用痕迹标记包裹你的绘图方法可以提供非常丰富的信息。你必须用systrace启用他们的标签才能看到他们。
如果你想以60fps的速度运行,你的渲染必须在16.7ms以下完成。如果你看到performTraversals
的一次调用需要更长的时间,你就无法达到最高速度。