我正在尝试确定(在 1 毫秒内(安卓上何时发生特定屏幕翻转。每次帧翻转时,编舞者都会触发,但无法确定实际显示的是哪个帧。根据 https://source.android.com/devices/graphics/architecture.html 的说法,这个过程有几层:用户土地缓冲区,它翻转到三重缓冲队列,它翻转到表面抛框,它翻转到硬件。这些层中的每一个都可能丢弃一个帧,但此时我只确定了如何监视用户土地缓冲区。有没有办法监控其他缓冲区/翻转(在非根、非自定义手机上实时(?
我在HTC M8上观察到意外的帧延迟(大约每5分钟1次(,但Nexus 7似乎没有这个问题。我通过使用带有光传感器和实验室流层 (https://github.com/sccn/labstreaminglayer( 的赛德思 StimTracker (http://cedrus.com/stimtracker/( 来测量延迟。我尝试使用eglPresentationTimeANDROID来控制屏幕何时翻转,但这并没有解决问题。
请注意,我使用的是 ndk,但我通常可以在需要时使用 JNI 来访问非 ndk 功能。
我关心的原因是为了使用 Android 进行心理和神经学实验,其中 1 毫秒的精度是非常可取的。
就可访问的 API 而言,听起来您已经找到了相关的零碎内容。 如果您还没有,请通读此堆栈溢出项目。
使用编排和外推,您可以猜测下一次显示刷新的时间。 在Android 5.0+设备上使用eglPresentationTimeANDROID()
,您可以告诉SurfaceFlinger何时要将特定帧发送到显示器。 假设SurfaceFlinger正确考虑了所有延迟(例如"智能"面板添加的额外帧(,这应该可以为您提供可靠的时间。
(请记住,时间基于显示屏锁定下一帧的时间,而不是下一帧在显示屏上完全可见的时间......延迟将取决于面板。
Grafika的"计划交换"活动使用此功能,但听起来您已经很熟悉了。
在进行交换时,显示器发出信号的唯一方法是从前一帧dup()
显示器停用围栏 fd,然后等待它。 SurfaceFlinger中的一些代码是这样做的,特别是DispSync监视退役围栏,以查看软件"VSYNC"是否漂移。 围栏没有公共 API,无论如何,用户空间响应时间肯定可以超过 1 毫秒......提前安排通常比做出反应更好。 您对无根非自定义设备的要求使这成为问题。
如果您主要看到正确的行为,但偶尔看到未命中,则最好的选择是使用 systrace 来追踪原因。