Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/195.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
Opengl es 2.0-为什么glFinish在我的新android手机上的帧速率比旧手机低?_Android_Performance_Opengl Es_Frame Rate - Fatal编程技术网

Opengl es 2.0-为什么glFinish在我的新android手机上的帧速率比旧手机低?

Opengl es 2.0-为什么glFinish在我的新android手机上的帧速率比旧手机低?,android,performance,opengl-es,frame-rate,Android,Performance,Opengl Es,Frame Rate,我最近将我的旧Galaxy S2手机升级为全新的Galaxy S7,非常惊讶地发现我编写的旧游戏在新手机上的表现似乎更差。在将所有内容简化为一个简单的项目之后,我发现了问题——我在每个onDrawFrame末尾执行的GLES20.glFinish()调用。有了这个,有了一个glClear但没有draw调用,FPS徘徊在40左右。如果没有glFinish,则速度为60 FPS。我的旧S2有稳定的60帧每秒 然后我回到我的游戏,删除了glFinish方法调用,确保足够的性能恢复到完美状态,删除它没有

我最近将我的旧Galaxy S2手机升级为全新的Galaxy S7,非常惊讶地发现我编写的旧游戏在新手机上的表现似乎更差。在将所有内容简化为一个简单的项目之后,我发现了问题——我在每个onDrawFrame末尾执行的GLES20.glFinish()调用。有了这个,有了一个glClear但没有draw调用,FPS徘徊在40左右。如果没有glFinish,则速度为60 FPS。我的旧S2有稳定的60帧每秒

然后我回到我的游戏,删除了glFinish方法调用,确保足够的性能恢复到完美状态,删除它没有明显的缺点


为什么glFinish会在我的新手机上降低帧速率,而不是我的旧手机?

我认为一个推测性的答案是最好的,所以-很抱歉,几乎肯定重复了很多你已经知道的内容:

发送到OpenGL的命令会经历三种状态,即相对于GPU端的状态:

  • 未提交
  • 已提交但待定
  • 完成
  • 与运行GPU的代码进行通信通常是昂贵的。因此,大多数OpenGL实现都会接受您的调用,并将工作在内存空间中排队等待一段时间。在某个时刻,它将决定通信是合理的,并将支付一次性转移所有呼叫的费用,将它们提升到提交状态。然后GPU将完成每一个(可能出现故障,但前提是不破坏API)

    glFinish

    。。。直到所有以前调用的GL的效果消失后才返回 命令已完成。此类影响包括总账状态的所有变更, 连接状态的所有更改以及帧缓冲区的所有更改 内容

    所以在一段时间内,当CPU线程可能在做其他事情时,它现在肯定不会。但是如果您不
    glFinish
    ,那么您的输出可能仍然会出现,只是不清楚何时出现
    glFlush
    通常是正确的前进方式-它会将所有内容提前提交,但不会等待完成,因此所有内容肯定会很快出现,您不必等待

    OpenGL与操作系统的绑定差异很大;一般来说,如果您的环境允许,您几乎肯定希望冲洗而不是完成。如果刷新或完成都是有效的,并且操作系统没有根据任何标准为您推进操作,那么您可能会产生一些额外的延迟(例如,在下一帧中再次填充未提交的队列之前,您发出的一帧命令可能无法到达GPU)但若你们无限期地做GL工作,那个么输出几乎肯定仍会继续

    Android坐在EGL上。根据规范3.9.3:

    eglSwapBuffers
    eglCopyBuffers
    执行隐式刷新操作 在上下文中

    因此,我认为,如果您使用双缓冲,则不需要在Android中执行刷新或完成。调用交换缓冲区将在绘图完成后立即导致缓冲区交换,而不会阻塞CPU


    至于真正的问题,S7有一个Adreno 530 GPU。S2有一个Mali T760MP6 GPU。MALI由ARM生产,Adrenos由高通公司生产,因此它们的体系结构和驱动程序实现完全不同。所以造成阻塞的差异几乎可以是任何东西。但这是允许的
    glFinish
    不是必需的,是一个非常钝的工具;这可能不是主要的优化目标之一。

    Android图形体系结构将缓冲区与完成时发出信号的内核围栏对象配对。这意味着您可以进行渲染,调用
    eglSwapBuffers()
    ,并在渲染开始之前在系统合成器中提供缓冲区。。。这允许缓冲和IPC机制与渲染重叠。调用
    glFinish()。我怀疑这是造成帧速率大幅降低的唯一原因,但同步等待完成肯定没有帮助。要记住的另一个方面是,当您调用
    glFinish()
    时,一些供应商实际上并不等待所有事情完成。你可以说它违反了规范,但它仍然是这样做的。