【问题标题】:Swap Buffers and Clear Back using windowing system (GLX)使用窗口系统 (GLX) 交换缓冲区和清除返回
【发布时间】:2016-03-31 14:39:26
【问题描述】:

在后台缓冲区和前台缓冲区之间交换时,后台缓冲区中的内容变得未定义。我想使用“窗口系统”来定义它,例如 GLX、EGL、WGL。使用诸如 OpenGL (glClear) 之类的“本机”渲染器是我的后备计划,不必费心提及它。它是备份的原因是因为我不想弄乱本机渲染上下文。对于这个问题,我会坚持使用 X/GLX,但如果您倾向于描述如何在其他环境中执行此操作,请继续。

从 Xlib 文档 (http://www.x.org/docs/X11/xlib.pdf) 我找到了一个操作 XClearWindow,用于清除带有“背景像素”的窗口(顺便说一句真棒的名字......不是)。

  1. XClearWindow 是清除前/后缓冲区还是同时清除两个缓冲区?我猜后台缓冲区是有道理的,但我无法仅从 Xlib 文档中弄清楚......如果有人问起三重缓冲区,那不是我!
  2. 是与 OpenGL 渲染同步,还是我必须通过例如在操作前调用 glxWaitGL 来同步自己?
  3. 命令是否阻塞,即暂停直到完成?依赖于实现?

关于如何在使用窗口系统 (GLX) 进行交换后清除后台缓冲区的其他建议已得到应用。

干杯!

【问题讨论】:

    标签: c++ x11 xlib egl glx


    【解决方案1】:

    当在后台缓冲区和前台缓冲区之间交换时,后台缓冲区中的内容变得未定义。

    是的,这是一件好事。

    我想使用“窗口系统”来定义它,例如 GLX、EGL、WGL

    为什么?除此之外,这样做是未定义的,因为交换后的背景不会有任何好处。

    如果 OpenGL DDX 知道它将同步的 XClearWindow,它充其量只会降低性能。在最坏的情况下,您会引入一种竞争条件,其结果是不可预测的。

    关于如何在使用窗口系统 (GLX) 进行交换后清除后台缓冲区的其他建议已得到应用。

    使用正确的 OpenGL 操作:glClear(…)

    【讨论】:

    • 如果我在交换后定义内容,它是按定义定义的,因为我刚刚定义了它。因为窗口系统交换不会降低性能,所以有理由相信(但未证明)窗口系统清除不会降低性能。而且OpenGL不是一个窗口系统。使用 glClear 是已知的备份计划,我明确要求您不要费心提及它。至于我的宏伟计划,其中这块拼图将保证统治世界,你不应该打扰。告诉我你对 OpenGL 的窗口系统同步的了解。
    • @Andreas 我可以定义*NULL 以产生值0xDEADBEEF,但如果实现不遵守该定义,那将完全没有用。是什么让您认为窗口系统的 clear 比您的 OpenGL 实现的 glClear 更高效?你的问题闻起来像XY Problem
    • @Andreas:你几乎不会得到比glClear 更高的性能。 XClearWindow 实际上可能会执行复杂的填充操作(用定义的背景平铺填充窗口)。此外,XClearWindow 的主要实现可能会实现为 CPU 驱动的内存写入 GPU 内存。它可能有也可能没有 DMA 辅助,但它永远不会像 GPU 标记 将整个内存区域设置为特定值的单个命令那样快。注意我写的是 "marking":
    • @Andreas:大多数现代 GPU 实际上只是为每个内存块设置一个标志,以假设它具有统一的值。同样在 GLX 直接渲染模式下,OpenGL 命令完全绕过 X 服务器。此外,XClearWindow 可能会创建一个Exposed 事件,并且窗口后台缓冲区的内容在被Expose-ed 之后是未定义,所以这只会让你回到你开始的地方。
    • @Andreas:我想知道你为什么要专门询问glClear。不过我有一个怀疑:您是否计算了glClear 执行所需的时间,您是否在配备英特尔 GPU 的系统上对其进行了测量,并且您得出的数字大约是一个显示刷新周期(对于 60Hz 的显示器,大约需要 16.666 毫秒)?如果是这种情况,您实际观察到的是,Mesa/Intel 驱动程序的 glXSwapBuffers 立即返回;此后修改后台缓冲区的下一个非队列 OpenGL 操作将被延迟,直到缓冲区交换实际发生。
    【解决方案2】:

    经过一番研究,我可能找到了解决方案。这些文件似乎是有序的,但我没有机会在实践中对此进行测试。一旦我得到一些工作,我会用代码更新答案。

    XClearWindow 是清除前/后缓冲区还是同时清除两个缓冲区?

    X 没有双缓冲区的概念。每当与 X 对双缓冲窗口进行交互时,两个缓冲区都会受到影响。例外是读取操作,例如 XGetImage,它只对前端缓冲区进行操作。

    然而,X 通过 X 双缓冲区扩展或 xdbe 使用双缓冲区概念进行扩展:http://www.x.org/releases/X11R7.6/doc/xextproto/dbe.html#dbeswapbuffers

    xdbe 提供类似于 GLX 提供的glxSwapBuffersXdbeSwapBuffers 操作。有一些重要的区别:

    • XdbeSwapBuffers 不管理与任何客户端的任何同步 像 glxSwapBuffers 这样的 API。用户必须手动执行此操作。幸运的是,GLX 提供了出色的 不会停止的同步操作(glxWaitGLglxWaitX) 执行。这几乎回答了我的第二个问题。
    • glxSwapBuffers 为当前执行隐式刷新 (glFlush) 语境。 XdbeSwapBuffers 没有。何时冲洗或不冲洗是一个 应用程序设计者的决定。
    • XdbeSwapBuffers 可以在一次调用中交换多个窗口。
    • XdbeSwapBuffers 在交换时可能有不同的行为: “未定义”、“背景”、“未触及”、“已复制”。阅读链接 了解详情。

    要在交换为预定义颜色后进行清除,“背景”交换行为是可行的方法。要清除的内容可以通过 X 进行配置,可以是像素图或单色(背景像素)。

    命令是否阻塞,即停止直到完成?执行 依赖?

    在许多情况下,使用 X 的应用程序必须提供自己的同步机制。这将表明异步执行模式,但标准本身并不要求它。我会选择“定义的实现”,强烈建议大多数平台的大多数命令都是异步执行的。

    【讨论】:

      猜你喜欢
      • 2013-03-18
      • 1970-01-01
      • 2012-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多