【问题标题】:PaintGL() call understanding [closed]PaintGL()调用理解[关闭]
【发布时间】:2013-12-04 09:30:32
【问题描述】:

我知道PaintGL() 函数的调用频率与屏幕的频率相同(比如说每秒 60 次)。但是,如果屏幕上没有显示像素(如果另一个窗口隐藏了 OpenGL),则对 PaintGL() 的调用将不再受到限制,并且会被调用更多......它最大程度地使用 CPU 并且很烦人。

那么,有没有办法抑制它?

我正在使用 MacOS 10.9 和 Qt Creator。

我对垂直同步了解不多。事实上,我的软件在前台使用 30% 的 CPU,而在隐藏时,它会上升到 95%。

【问题讨论】:

  • 您是说启用 vsync 后,您的背景窗口不再被 vsync 锁定吗?什么操作系统/图形驱动程序/等?您确定启用了 vsync 吗?
  • 您确定在这种情况下您的PaintGL() 真的会被更频繁地调用吗?我不知道 Qt 的内部结构,但通常在隐藏窗口时根本不应该调用它

标签: c++ opengl


【解决方案1】:

如果您没有启用垂直同步,则尽可能频繁地交换帧(如果您没有添加人为暂停)。如果你在显卡上推高负载,很可能你的程序是 GPU 受限的(CPU 无事可做,等待 GPU 完成绘图)。

当您的程序不可见时,绘制成本几乎为零,因为无论如何都没有人看到结果(由图形驱动程序内部执行优化)。

因此,您的问题的答案是 - 启用 vsync。它将缓冲区交换间隔锁定到显示器的刷新率,因此您的帧率永远不会高于刷新率(事实上,如果您的显示器处于 60 Hz,它将锁定到数字 60/30/20/等)。这是非常有用的技术,例如消除屏幕撕裂。

【讨论】:

  • 我该如何启用垂直同步?
  • 依赖于平台。如果您使用 Qt 的 GL 初始化,请尝试 qtcentre.org/threads/39399-QGraphicsView-opengl-Vsync
  • VSYNC 对于消除屏幕撕裂不再特别有用(在窗口应用程序中)。 OS X 和 Windows 现在都使用合成窗口管理器,您可以在没有 VSYNC 的情况下以全速(例如 12,000 FPS)交换缓冲区,并且窗口管理器本身将通过仅以适当的 VBLANK 间隔更新窗口来防止撕裂。它对于限制渲染速度快于显示器显示图像的应用程序的 CPU/GPU 利用率非常有用。
  • @AndonM.Coleman 不了解 OSX,但在 Windows 上(从 vista 开始)无论我做什么 - 我仍然看到撕裂,除非在启用 vsync 或禁用 aero 的真正全屏模式下不知何故。不知道 8 tho,因为我记得他们移除了 aero,也许现在情况好多了。从未在 linux 上使用过合成 WM,所以从未见过撕裂那里(我的主要环境)。但无论如何,从 vsync 工作原理的核心技术来看 - 我怀疑 WM 是否可以将任意帧速率映射到屏幕刷新(Windows aero 部分证实了这一点)。
  • @keltar:应该反过来。 VSYNC 对于合成窗口管理器是不必要的,因为它们可以使用最后一个完全交换的前缓冲区图像的副本(消除在 VBLANK 间隔之前未完成的交换问题)。当您交换缓冲区时,帧缓冲区不会像以前那样直接进入显示器...窗口管理器将窗口作为单独的绘图过程进行绘制。事实上,在 Microsoft Windows 上,在调度 GPU 方面,DWM 具有任何应用程序的最高优先级。
猜你喜欢
  • 1970-01-01
  • 2013-07-16
  • 1970-01-01
  • 2020-07-24
  • 2011-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-17
相关资源
最近更新 更多