【问题标题】:Determine exact screen flip times on Android在 Android 上确定准确的屏幕翻转时间
【发布时间】:2016-02-04 23:45:49
【问题描述】:

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

我在 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 毫秒的精度是非常理想的。

【问题讨论】:

    标签: android performance android-ndk vsync surfaceflinger


    【解决方案1】:

    就可访问的 API 而言,听起来您已经找到了相关的点点滴滴。如果您还没有,请仔细阅读this stackoverflow item

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

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

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

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

    如果您看到的大部分行为是正确的,但偶尔会出现失误,那么最好的办法是使用 systrace 来追查原因。

    【讨论】:

    • 感谢法登。 “使用 Choregorapher 和外推……使用 eglPresentationTimeANDROID()……这应该可以让你获得可靠的时间。”这是我做的测试。不幸的是,它并没有在 HTC M8 上产生可靠的计时。典型的延迟随着外推值的增加而变化,所以我知道我正在正确使用该函数。同样不幸的是,systrace 不适用于 HTC M8。见stackoverflow.com/questions/32185412/…。如果没有更多工具,我们可能不得不将 HTC M8 列入科学不推荐名单。
    • 每台 Android 设备都是一片特殊的雪花。根据您的要求,创建白名单可能更安全。如果您特别有动力,您可能能够植根 M8 并安装启用 systrace 的内核,但您有可能更换任何导致不稳定的组件,这对于该设备来说非常有用,但有点失败目的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-07
    相关资源
    最近更新 更多