openGL 中的帧速率和绘制流程

Posted

技术标签:

【中文标题】openGL 中的帧速率和绘制流程【英文标题】:Frame Rate and draw flow in openGL 【发布时间】:2014-12-25 12:41:53 【问题描述】:

我似乎无法理解帧绘制如何与缓冲区交换同步。

以下是问题:

1.由于大多数开放式 GL 调用都是非阻塞(或缓冲)的,您如何知道 gpu 是否已完成当前帧?

2.open GL 是否会处理它,以便未完成的帧不会被交换到窗口缓冲区

3.如何计算帧率?我的意思是确定绘制的帧数或每帧花费的时间的依据是什么?

【问题讨论】:

相关:***.com/a/24136893/524368 @datenwolf 没错!优点 【参考方案1】:

与 GL 同步的现代方式是使用 sync objects。使用glFinish()(或其他阻塞GL 调用)的缺点是会使GPU 和CPU(线程)都停顿:CPU 将等到GPU 完成,然后GPU 因为没有新的工作排队而停顿。如果同步对象使用得当,两者都可以完全避免。

您只需在您感兴趣的任何时候将 fence sync 插入到 GL 命令流中,然后可以检查之前是否所有命令都已完成,或者您可以等待完成(同时你仍然可以有更多的命令排队)。

请注意,对于帧速率估计,您不需要任何明确的同步方式。只需使用SwapBuffers() 就足够了。 gpu 可能会提前排队几帧(nvidia 驱动程序甚至对此进行了设置),但这不会干扰 fps 计数,因为只有前 n 帧排队。只需计算每秒发出的SwapBuffer() 呼叫数,您就可以了。如果用户开启了sync to vblank,帧率会被限制为显示器的刷新率,不会出现撕裂现象。

如果您需要更详细的 GPU 计时统计信息(但对于帧速率计数器,您不需要),您应该查看timer queries。

【讨论】:

我需要将此扩展到另一个问题 那么完成通话是贬值还是不鼓励? 此外,将绘图调用与程序计算同步似乎仍然是一个活跃的话题,并且没有标准化 @Allahjane: glFinish() 没有被弃用,它仍然存在于现代核心配置文件中。但应该小心使用。在一个普通的 OpenGL 程序中,很少(而且通常从不)需要它。过去在共享上下文的多线程情况下需要它,但同步对象也是一个更好的选择。 对!东西终于进入了我的脑海【参考方案2】: 问题12:调用glFinish()而不是glFlush()

说明

glFinish 在所有先前调用的 GL 命令的效果完成之前不会返回。此类影响包括对 GL 状态的所有更改、对连接状态的所有更改以及对帧缓冲区内容的所有更改。

问题3:启动一个Timer,计算一秒钟内对glFinish()的调用次数。

【讨论】:

错误是标准方法吗?我还没有看到任何使用 glFinish 或 glFlush 的 GL 应用程序代码!或者也许只是我 据我所知。我很想看到你对此的回答。 我还需要更多关于 Q.2 的信息 您必须查看 OpenGL 的一种实现才能以您想要的详细程度回答该问题。 当您调用glFinish() 时,可以保证此函数只会在帧成功绘制到屏幕后返回。所以再次回答问题 2,YES【参考方案3】:
    通常,您不会。而且我想不出一个很好的理由为什么您应该在实际应用程序中担心它。如果您真的知道,使用同步对象(正如@derhass 的回答中已经建议的那样)是现代 OpenGL 中的最佳选择。但是你应该确保你清楚地了解你为什么需要它,因为这对我来说似乎很不寻常。 是的。虽然 OpenGL 中调用的处理大多是异步的,但调用的顺序仍然保持不变。因此,如果您进行SwapBuffers 调用,它将保证您在SwapBuffers 调用之前进行的所有调用都将在交换缓冲区之前完成。 没有简单的方法可以测量单个帧所用的时间。最实用的方法是渲染足够长的时间(至少几秒钟似乎是合理的)。您计算在此期间渲染的帧数,以及经过的挂钟时间。然后将帧数除以获得帧速率所需的时间。

上面的一些内容被稍微简化了,因为这开辟了一些可能非常广泛的领域。例如,您可以使用计时器查询来测量 GPU 处理给定帧所需的时间。但是你必须小心你从中得出的结论。

作为一个假设示例,假设您以 60 fps 的速度渲染,受垂直同步的限制。您在帧上放置了一个计时器查询,它告诉您 GPU 花了 15 毫秒来渲染该帧。这是否意味着您能够保持 60 fps 的极限是正确的?并且使您的渲染/内容更复杂会使其低于 60 fps?不必要。除非您还跟踪了 GPU 时钟频率,否则您不知道 GPU 是否真的在其极限运行。电源管理可能已将频率/电压降低到处理当前工作负载所需的水平。如果你给它更多的工作,它可能能够很好地处理它,并且仍然以 60 fps 的速度运行。

【讨论】:

以上是关于openGL 中的帧速率和绘制流程的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 VBO 和单个 OpenGL drawelements 调用绘制多个对象?

OpenGL - 004通过简单案例介绍绘制渲染流程

OpenGL学习脚印: 绘制一个三角形

Android OpenGL学习:最小系统绘制

Android游戏:Canvas还是OpenGL?

android帧的绘制过程以及fps的获取