消费者生产者模型中的双缓冲 OpenGL 对象

Posted

技术标签:

【中文标题】消费者生产者模型中的双缓冲 OpenGL 对象【英文标题】:Double buffered OpenGL objects in a consumer producer model 【发布时间】:2013-08-25 08:50:07 【问题描述】:

在我的 OpenGL ios 应用程序中,我试图实现生产者-消费者模型,其中生产者需要加载纹理,而消费者需要显示它们。通过阅读文档,我了解到这将需要使用 EAGL 共享组,并且共享的 OpenGL 对象应该是双缓冲的。但是,我不太确定应该对哪些 OpenGL 对象进行双缓冲。应该纹理还是帧缓冲区?每次需要显示新帧时,我的制作人都会加载三个纹理,因此我认为切换帧缓冲区可能更有效。

所以,在高层次上,这就是我认为应该发生的事情:

    在 openGL 初始化期间的某处创建一个渲染缓冲区和两个帧缓冲区 (frameBuffers[2])。 在生产者线程中,当消费者线程使用 frameBuffers[0] 时,将传入的帧作为 OpenGL 纹理加载到 frameBuffers[1],并将帧缓冲区 ID 推送到某种共享队列中。 在消费者线程中,从共享队列中弹出下一个帧缓冲区ID,并使用它来绑定帧缓冲区(glBindFramebuffer(GL_FRAMEBUFFER, i))。最后交换渲染缓冲区以显示。

这有意义吗?有没有更好的方法来实现这一切?

【问题讨论】:

【参考方案1】:

我想,既然您说的是每帧都加载新纹理,那么您不仅仅是从磁盘中获取它们。 (为此,GLKTextureLoader 提供了一个简单的异步加载接口。)

您应该对受设计的异步部分影响的对象使用双缓冲。在这种情况下,您正在异步加载纹理,因此纹理对象应该是双缓冲的。当您的生产者线程正在加载纹理 0、1 和 2 时,您的消费者线程可以从纹理 3、4 和 5 中进行绘制。只要这两个操作在大约相同的时间内完成,您就可以分别交换缓冲区集框架;否则你需要研究三重缓冲。

【讨论】:

以上是关于消费者生产者模型中的双缓冲 OpenGL 对象的主要内容,如果未能解决你的问题,请参考以下文章

多线程20:管程法

生产者和消费者模型

生产者和消费者模型

生产者和消费者

生产消费模式

多线程——生产者和消费者