Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos 为什么glUseProgram这么慢?_Macos_Opengl_Glsl_Shader - Fatal编程技术网

Macos 为什么glUseProgram这么慢?

Macos 为什么glUseProgram这么慢?,macos,opengl,glsl,shader,Macos,Opengl,Glsl,Shader,我一直在编写一个视频应用程序,它可以使用OS X上的GLSL在不同的设备上渲染具有许多不同覆盖层的视频 在一台相对较新的机器(retina MacBook Pro)上试用时,一切都很好,但我现在有一台较旧的机器(MacPro 4,1和Nvidia GT 120),我遇到了一个瓶颈,我希望找到解决方案 我的应用程序基本上渲染纹理和简单的基本体。我有几个着色器,它们做不同的工作。一个用于绘制纹理,一个用于绘制圆,一个用于绘制条形图。。。我基本上是通过渲染到帧缓冲区,一个接一个地使用glUseProg

我一直在编写一个视频应用程序,它可以使用OS X上的GLSL在不同的设备上渲染具有许多不同覆盖层的视频

在一台相对较新的机器(retina MacBook Pro)上试用时,一切都很好,但我现在有一台较旧的机器(MacPro 4,1和Nvidia GT 120),我遇到了一个瓶颈,我希望找到解决方案

我的应用程序基本上渲染纹理和简单的基本体。我有几个着色器,它们做不同的工作。一个用于绘制纹理,一个用于绘制圆,一个用于绘制条形图。。。我基本上是通过渲染到帧缓冲区,一个接一个地使用
glUseProgram()

大多数情况下,每个渲染过程的执行速度都非常快(<5毫秒),但有时需要超过20毫秒,这是一个问题,因为我正在以每帧24 fps=41.6667毫秒的速率为3-4个设备提供服务

我发现问题是在将上下文设置为当前上下文后直接调用GluseProgramm。代码如下:

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的人谈过,他们告诉我GluseProgramm很可能会调用自己。他们确实是对的。OpenGL管道似乎在切换着色器之前等待。我将
glFinish()
调用放在
glUseProgram()
之前,现在
glFinish()
占用了所有的时间。我将进一步查找性能漏洞。

我在这里做了一个远大的猜测:您是否有可能结合该着色器更改任何统一值或属性绑定?NV GT120是一个相当古老的GPU,如果这台机器上的驱动程序也同样古老,我也不会感到惊讶。问题在于:在某些情况下,着色器会在原地重新编译(即使在现代驱动程序中也是如此)。如果发生统一值更改这样简单的事情,旧的NVidia驱动程序尤其容易重新编译着色器。也许这就是导致您打嗝的原因。

我发现glUseProgram调用本身并没有花太长时间,而是在等待前面的glReadPixels操作完成


根据您的提示,我可以通过删除glGetError和glClear调用来进一步提高性能。谢谢

你是如何确定时间的?通常,OpenGL与应用程序是异步工作的,因此无法确定每个命令需要多长时间。可能是在
glUseProgram
之前必须执行其他几个命令。假设
GetError
调用
glGetError
,这肯定是一个性能问题,因为所有glGet*命令都会刷新管道。另一方面,在任何现代GPU上,更改着色器程序是第二个最昂贵的状态更改(第一个是更改目标帧缓冲区)。请参阅此NVIDIA演示文稿(绝对数字并不重要,图形的形状确实重要)。@BDL:Timer查询允许您计算命令所需的时间,但也允许您推断不真实的情况。例如,GL实现可能会延迟VSYNC的阻塞,而不是在发生缓冲区交换时,而是在发出修改backbuffer的第一个命令时。然后,您可能会错误地认为命令本身异常缓慢,需要避免某些事情。。。我接着说GL的隐式同步行为是问题所在。驱动程序将在某些点阻止一些命令,原因仅是它已知的原因。英伟达MOS不暴露 GLY-KHRY-DEXGE/<代码>,但是在其他OSES上,NVIDIA驱动程序通过低优先级调试消息告诉您这一点。