glBufferSubData在许多android设备上非常慢

时间:2019-03-28 02:59:56

标签: opengl-es opengl-es-2.0 opengl-es-3.0

我已请求约2M个gl缓冲区进行共享,并使用glBufferSubData更新顶点和索引的数据,它在我的iOS设备上运行良好。同时,当我在Android设备上对其进行测试时,它非常非常慢。

我从官方网站上发现了一些笔记: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBufferSubData.xhtml

“在必须更新数据存储区之前,渲染必须从管道中耗尽”的真正含义是什么?

1 个答案:

答案 0 :(得分:1)

您看到的性能差异可能不仅是iOS / Android差异,而且还将非常特定于API的使用以及驱动程序中glBufferSubData的实现。在没有看到更多代码或不知道您要收集什么性能指标的情况下,很难进一步评论。

  

“呈现必须在数据之前从管道中流失的内容是什么?   商店可以更新”是真的意思吗?

这里的想法是,尽管OpenGL API给人一种错觉,即每个命令在继续执行之前就已执行完毕,实际上,绘制通常是在后台批处理并异步完成的。这里的问题是glBufferSubData可能会添加一个同步点,这将意味着驱动程序将不得不停止,直到使用该缓冲区的所有以前的渲染完成为止。

请考虑以下示例。在一个好的情况下,我们可能会遇到这样的情况:

  • glBufferSubData通过ABCDE进入缓冲区1
  • 使用缓冲区1进行绘图调用
  • glBufferSubData通过FGHIJ进入缓冲区2
  • 使用缓冲区2进行绘图调用
  • 交换缓冲区<-----同步点,驱动程序在交换缓冲区之前必须等待渲染完成

但是,如果您要覆盖相同的缓冲区,则会得到此缓冲区。

  • glBufferSubData通过ABCDE进入缓冲区1
  • 使用缓冲区1进行绘图调用
  • glBufferSubData放入缓冲区1中,用FGHIJ覆盖<-----同步点,因为驱动程序必须确保在修改数据之前第一次绘制调用已使用完缓冲区
  • 使用更新后的缓冲区1进行绘图调用
  • 交换缓冲区<-----同步点,驱动程序在交换缓冲区之前必须等待渲染完成

如您所见,您可能最终会获得第二个同步点。但是,如前所述,这在某种程度上是特定于驱动程序的。例如,某些驱动程序可能能够检测到上一次绘制调用未使用要更新的缓冲区部分的情况,而其他驱动程序则可能没有。这种性质可能是造成您所看到的性能差异的原因。