【发布时间】:2014-04-30 00:21:45
【问题描述】:
我正在调查我的应用的性能,因为我注意到它在滚动时丢了一些帧。我运行了 systrace(在运行 4.3 的 Nexus 4 上)并注意到输出中有一个 interesting section。
一开始一切都很好。 Zooming in on the left section,我们可以看到绘图在每个 vsync 上开始,并在空闲时间结束,并等待到下一个 vsync。由于它是三重缓冲的,因此它应该被绘制到一个缓冲区中,该缓冲区将在完成后发布到以下 vsync 上。
在放大的屏幕截图中的第 4 次垂直同步中,应用执行了一些工作,但绘制操作没有及时完成下一次垂直同步。但是,我们不会丢弃任何帧,因为之前的抽签是在前一帧进行的。
发生这种情况后,绘制操作并不能弥补错过的垂直同步。相反,每个 vsync 只启动一个绘制操作,现在它们不再向前绘制一帧了。
Zooming in on the right section,该应用程序做了更多工作,但错过了另一个垂直同步。因为我们没有在前面画一个框架,所以实际上这里丢掉了一个框架。在此之后,它会返回到前面绘制一帧。
这是预期的行为吗?我的理解是,如果您错过了一次垂直同步,三重缓冲可以让您恢复,但这种行为看起来每错过两次垂直同步就会丢帧一次。
跟进问题
在this screenshot 的右侧,应用实际渲染缓冲区的速度比显示器消耗缓冲区的速度要快。在 performTraversals #1 期间(在屏幕截图中标记),假设正在显示缓冲区 A,正在渲染缓冲区 B。 #1 在 vsync 之前很久就完成了,并将缓冲区 B 放入队列中。此时,应用程序不应该能够立即开始渲染缓冲区C吗?相反,performTraversals #2 直到下一次 vsync 才开始,浪费了这之间的宝贵时间。
-
与此类似,我对 waitForever on the left side here 的需求感到有点困惑。假设缓冲区 A 正在显示,缓冲区 B 在队列中,缓冲区 C 正在渲染。当缓冲区 C 完成渲染时,为什么不立即将其添加到队列中?相反,它一直等待直到缓冲区 B 从队列中移除,此时它添加缓冲区 C,这就是为什么无论应用程序渲染缓冲区的速度有多快,队列似乎总是保持大小为 1。
李>
【问题讨论】:
标签: android performance systrace