我在一个简单的2D游戏中使用自定义视图画布绘图(postInvalidate())和HardwareAcceleration。经过几周的性能分析,我决定通过接口Choreographer.FrameCallback将更新和绘图操作与VSYNC脉冲同步。我认为这是获得平稳运动的正确方法。
然而,我仍然经历着波涛汹涌的运动。我用系统分析了它,并注意到这与我的BufferQueue有关。一旦双缓冲启动,帧时间就超过16 As。我用一些解释对我的追踪做了一个截图:

整个绘制操作等待SurfaceFlinger (使用者)的缓冲区释放,以排除它自己的新的空缓冲区。
你能告诉我这是否是一种正常的行为,或者是什么原因?
发布于 2016-07-23 04:09:25
在您的图表上,您有一个注释,"SurfaceFlinger错过了VSYNC“。
但是,如果查看BufferQueue行,可以看到缓冲区是在VSYNC截止日期之后到达的。SurfaceFlinger醒了,但没什么可做的。
您的应用程序随后提供了一个额外的缓冲区,这意味着您有两个缓冲区待定。由于您继续在每个VSYNC上提供一个缓冲区,所以队列从未恢复到零缓冲区。在队列已满的情况下,每次添加额外缓冲区的尝试都会导致阻塞。
FWIW,您的BufferQueue是三缓冲的:两个在队列中,一个在显示中。
有几件事你可以做:
#2只在SurfaceView上使用GLES,所以我们可以忽略它。
#1可能对您有用;您可以看到一个Grafika的例子。它本质上说,“如果下一个VSYNC在小于2ms的时间内启动,或者已经启动了,那么就不用去渲染当前的帧了。”尽管视图/无效方法没有给您提供与GLES相同的细粒度控制,所以我不确定它的工作效果如何。
在繁忙的设备上平滑动画的关键不是在60 key时击中每个帧。关键是使您的更新基于增量时间,所以事情看起来很顺利,即使你丢下一两帧。
有关图形体系结构的详细信息,请参阅这位医生。
https://stackoverflow.com/questions/38269416
复制相似问题