3

我试图确定(在 1 毫秒内)Android 上发生特定屏幕翻转的时间。每次帧翻转时,Choreographer 都会触发,但无法确定实际显示的是哪一帧。根据https://source.android.com/devices/graphics/architecture.html,这个过程有好几层:用户登陆缓冲区,它翻转到一个三缓冲队列,它翻转到表面flinger,它翻转到硬件。这些层中的每一层都可能会丢帧,但此时我只确定了如何监控用户空间缓冲区。有没有办法监控其他缓冲区/翻转(实时,在无根、非自定义手机上)?

我在 HTC M8 上观察到了意外的帧延迟(大约每 5 分钟 1 次),但 Nexus 7 似乎没有这个问题。我使用带有照片传感器和实验室流层 ( https://github.com/sccn/labstreaminglayer ) 的 Cedrus StimTracker ( http://cedrus.com/stimtracker/ )来测量延迟。我尝试使用 eglPresentationTimeANDROID 来控制何时翻转屏幕,但这并没有解决问题。

请注意,我使用的是 ndk,但我通常可以在需要时使用 JNI 来访问非 ndk 功能。

我关心的原因是为了将 Android 用于心理和神经学实验,其中 1 毫秒的精度是非常可取的。

4

1 回答 1

2

就可访问的 API 而言,听起来您已经找到了相关的点点滴滴。如果您还没有,请通读这个 stackoverflow 项目

使用 Choreographer 和外推,您可以猜测下一次显示刷新的时间。在 Android 5.0+ 设备上使用eglPresentationTimeANDROID()时,您可以告诉 SurfaceFlinger 何时要将特定帧发送到显示器。假设 SurfaceFlinger 正确考虑了所有延迟(例如“智能”面板添加的额外帧),这应该可以让您获得可靠的计时。

(请记住,时间基于显示器锁定下一帧的时间,而不是下一帧在显示器上完全可见的时间……延迟取决于面板。)

Grafika 的“scheduled swap”Activity 使用了这个功能,不过听起来你已经很熟悉了。

在进行交换时,显示器发出信号的唯一方法是dup()从前一帧到 display-retire fence fd,然后等待它。SurfaceFlinger 中的一些代码会执行此操作,特别是 DispSync 会监视退休围栏以查看软件“VSYNC”是否正在漂移。没有用于栅栏的公共 API,而且用户空间响应时间肯定会超过 1 毫秒……通常提前安排比做出反应更好。您对非根非自定义设备的要求使这成为问题。

如果您主要看到正确的行为,但偶尔看到未命中,最好的办法是使用systrace来追踪原因。

于 2016-02-05T05:30:09.657 回答