OpenGL ES 3.0 数据可视化 3:多次绘制调用(glDraw*)的性能问题

上一篇文档OpenGL ES 3.0 数据可视化 2:多重采样绘制光滑圆点实现了画多个圆点的功能,忽略其图像质量,还存在一些影响性能的代码。
本文档先讨论当前代码存在的性能问题,同时简要介绍OpenGL ES命令的工作方式。

OpenGL ES 3.0 数据可视化 2:多重采样绘制光滑圆点通过循环调用glDrawArrays绘制多个圆点,这种实现容易带来较大的CPU开销,因为OpenGL (ES)相关的函数是运行期间由CPU转成GPU命令并发送到GPU命令缓冲区中,在GPU命令缓冲区装满或调用glFlush之后,GPU异步读取命令并执行,如下示意图所示。

glDrawArrays从GL函数转成GPU命令

同时,GPU也维护了一个GPU命令缓冲区,CPU在操作系统内核维护的GPU命令缓冲区在装满或调用glFlush后,内核端的缓冲区及其相关数据被拷贝到GPU端缓冲区,此时,GPU再从该缓冲区中读取命令并执行,如下示意图所示。

GPU命令缓冲区

部分GL函数的翻译消耗较多资源,如glDrawArrays,虽然开发者只调用了glDrawArrays,它还有自己的调用栈,如下所示。因此,开发者应尽量减少这些高消耗函数的调用次数。

glDrawArrays内部调用栈

那么,说了半天,到底每次glDrawArray调用要花多长时间?没图没真相。方便起见,现截取Debug模式的性能数据,首先是每帧绘制的总耗时为10.72毫秒,然后是逐点的绘制耗时。它们符合一个规律:点越大,则光栅化出来的正方形也大,在片段着色器中需要判断的片段数量越多,同时出现更多被放弃(discard)的片元,计算耗时随之加大。

多次glDrawArrays画多个圆点的每帧资源消耗
每次glDrawArrays的耗时列表
圆点递增耗时

从前面的图表已知耗时信息,现在看看具体存在的性能问题,使用Xcode 8 Instruments提示如下。值得注意的是,Instruments 8.0 (8A218a)对于同一份代码的部分性能警告不同于Instruments 7.3 (7D175),我个人经实测,认为Instruments 7.3的提示更准确。

绘制多个圆点存在的性能问题
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容