本文章为官方文档译文,仅供个人日后复习使用,如有需求请移步至 https://perfetto.dev/docs/
Slice Details包含的信息
(1) Present Type
frame是提前、准时或者延迟
(2) On time finish
应用程序是否按时完成了frame的工作?
(3) Jank Type
这一帧有没有观察到卡顿? 如果有,这将显示观察到的卡顿类型。 如果不是,则类型将为 **None**。
(4) Prediction type
当 FrameTimeline 接收到这个帧时,是否超过预期时间?如果是,将显示 **Expired Prediction**。否则,**Valid Prediction**。
(5) GPU Composition
判断帧是否由 GPU composition的布尔值。
(6) Layer Name
显示框架的层/表面的名称。 一些进程将帧更新到多个surface。 这时,多个具有相同token的slice将显示在Actual Timeline中。 Layer Name就可以用来区分这些slice。
(7) Is Buffer?
布尔值,它标识frame是对应于buffer还是动画。
颜色信息
Color | Image | Description |
---|---|---|
Green | A good frame. No janks observed | |
Light Green | 高延迟状态。帧速率平滑,但帧呈现延迟,导致输入延迟增加。 | |
Red | 有问题的frame,slice的程序就是frame出现问题的原因 | |
Yellow | 这个颜色只有应用程序才能使用,frame有问题但不是应用程序造成的,是 SurfaceFlinger 造成的。 | |
Blue | 丢帧。与 jank 无关。该帧由 SurfaceFlinger 丢弃, |
Janks类型解释说明
Jank 类型在 JankInfo.h中定义。由于每个应用程序的编写方式不同,因此没有通用的方法可以深入到应用程序的内部,并指定出现问题的原因是什么。我们的目标只是提供一个快速的方法来判断应用程序是否有问题或者 SurfaceFlinger 是否有问题。
(1) None
No jank, 理想状态。
(2) App janks
-
AppDeadlineMissed (应用程序运行时长超出预期)
这个应用程序运行的时间比预期的要长,引起了一次Jank。应用程序frame占用的总时间是通过将choreographer的唤醒作为开始时间和 Max(gpu,post time) 作为结束时间来计算的。post time 是frame发送到 SurfaceFlinger 的时间。由于 GPU 通常是并行运行的,所以 GPU 的完成时间可能晚于post time。
-
Buffer Stuffing
这更像是一种状态而不是卡顿。如果应用在上一帧出现之前不断向 SurfaceFlinger 发送新帧,就会出现这种情况。 内部缓冲区队列中塞满了尚未呈现的缓冲区,因此得名Buffer Stuffing(缓冲区填充)。 队列中的这些额外buffer只是一个接一个地出现,从而导致额外的延迟。 这也可能导致应用程序没有更多的buffer可以使用,并进入一个 dequeue 阻塞等待阶段。 应用程序执行的实际工作持续时间可能仍在截止时间(deadline)内,但由于填充性质,无论应用程序完成其工作的速度有多快,所有帧都将至少延迟一个 vsync 呈现。 在此状态下,帧仍将是平滑的,但与延迟出现相关的输入延迟会增加。
(3) SurfaceFlinger Janks
SurfaceFlinger可以通过两种方式来合成frame
- Device Composition —— 使用专用硬件
- GPU/Client 合成 —— 使用GPU合成
需要注意的一点是,执行Device Composition是作为主线程上的阻塞调用。然而,GPU 合成是并行发生的。SurfaceFlinger 执行必要的绘图调用,然后将 gpu fence移交给显示设备。显示设备等待fence的信号,然后显示帧。
-
SurfaceFlingerCpuDeadlineMissed
SurfaceFlinger 预计在给定的最后期限内完成。如果主线程运行的时间超过这个时间,那么 jank 就是 SurfaceFlingerCpuDeadlineMissed。SurfaceFlinger 的 CPU 时间是花在主线程上的时间。如果使用device composition,则包括整个组合时间。如果使用 GPU composition,这包括编写绘制调用和将帧移交给 GPU 的时间。
-
SurfaceFlingerGpuDeadlineMissed
SurfaceFlinger 的主线程在 CPU + GPU composition上花费的时间比预期的要长。在这里,CPU 时间仍然在预期之内,但是由于 GPU 上的工作没有准时完成,frame被推到下一个 vsync。
-
DisplayHAL
Displayhal Jank是指这样一种情况:SurfaceFlinger完成其工作并按时将框架发送到HAL,但是框架没有在Vsync上呈现。它是在下一个vsync上呈现的。SurfaceFlinger可能没有给HAL的工作提供足够的时间,也可能是 HAL 的工作真的延迟了。
-
PredictionError
SurfaceFlinger 的调度程序提前计划显示帧。但是,这个预测有时会偏离实际的硬件 vsync 时间。例如,一个帧可能预测当前时间为20毫秒。由于估计的漂移,帧的实际现在时间可能是23毫秒。这称为 SurfaceFlinger 调度程序中的预测错误。调度程序会周期性地自我修正,所以这种漂移不是永久性的。然而,有一个预测漂移的帧仍然会被归类为跟踪目的的 jank。
用户通常不会感知独立出现的Prediction Error,因为调度程序可以快速调整和修复偏差。
(4) Unknown jank
顾名思义,在这种情况下,原因是未知的。这里的一个例子是,SurfaceFlinger 或应用程序花费了比预期更长的时间,错过了最后期限,但帧仍然提前呈现。这种情况发生的可能性很低,但并非不可能。
SQL
涉及frametimeline数据的有两个表
-
expected_frame_timeline_slice
-
actual_frame_timeline_slice
select ts, dur, surface_frame_token as app_token, display_frame_token as sf_token, process.name
from expect_frame_timeline_slice left join process using(upid)
select ts, dur, surface_frame_token as app_token, display_frame_token, jank_type, on_time_finish, present_type, layer_name, process.name
from actual_frame_timeline_slice left join process using(upis)
Trace 配置
Datasource
data_source{
config{
name: "android.surfaceflinger.frametimeline"
}
}