我正在努力更好地了解Android显示子系统,但仍然让我感到困惑的一个问题是VSYNC信号是如何处理的,以及为什么会有这么多信号存在。
Android的核心是使用VSYNC,但它采用了多种VSYNC信号。通过“VSYNC偏移”部分中的https://source.android.com/devices/graphics/implement.html,可以看到三个VSYNC信号的流程图:HW_VSYNC_0,VSYNC和SF-VSYNC。我知道HW_VSYNC用于更新DispSync中的时序,并且应用程序和surfaceflinger使用VSYNC和SF-VSYNC,但为什么这些单独的信号是必需的?此外,偏移如何影响这些信号?是否有可用的时序图更好地解释了这一点?
感谢您提供的任何帮助。
答案 0 :(得分:23)
要理解这些内容,最好从System-Level Graphics Architecture文档开始,特别注意需要三重缓冲部分和相关图表(理想情况下是动画的) GIF)。开头的句子,“如果应用程序开始在VSYNC信号之间进行渲染”,则专门讨论DispSync。一旦你读完了,希望设备图形文档的DispSync部分更有意义。
大多数设备没有配置DispSync偏移,因此实际上只有一个VSYNC信号。接下来我假设启用了DispSync。
硬件仅提供一个VSYNC信号,对应于主显示器刷新。其他的是由SurfaceFlinger DispSync代码在软件中生成的,在实际VSYNC的固定偏移处触发。一些聪明的软件用于防止时间不同步。
信号用于触发SurfaceFlinger合成和应用渲染。如果您按照体系结构文档中的部分进行操作,则可以看到这在应用程序呈现其内容与内容显示在屏幕上之间建立了两帧延迟。可以这样想:给定三次VSYNC,应用程序在V0处绘制,系统在V1处进行合成,并且组合的帧在V2处被发送到显示器。
如果您正在尝试跟踪触摸输入,可能会在用户的手指下移动地图,则用户会将任何延迟视为缓慢的触摸响应。目标是最小化延迟以改善用户体验。假设我们稍微延迟了事件,因此app在V0.5处绘制,我们在V1.2处合成,然后在V2处交换到显示。通过抵消app和SF活动,我们将总延迟从2帧减少到1.5,如下所示。
这就是DispSync的用途。在您链接的页面上的反馈图中,HW_VSYNC_0是物理显示的硬件刷新,VSYNC使应用程序呈现,SF_VSYNC使SurfaceFlinger执行合成。将它们称为“VSYNC”有点用词不当,但在液晶面板上指的是“VSYNC”可能是用词不当。
反馈回路图中提到的“退役围栏时间戳”指的是一种巧妙的优化。由于我们没有在实际的硬件VSYNC上做任何工作,如果我们关闭刷新信号,我们可以稍微提高效率。 DispSync代码将改为使用退役围栏的时间戳(这是一个完整的其他讨论)来查看它是否失去同步,并暂时重新启用硬件信号,直到它回到正轨。
修改:您可以在Nexus 5 boardconfig中查看值的配置方式。请注意VSYNC_EVENT_PHASE_OFFSET_NS
和SF_VSYNC_EVENT_PHASE_OFFSET_NS
的设置。