许多OpenGL绘图区域交换缓冲区减速问题

Posted

技术标签:

【中文标题】许多OpenGL绘图区域交换缓冲区减速问题【英文标题】:Many OpenGL drawing areas swapping buffers slowdown problem 【发布时间】:2011-08-20 14:41:32 【问题描述】:

在将 openGL 与 gtk(虽然是 gtkglext)一起使用并制作动画时,我遇到了减速问题。

基本上我有一个应用程序在 GTK 应用程序中使用 OpenGL 进行某些显示。可以同时打开多个窗口(某些窗口可以有多个绘图区域)。因此,一次可以在屏幕上显示 20-30 个 openGL 绘图区域。没有一张图太重,openGL 做得很快。

当所有这些显示都在动画时,我的问题就出现了,它确实会减慢应用程序的速度。经过对问题的大量研究,我确定是对 openGL 的交换缓冲区调用导致了我的问题。在 GTK 中绘图时,您必须在小部件公开事件中进行所有绘图。因此,当您要绘制时,您在绘图区域小部件上调用 gtk_widget_queue_draw,然后当 GTK 处理其事件时,它将在所有需要绘图的小部件上依次调用公开事件。绘制完成后,问题就出现了,我需要调用交换缓冲区来在屏幕上绘制实际的 openGL(因为双缓冲)。在监视器刷新之前,此调用似乎会阻塞(因为 vysnc 已打开)。当屏幕上有 3 个绘图区域时,这不是问题,但是当有很多时,会有大量的交换缓冲区调用全部阻塞并真正减慢应用程序,因为这些交换缓冲区调用中的每一个都被调用他们自己的暴露事件,没有一个是同步的。

我的问题是,是否有某种方法可以同步所有交换缓冲区调用,这样就不会出现太多阻塞。关闭 vsync(本身很丑,因为它的 OS/openGL 实现特定)修复了速度问题,但随后出现了撕裂问题。我不确定多线程会有什么帮助,因为我必须在 GTK 公开事件中执行交换缓冲区,以便绘图与 GTK 同步,除非有我没有想到的东西。

任何帮助将不胜感激!

【问题讨论】:

【参考方案1】:

如果您有 20 多个窗口,您期望什么?每个都垂直同步到相同的时间:屏幕刷新。在此期间,每个人都必须进行一系列内存操作。同时。当然会放缓。除非你有 20 多个处理器,否则它们将不得不一个接一个地排队。

真的,除了限制向用户显示的 GL 窗口的数量之外,您无能为力。

【讨论】:

假设每个 OpenGL 窗口只绘制一个三角形。 V-Sync 阻塞了调用 SwapBuffers 的线程是问题所在。【参考方案2】:

解决这个问题的典型方法是为每个 OpenGL 上下文使用一个自己的线程来交换。

然而 OpenGL 实现者可以(我应该说他们)引入一个新的扩展,引入“协调交换”或类似的东西。有一些同步扩展,最著名的是http://www.opengl.org/registry/specs/OML/glx_sync_control.txt

【讨论】:

以上是关于许多OpenGL绘图区域交换缓冲区减速问题的主要内容,如果未能解决你的问题,请参考以下文章

在仅触及深度缓冲区的openGL中进行绘图调用

单缓冲和双缓冲 有啥区别

在 OpenGL ES 1.1 中使用顶点缓冲区对象绘图不起作用

快速交换帧缓冲区 OpenGL

绘图调用期间 Opengl vao 中断

Android OpenGLES3绘图 - 帧缓冲