2016-02-04 53 views
2

我试图确定(在1毫秒内)何时在Android上发生特定的屏幕翻转。每当画面翻转时,编舞者都会触发,但无法确定实际显示的画面。根据https://source.android.com/devices/graphics/architecture.html,在这个过程中有几个层次:用户登陆缓冲区,它翻转到三重缓冲队列,翻转到表面抛掷,然后翻转到硬件。这些层中的每一层都可能会丢弃一帧,但此时我只确定如何监视用户的陆地缓冲区。有没有办法监视其他缓冲区/翻转(实时,在非根源,非自定义电话上)?在Android上确定确切的屏幕翻转时间

我在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 ms的精度非常可取。

回答

2

就可访问的API而言,听起来好像你已经找到了相关的零件。如果你还没有,请通读this stackoverflow item

使用编排器和外推法,您可以猜测下一次显示刷新何时发生。在Android 5.0+设备上使用eglPresentationTimeANDROID(),您可以在需要将特定帧发送到显示器时告诉SurfaceFlinger。假设SurfaceFlinger正确计算了所有延迟(例如“智能”面板添加的附加帧),那么应该为您提供可靠的时间。

(记住,所述定时是基于当显示锁存下一帧,而不是当所述下一帧在所述显示器上完全可见于...的等待时间有将取决于在面板上。)

Grafika's“计划交换”活动使用此功能,但听起来您已经很熟悉。

当它进行交换时,显示器发出信号的唯一方法是将dup()显示器退出前一帧的退出栅栏fd,然后等待它。 SurfaceFlinger中的一些代码执行此操作,值得注意的是,DispSync监视退休围栏以查看软件“VSYNC”是否漂移。没有用于栅栏的公共API,无论如何用户空间响应时间肯定可以超过1ms ......它通常比预先安排好的反应时间更好。您对非固定非定制设备的要求会造成问题。

如果你大多看到正确的行为,但偶尔会看到一个小姐,你最好的选择是使用systrace追查原因。

+0

谢谢法登。 “使用Choregorapher和推断....使用eglPresentationTimeANDROID()....应该让你得到可靠的时间。”这是我做的测试。不幸的是,它没有导致HTC M8的可靠时机。典型的延迟随着外推值的增加而改变,所以我知道我正确地使用了该功能。不幸的是,systrace在HTC M8上不起作用。请参阅http://stackoverflow.com/questions/32185412/unable-to-systrace-on-htc-one-m8-lollipop。如果没有更多的工具,我们可能不得不将HTC M8推荐到科学列表中。 –

+1

每款Android设备都是特殊的雪花。根据您的要求,创建白名单可能更安全。如果你有特别的动机,你可以根植M8并安装一个支持systrace的内核,但是有可能你会替换导致不稳定的任何组件,这对于那个设备来说很好,但是有点失败目的。 – fadden