Performance OpenGL ES 2.0-渲染到纹理时减少内存拷贝

Performance OpenGL ES 2.0-渲染到纹理时减少内存拷贝,performance,opengl-es,rendering,opengl-es-2.0,fbo,Performance,Opengl Es,Rendering,Opengl Es 2.0,Fbo,假设我有四个内容层:A、B、C和D;每一个代表一种类型的视觉内容 每个层执行几个连续的渲染调用(没有来自各个层的交错渲染调用) 此外,层B和D需要渲染到纹理,以便应用视觉效果。为了减少内存占用,我只使用一个FBO和一个纹理 因此,目前我确实: 呈现内容 绑定FBO>渲染B内容>取消绑定FBO>渲染纹理(B内容) 渲染C 绑定FBO>渲染D内容>取消绑定FBO>渲染纹理(D内容) 这种方法的主要问题是,每次绑定/解除绑定FBO时,默认帧缓冲区都会保存/恢复到内存中或从内存中恢复 我不能简单地先

假设我有四个内容层:A、B、C和D;每一个代表一种类型的视觉内容

每个层执行几个连续的渲染调用(没有来自各个层的交错渲染调用)

此外,层B和D需要渲染到纹理,以便应用视觉效果。为了减少内存占用,我只使用一个FBO和一个纹理

因此,目前我确实:

  • 呈现内容
  • 绑定FBO>渲染B内容>取消绑定FBO>渲染纹理(B内容)
  • 渲染C
  • 绑定FBO>渲染D内容>取消绑定FBO>渲染纹理(D内容)
这种方法的主要问题是,每次绑定/解除绑定FBO时,默认帧缓冲区都会保存/恢复到内存中或从内存中恢复

我不能简单地先将层B和D绘制到FBO,因为我不能更改层的渲染顺序


是否有更好的方法来执行此操作并避免主帧缓冲区的多次保存/恢复?请记住,这是一个示例,实际情况更复杂(更多层)。

能够在渲染目标之间快速切换是FBO功能的主要原始用途。它通常比旧的pbuffer方法更快,因为它不必处理不断变化的渲染上下文。此外,FBO不像PBuffer那样依赖EGL来分配渲染曲面。如果Adreno 200无法快速切换FBO,则这是特定于Adreno的实现问题。

驱动程序将从内存中带回FBO的内容(这是一项代价高昂的操作),除非在绘图之前使用
glClear()
清除FBO。清除FBO将提示驱动程序丢弃当前内容,而不是将其从主存中取出。如果FBO有深度缓冲区,请确保在调用
glClear()
时也包含该位


由于您只使用一个FBO,因此可能无法绕过它。检查您的内存要求是否严格到不能使用第二个FBO,这样您可以将B渲染到第一个FBO,然后将D渲染到第二个FBO,然后将所有内容层一起渲染到屏幕上。

“每次绑定/解除绑定FBO时,默认帧缓冲区都会保存/恢复到内存中/从内存中恢复。”-您确定吗?FBO的主要原理和优势之一不是因为根本不需要逐出/恢复默认帧缓冲区就不会发生这种情况吗(但可能是ES硬件在这方面的行为不同,这会让FBO非常痛苦)?我不确定这是否会发生在每个芯片上,但根据Adreno 200性能提示,每次绑定和解除绑定FBO时,驱动程序都会在主内存中/外解析GMEM。问题是我需要两个以上的FBO,因为实际情况比我在问题中使用的示例更复杂。没有更多细节,很难说,但也许可以更改渲染调用以组合效果?例如,如果需要将A、B和C渲染为纹理,则可以渲染A和B,然后切换到屏幕FBO并同时渲染二者,然后渲染为C,将屏幕FBO恢复并在C中渲染结果。这不是一个完美的解决方案,但可以节省一些帧缓冲区加载。