确定安卓屏幕翻转的精确时间

3

我正在试图确定Android上特定屏幕翻转发生的时间(精度为1毫秒)。Choreographer每次帧翻转时都会触发,但没有办法确定实际显示哪一帧。根据https://source.android.com/devices/graphics/architecture.html,该过程中有几个层次:用户空间缓冲区翻转到三重缓冲队列,再翻转到表面贴图器,最后翻转到硬件。这些层面中的每一个都可能丢失一帧,但目前我只确定了如何监视用户空间缓冲区。是否有办法监视其他缓冲区/翻转(在非Root、非自定义手机上实时)?

我在HTC M8上观察到意外的帧延迟(大约每5分钟1次),但Nexus 7似乎没有这个问题。我使用Cedrus StimTracker(http://cedrus.com/stimtracker/)和Lab Streaming Layer(https://github.com/sccn/labstreaminglayer)通过光电传感器测量延迟。我尝试使用eglPresentationTimeANDROID来控制屏幕翻转的时间,但这并没有解决问题。
请注意,我正在使用ndk,但通常可以使用JNI来访问非ndk功能。
我关心的原因是为了在心理和神经学实验中使用Android,其中1毫秒的精度非常重要。
1个回答

2
就可访问的API而言,听起来您已经找到了相关的部分。如果还没有,请阅读这个stackoverflow项目
使用Choreographer和外推法,您可以猜测下一个显示刷新将发生的时间。在Android 5.0+设备上使用eglPresentationTimeANDROID(),您可以告诉SurfaceFlinger何时将特定帧发送到显示器。假设SurfaceFlinger正确考虑了所有延迟(例如由“智能”面板添加的额外帧),那么这应该可以获得可靠的时间。
(请记住,时间基于显示器锁存下一帧的时间,而不是下一帧完全出现在显示器上的时间...那里的延迟取决于面板。) Grafika的“scheduled swap”活动使用了这个功能,但听起来您已经很熟悉了。
当显示面板进行切换时,唯一可以通过显示信号来得到通知的方法是从前一帧中dup()显示退役栅栏fd,然后等待它。 SurfaceFlinger中的一些代码会这样做,特别是DispSync会观察退役栅栏以查看软件“VSYNC”是否漂移。没有公共API用于栅栏,用户空间响应时间肯定会超过1ms...通常提前调度比反应更好。您对非root非自定义设备的要求使此变得棘手。如果您大多数情况下看到正确的行为,但偶尔出现错过的情况,最好使用systrace来找出原因。

感谢Fadden。 "使用Choregorapher和外推....使用eglPresentationTimeANDROID()....这应该可以获得可靠的时间。" 这是我做的测试。不幸的是,在HTC M8上它没有产生可靠的时间。典型的延迟随着外推值的增加而改变,所以我知道我正在正确地使用该函数。不幸的是,systrace在HTC M8上无法工作。请参见http://stackoverflow.com/questions/32185412/unable-to-systrace-on-htc-one-m8-lollipop。如果没有更多的工具,我们可能不得不将HTC M8列入不推荐科学列表。 - Matthew Grivich
1
每个Android设备都是独一无二的。根据您的要求,创建一个白名单可能更安全。如果您特别有动力,可以对M8进行root并安装启用systrace的内核,但有可能会替换导致不稳定的任何组件,这对于该设备来说很好,但有些失去了初衷。 - fadden

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接