首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >双缓冲减慢帧呈现系统分析

双缓冲减慢帧呈现系统分析
EN

Stack Overflow用户
提问于 2016-07-08 14:42:05
回答 1查看 954关注 0票数 2

我在一个简单的2D游戏中使用自定义视图画布绘图(postInvalidate())和HardwareAcceleration。经过几周的性能分析,我决定通过接口Choreographer.FrameCallback将更新和绘图操作与VSYNC脉冲同步。我认为这是获得平稳运动的正确方法。

然而,我仍然经历着波涛汹涌的运动。我用系统分析了它,并注意到这与我的BufferQueue有关。一旦双缓冲启动,帧时间就超过16 As。我用一些解释对我的追踪做了一个截图:

整个绘制操作等待SurfaceFlinger (使用者)的缓冲区释放,以排除它自己的新的空缓冲区。

你能告诉我这是否是一种正常的行为,或者是什么原因?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-07-23 04:09:25

在您的图表上,您有一个注释,"SurfaceFlinger错过了VSYNC“。

但是,如果查看BufferQueue行,可以看到缓冲区是在VSYNC截止日期之后到达的。SurfaceFlinger醒了,但没什么可做的。

您的应用程序随后提供了一个额外的缓冲区,这意味着您有两个缓冲区待定。由于您继续在每个VSYNC上提供一个缓冲区,所以队列从未恢复到零缓冲区。在队列已满的情况下,每次添加额外缓冲区的尝试都会导致阻塞。

FWIW,您的BufferQueue是三缓冲的:两个在队列中,一个在显示中。

有几件事你可以做:

  1. 如果你错过了截止日期,让应用程序删除帧。
  2. 指定框架的演示时间,这样如果时间过了,SurfaceFlinger就会删除它们。
  3. 每隔一段时间故意丢弃一个帧,让队列空。(不是首选的办法)。

#2只在SurfaceView上使用GLES,所以我们可以忽略它。

#1可能对您有用;您可以看到一个Grafika的例子。它本质上说,“如果下一个VSYNC在小于2ms的时间内启动,或者已经启动了,那么就不用去渲染当前的帧了。”尽管视图/无效方法没有给您提供与GLES相同的细粒度控制,所以我不确定它的工作效果如何。

在繁忙的设备上平滑动画的关键不是在60 key时击中每个帧。关键是使您的更新基于增量时间,所以事情看起来很顺利,即使你丢下一两帧。

有关图形体系结构的详细信息,请参阅这位医生

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38269416

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档