我一直在编写一个视频应用程序,可以在OS X上使用GLSL将具有多种不同叠加层的视频渲染到不同的设备。
在一台相对较新的机器(视网膜MacBook Pro)上尝试时,一切都运行良好,但我现在有一台旧机器(带有Nvidia GT 120的MacPro 4,1),我遇到了瓶颈,我遇到了这个问题。我希望找到一个解决方案。
我的应用程序基本上渲染纹理和简单的基元。我有一些着色器可以完成不同的工作。一个用于绘制纹理,一个用于绘制圆形,一个用于绘制条形图...我基本上使用glUseProgram()
通过渲染到帧缓冲区中逐个应用着色器。
大多数情况下,每次渲染通过的执行速度非常快(<5毫秒),但有时需要超过20毫秒,这是一个问题,因为我以3-4的速率运行3-4个设备例如每帧24 fps = 41.6667 ms。
我发现问题是在将上下文设置为当前上下文后直接调用glUseProgram。这是代码:
CGLSetCurrentContext(device.renderingContext);
CGLLockContext(device.renderingContext);
// Setting and locking the context sometimes causes an inevitable GL error.
// We must clear the error here to enable proper error checking below.
glGetError();
[device bindFramebuffer];
GetError();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glViewport(0.0f, 0.0f, deviceSize.width, deviceSize.height);
glUseProgram(self.texApplyShader.program);
GetError();
任何人都可以告诉我这可能是由什么引起的,为什么它只会偶尔发生?我的绘图方法是否有意义,或者让一个着色器完成所有操作会更好吗?
修改
我刚刚和freenode IRC上的一些OpenGL人员谈过,他们告诉我,glUseProgram可能会调用自己。他们确实是对的。 OpenGL管道似乎在切换着色器之前等待。我在glFinish()
之前拨打glUseProgram()
电话,现在glFinish()
占用了所有时间。我会进一步发现性能泄漏。
答案 0 :(得分:1)
我在这里做了一个有远见的教育猜测:你 - 无论如何 - 改变任何统一值或属性绑定与该着色器组合? NV GT120是一款相当古老的GPU,如果那台机器上的驱动程序差不多,我也不会感到惊讶。这就是问题:在某些情况下,着色器会在原位重新编译(即使在现代驱动程序中)。旧的NVidia驱动程序特别容易进行着色器重新编译,如果发生简单的值更改这样简单的事情。也许这就是导致你出现打嗝的原因。
答案 1 :(得分:1)
我发现glUseProgram调用本身并没有花太长时间,但它正在等待前面的glReadPixels操作完成。
由于你的提示,我可以通过删除glGetError和glClear调用来进一步提高性能。谢谢!