【发布时间】:2014-01-07 21:09:15
【问题描述】:
我有一个非常简单的应用程序,它使用 opengl 渲染一个正方形,输入触摸由 GLSurfaceView 读取,最后位置使用 volatile 变量与渲染线程交换。
我观察到(在https://www.mail-archive.com/android-developers@googlegroups.com/msg235325.html 中也有很好的描述)是触摸位置和显示之间存在延迟(滞后)。
当激活开发者选项以显示触摸位置时,我看到快速移动时:
与我的手指位置相比,系统显示的跟踪触摸位置的圆圈延迟了 1 厘米。我认为这是系统/硬件相关的,无法由应用程序纠正。
但在我的应用程序中呈现的运动在调试圈之后也延迟了 1 厘米。 所以实际上延迟是可能的两倍。
当手指移动变慢时,绘图的最终位置停止,当前触摸位置同步。完全如本视频所示(上述讨论中的链接)http://www.youtube.com/watch?v=fWZGshsXDhM
我仍然对导致第二次延迟的原因一无所知,我已经确定了从 onTouchEvent 到渲染线程的位置交换时间,它只有几毫秒。 渲染频率为 18 毫秒。
我曾尝试使用速度通过预测 18 毫秒后的位置来缩短延迟的出现,但它并没有改变任何延迟感知。
有人解释这种延迟吗? 在 onTouchEvent 中访问之前是由系统层引起的吗?其中 万一我看不出有什么办法纠正它。
google 群里没有具体的答案。另外困扰我的是,在线程中提到延迟通过使用画布而不是OpenGL而消失。这提出了更多它回答的问题。
【问题讨论】:
-
这是输入延迟,这是与异步 CPU/GPU 操作相关的经典问题。大多数 GL 实现将接受并从命令返回,无论它们是否完整,这可能导致在任何给定时间排队的多帧命令。在用户输入产生的命令进入最终显示的图像之前,所有其他排队的命令必须首先完成。另外,您设备的显示屏是否真的以刷新率或 55.5 Hz 运行,或者您是否随意选择了 18 毫秒作为更新间隔?
-
您可以在战略点发出
glFinish (...)以减少“提前渲染”的数量,但您确实违反了实时计算机图形的现代设计原则......保持 CPU 和 GPU 异步工作。这在here进行了简要讨论。 -
@Andon Tbe 的行为看起来确实如您所描述的那样:好像帧已排队。按照您的建议,我尝试调用 glFinish 和 glFlush 但它并没有改变行为。 18ms的时间是平均值,我只是测量一下。
标签: android multithreading opengl-es touch lag