我最近把我的旧galaxy s2手机升级到了全新的galaxy s7,很惊讶地发现我写的一款旧游戏在新手机上的表现似乎更差。在将所有内容都简化为一个简单的项目之后,我发现了问题——我在每个OnDrawFrame的末尾执行的gles20.glfinish()调用。有了这个,有一个glclear但没有draw调用,fps徘徊在40左右。没有glfinish,60帧/秒。我的旧S2有60 fps的固体不管。
然后我回到我的游戏中,删除了glfinish方法调用,并且确定足够的性能恢复到完美状态,并且删除它没有明显的缺点。
为什么glfinish在我的新手机而不是旧手机上降低了帧速率?

最佳答案

我认为一个推测性的答案是最好的,所以-抱歉几乎肯定重复了很多你已经知道的:
发送给opengl的命令经历了三种状态,与gpu相关:
未提交的
已提交但待定
完整的
与运行gpu的代码通信通常很昂贵。因此,大多数opengl实现都接受您的调用,只需将工作在内存空间中排队一段时间。在某个时候,它将决定一个通信是合理的,并将支付一次传输所有调用的费用,将它们提升到提交状态。然后gpu将完成每一个(可能是无序的,以不破坏api为前提)。
glFinish
…不返回,直到所有以前调用的gl的效果
命令已完成。这些影响包括对GL状态的所有更改,
对连接状态的所有更改,以及对帧缓冲区的所有更改
内容。
因此,在某段时间内,当CPU线程可能在做其他事情时,它现在肯定不会。但是如果您不glFinish,那么您的输出可能仍然会出现,只是不清楚什么时候会出现。glFlush通常是正确的前进方向-它会将所有内容提前提交,但不会等待完成,因此所有内容肯定会很快出现,您只是不必等待它。
opengl与os的绑定有很多不同;一般来说,如果环境允许,您几乎肯定希望刷新而不是完成。如果刷新或完成都无效,并且操作系统没有根据任何条件为您推进操作,则可能会导致一些额外的延迟(例如,在下一帧中再次填满未提交的队列之前,发出的命令可能无法到达GPU),但是如果您无限期地执行gl工作,那么输出几乎肯定仍将继续。
安卓坐在egl上。根据规范3.9.3:
eglSwapBufferseglCopyBuffers执行隐式刷新操作
在上下文中…
因此,我相信如果你是双缓冲的,你不需要在android中执行flush或finish。调用交换缓冲区将在绘图完成后立即导致缓冲区交换,而不会阻塞CPU。
至于真正的问题,s7有一个adreno 530 gpu。S2具有马里T760MP6 GPU。MALI由ARM生产,ADRENOS由高通公司生产,因此它们是完全不同的体系结构和驱动程序实现。所以导致阻塞的差别可能是任何东西。但这是允许的。glFinish不是必需的,而且是一种非常生硬的工具;它可能不是主要的优化目标之一。

10-08 05:43