我正在尝试确定(在1毫秒内)何时在Android上发生特定屏幕翻转。每次帧翻转时,编舞者都会触发,但无法确定实际显示哪个帧。根据{{3}},在这个过程中有几个层:用户陆地缓冲区,它翻转到三重缓冲队列,翻转到表面翻转,翻转到硬件。这些层中的每一层都可能丢弃一个帧,但此时我只确定了如何监视用户的陆地缓冲区。有没有办法监控其他缓冲区/翻转(实时,在非根,非自定义手机上)?
我观察到HTC M8出现意外帧延迟(每5分钟约1次),但Nexus 7似乎没有出现此问题。我使用带有光电传感器和实验室流层(https://source.android.com/devices/graphics/architecture.html)的Cedrus StimTracker(http://cedrus.com/stimtracker/)来测量延迟。我已经尝试使用eglPresentationTimeANDROID来控制何时翻转屏幕,而这并没有解决问题。
请注意,我正在使用ndk,但我通常可以在需要时使用JNI来访问非ndk功能。
我关心的原因是为了使用Android进行心理和神经学实验,非常需要1 ms的精度。
答案 0 :(得分:2)
就可访问的API而言,听起来你已经找到了相关的点点滴滴。如果您还没有,请仔细阅读this stackoverflow item。
使用Choreographer和外推法,您可以猜测下一次显示刷新的时间。在Android 5.0+设备上使用eglPresentationTimeANDROID()
,您可以在需要将特定帧发送到显示器时告诉SurfaceFlinger。假设SurfaceFlinger正确地考虑了所有延迟(例如由" smart"面板添加的额外帧),那么应该可以获得可靠的时间。
(请记住,时间是基于显示器锁定下一帧的时间,而不是下一帧在显示器上完全可见的时间......延迟将取决于面板。)
Grafika's"预定交换" Activity使用此功能,但听起来你已经熟悉了。
显示器在进行交换时发出信号的唯一方法是从前一帧dup()
显示 - 退出栅栏fd,然后等待它。 SurfaceFlinger中的一些代码就是这样做的,特别是DispSync监视退役围栏以查看软件" VSYNC"漂流。没有用于围栏的公共API,并且用户空间响应时间肯定可能超过1毫秒......它通常比预先做好反应更好。您对非root用户非自定义设备的要求会导致此问题。
如果您主要看到正确的行为,但偶尔会看到错过,最好的办法是使用systrace来追踪原因。