【问题标题】:Is double buffering needed any more是否需要双缓冲
【发布时间】:2011-07-01 05:28:17
【问题描述】:

由于今天的卡片似乎保留了渲染命令列表并且仅在调用 glFlushglFinish 时刷新,所以真的需要双缓冲吗?我正在使用 SDL/OpenGL 在 Linux(ATI Mobility radeon 卡)上开发的 OpenGL 游戏实际上在将 SDL_GL_swapbuffers() 替换为 glFinish() 并在 init 代码中使用 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,0) 时闪烁较少。这是我卡的特殊情况还是所有卡都可能出现这种情况?

编辑:我发现造成这种情况的原因是 KWin。似乎正如 datenwolf 所说,没有同步的合成是原因。当我关闭 KWin 合成时,游戏运行良好,无需任何源代码补丁

【问题讨论】:

    标签: opengl sdl-opengl


    【解决方案1】:

    双缓冲和glFinish 是两个截然不同的东西。

    glFinish 阻塞程序,直到所有绘图操作完成。

    双缓冲用于向用户隐藏渲染过程。如果没有双缓冲,假设显示刷新频率无限高,每一个绘图操作都会立即变得可见。在实践中,您会得到一些显示伪影,例如场景的某些部分在一种状态下可见,其余部分不可见或在某些其他状态下,图片可能不完整等。双缓冲通过首先渲染到后台缓冲区来避免这种情况,并且只有在渲染完成后才将其与前端缓冲区交换回来,然后才会发送到显示设备。

    现在合成窗口管理变得很流行:Windows 有 Aero、MacOS X Quartz Extreme,在 Linux 上至少 Unity 和 GNOME3 shell 使用合成(如果可用)。关键是:从技术上讲,合成创建了双缓冲:Windows 绘制到屏幕外缓冲区,最终屏幕被合成。因此,如果您在一台具有合成功能的机器上运行,那么如果在您的程序中执行双缓冲,那么双缓冲是一种冗余,而它所需要的只是某种同步机制,以便在下一帧准备好时告诉合成器。 MacOS X 有这个。 X11 仍然缺少适当的同步方案,请参阅邮件列表中的这篇文章:http://lists.freedesktop.org/archives/xorg/2004-May/000607.html

    TL;DR:双缓冲和glFinish 是不同的东西,你需要双缓冲(某种形式的)来让事情看起来更好。

    【讨论】:

    • 所提及的帖子已超过 6 年。 X11 是否还缺少同步方案?那么 Windows 呢?
    • 除了 datenwolf 的解释之外,您应该注意,您通常永远不会想要致电 glFlushglFinish,除非在一些非常非常非常罕见的特殊情况下案例。 glFinish 没有做任何 (wgl|glx)SwapBuffers 没有做的事情(假设 vsync 已启用),并且 glFlush 只刷新排队的命令并通知服务器开始处理它们,这在最好的情况下什么都不做(但它是无用的调用和上下文切换),并在最坏的情况下导致更差的性能(因为 GPU 资源的次优调度)。
    • 理想情况下,您将希望尽可能多地在 GL 上抛出命令,并尽可能地传播依赖关系(即,如果您使用纹理,首先发送命令来定义纹理图像,设置纹理状态等,然后发送一些执行其他操作的命令,然后才绘制使用该纹理的东西)。这确保 a) 命令流中的命令不太可能因为依赖关系而阻塞,并且 b) 如果队列中的命令停止,驱动程序可以安排其他一些命令来利用 GPU(OpenCL 或其他程序?)。
    • 这样,您的程序应该始终保持以最大速度运行而没有任何延迟(永远不要休眠等!),并且垂直同步会在适当的时候阻止它并且不会造成伤害。因此,您的程序不会消耗 100% CPU,而是以最佳速度运行。
    • @Sudarshan S:不幸的是,没有,那里没有真正的优势,这是一个遗憾。虽然这确实是必要的,但不得不承认这个话题非常重要。 ATM 这通过使用 XDamage 扩展来告诉合成器图像已经完成。但是您仍然需要完成任务,如何在下一次 VSync 之前保持空白。如果您只是 glXSwapBuffers,您将引入一帧延迟,因为 glXSwapBuffers 也会阻塞您的程序。
    【解决方案2】:

    我希望它更多地与您正在渲染的内容或您的硬件有关,而不是任何可以推广到不在您的机器上的东西。所以不:不要尝试这样做。

    哦,别忘了multisampling。许多实现只对后台缓冲区进行多重采样;前缓冲区未进行多重采样。进行交换将从多重采样缓冲区中下采样。

    【讨论】:

      猜你喜欢
      • 2010-12-22
      • 1970-01-01
      • 2012-07-31
      • 2022-11-20
      • 2021-10-01
      • 2011-02-17
      • 2012-12-01
      • 1970-01-01
      相关资源
      最近更新 更多