我试图更好地了解Android显示子系统,但仍然令我感到困惑的是如何处理VSYNC信号,以及为什么这么多信号最初存在。
Android旨在使用VSYNC作为其核心,但是它采用了多个VSYNC信号。通过“VSYNC偏移”部分中的https://source.android.com/devices/graphics/implement.html,有一个流程图,其中绘出了三个VSYNC信号:HW_VSYNC_0,VSYNC和SF-VSYNC。我知道HW_VSYNC用于更新DispSync中的时序,而VSYNC和SF-VSYNC由应用程序和Surfaceflinger使用,但是为什么这些单独的信号根本没有必要?此外,偏移量如何影响这些信号?是否有可用的时序图更好地解释了这一点?
谢谢你的尽心帮助。
最佳答案
为了理解这些内容,最好从System-Level Graphics Architecture文档开始,特别要注意“三重缓冲的需求”部分和相关的图(理想情况下是动画GIF)。开头为“如果应用程序开始在VSYNC信号之间进行渲染的中途”的句子专门讨论了DispSync。阅读完这些内容后,希望设备图形文档的DispSync部分更有意义。
大多数设备未配置DispSync偏移,因此实际上只有一个VSYNC信号。接下来,我假设DispSync已启用。
硬件仅提供一个VSYNC信号,对应于主显示刷新。其他的则由SurfaceFlinger DispSync代码在软件中生成,以与实际VSYNC的固定偏移触发。一些聪明的软件被用来防止时序错位。
这些信号用于触发SurfaceFlinger合成和应用渲染。如果按照体系结构文档中的部分进行操作,则可以看到这在应用程序呈现其内容与屏幕上显示内容之间建立了两帧延迟。可以这样想:在出现了3个VSYNC的情况下,应用程序在V0处进行绘制,系统在V1处进行构图,然后将合成的帧发送到V2处的显示。
如果您试图跟踪触摸输入,或者在用户手指下四处移动 map ,则任何延迟都将被用户视为迟钝的触摸响应。目标是最大程度地减少等待时间,以改善用户体验。假设我们稍微延迟了事件,因此应用程序在V0.5上绘制,在V1.2上进行合成,然后在V2上切换到显示。通过抵消应用程序和SF Activity ,我们将总延迟从2帧减少到1.5,如下所示。
这就是DispSync的目的。在您链接的页面的反馈图中,HW_VSYNC_0是物理显示器的硬件刷新,VSYNC导致应用程序渲染,SF_VSYNC导致SurfaceFlinger执行合成。将它们称为“VSYNC”有点用词不当,但是在LCD面板上,将任何东西称为“VSYNC”都可能是用词不当。
反馈回路图中指出的“退休围栏时间戳”是指聪明的优化。由于我们不在实际的硬件VSYNC上进行任何工作,因此如果关闭刷新信号,我们的效率可能会略高一些。 DispSync代码将改用退休围栏上的时间戳(这是另一个完整的讨论),以查看它是否不同步,并将暂时重新启用硬件信号,直到它回到正常轨道为止。
编辑:您可以看到如何在Nexus 5 boardconfig中配置值。注意VSYNC_EVENT_PHASE_OFFSET_NS
和SF_VSYNC_EVENT_PHASE_OFFSET_NS
的设置。
关于android - 了解Android VSYNC信号的必要性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27947848/