在IOS上使用OpenGL实现三重缓冲

在IOS上使用OpenGL实现三重缓冲,ios,rendering,opengl-es-2.0,Ios,Rendering,Opengl Es 2.0,我们的应用程序仍然在IOS上使用OpenGLES2.0。是的,我知道我们应该使用Metal,但我们的应用程序也可以在Android上运行。虽然大多数情况下,它以60 fps的速度运行得非常愉快,但偶尔会出现故障,在某些情况下,它似乎会交替使用一帧渲染场景,然后使用两帧。1, 2, 1, 2, 1, 2... 然后,在不更改渲染内容的情况下,它将跳回到1,1,1,即60帧/秒。延迟在我们“呈现”最后一个缓冲区后的第一个glClear中。我猜OpenGL要么仍在渲染最后一个场景,要么必须等待整个帧才

我们的应用程序仍然在IOS上使用OpenGLES2.0。是的,我知道我们应该使用Metal,但我们的应用程序也可以在Android上运行。虽然大多数情况下,它以60 fps的速度运行得非常愉快,但偶尔会出现故障,在某些情况下,它似乎会交替使用一帧渲染场景,然后使用两帧。1, 2, 1, 2, 1, 2... 然后,在不更改渲染内容的情况下,它将跳回到1,1,1,即60帧/秒。延迟在我们“呈现”最后一个缓冲区后的第一个glClear中。我猜OpenGL要么仍在渲染最后一个场景,要么必须等待整个帧才能再次同步。也许我们的渲染/更新循环需要接近或刚刚超过一整帧-这将有助于解释延迟,因为它“错过”了vsync

然而,如果我们有三重缓冲,我希望帧时间是1,1,2,1,1,2,1,1,2。。不是1,2,1,2,1,2,1。有没有办法让IOS使用三重缓冲

目前,我们似乎只初始化了两个“缓冲区”

GLuint viewRenderbuffer;
GLuint viewFramebuffer;
glGenFramebuffers(1, &viewFramebuffer);
glGenRenderbuffers(1, &viewRenderbuffer);
glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);
glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
然后我们在每个帧完成渲染后调用它

glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER];
通常我希望在某个地方调用glSwapbuffers,但我希望它在presentRenderbuffer调用中。我想这取决于司机,然后处理双重或三重缓冲

有没有办法强制使用三重缓冲,或者实际上已经在使用了

谢谢
默认情况下,iOS上的Shaun渲染是三重缓冲的。这可防止机架撕裂和/或失速。当平均帧时间大于vsync间隔施加的限制时(例如,对于60 FPS,约16.6ms),通常会发生帧口吃。您可以在XCode评测工具中检查这一时间,或者自己使用系统计时器测量它,并在调试HUD中绘制结果

相同呈现内容的意外性能下降可能是由于操作系统的CPU/GPU频率管理造成的

请查看这篇关于帧配速的演讲(6:00及以后)

另一方面,性能可能不好,这不仅是因为原始负载,还因为同步问题。同步问题的一个示例是读回帧缓冲区内容或不正确处理动态顶点/索引缓冲区


提高移动设备上的渲染性能是一个复杂的问题,需要小心处理FBO以避免不必要的带宽使用。您可以使用XCode评测工具和帧捕获来查找瓶颈。

使用评测器进行的更多调查显示了有趣的结果。当游戏运行平稳时,GPU会在一个帧内忙碌,三个曲面(14、15、16)依次循环。在我看来是三重缓冲。当它开始抖动时,会出现“等待自由曲面”的大暂停,显示曲面的顺序类似于14(1帧)15(3帧)14(1帧)16(3帧)。。它可以恢复同步,但我不知道这是怎么发生的。如果我在渲染结束时放置glFinish,它会变慢,但始终变慢。