9.3、尽量减少缓存复制
GPU每秒需要访问顶点属性缓存、纹理缓存和渲染缓存数百万次。一般情况下, 当CPU正在访问一个缓存时,GPU就不能在这一时间访问这个缓存了。当CPU试图读 写缓存内容时,可能会迫使CPU或者GPU (一些情况下两者一起)停下来并等待。这 个等待叫做卡顿(stal)。为了减少卡顿的危险,OpenGLES上下文和某些情况下的底 层OpenGLES硬件设备驱动会创建私有的缓存副本。复制缓存会耗费内存和处理器时 间,但是OpenGL ES通常会用最少的中断时间来执行复制以避免卡顿。
尽量减少缓存复制的最好方式是初始化缓存,接着使用GL_STATIC_DRAW提示 调用glBufferData()函数来把它们交给OpenGL ES,然后就永远不要再用在CPU内执 行的程序修改或者读取缓存了。OpenGLES会复制由glBufferData()初始化的缓存到 GPU控制的内存,然后就可以用最佳效率来访问它们了。类似的,GPU会向在GPU控 制的内存中的渲染缓存写数据。试图用CPU通过glReadPixels()函数来读取渲染缓存中 的内容可能会导致卡顿,并常常会迫使OpenGLES耗费时间和内存来创建渲染缓存内 容的副本。
当然,有时也需要动态更新缓存或者读取渲染缓存的内容。否则将无法完成应用的 目的,又或者不这样做的话性能甚至会更糟。在这种情况下,推荐使用双缓存。例如: 为GPU提供一个顶点属性缓存后,接着开始利用CPU处理另一个。基于当前在GPU 中使用的缓存的所有OpenGL ES渲染命令都发送完后,通过调用glBindBuffer()函数来 切换缓存,以便把CPU刚刚更新的缓存用于接下来的渲染,并用CPU更新先前GPU 使用的缓存。只要确保GPU和CPU在同-时间不会工作在相同的缓存下即可。 苹果公司详细解释了双缓存技术,地址为: https://developerapple.cop/ibrary/ios/ documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/OpenGLESApplication-Design/OpenGLESApplicationDesign.html