我正在学习OpenGL ES,我看到很多示例分配直接ByteBuffer
,然后将其包装在FloatBuffer
中并在{{3}中将顶点数据写入其中}}
为什么这个线程安全? (或者是吗?)它是直接ByteBuffer
的特征,还是onDrawFrame(...)
调用者所做的事情,它确保着色器程序可以看到对缓冲区的写入?
编辑:我对JMM的理解是它的本质是因为Java暴露了现代硬件的一些复杂性。我假设在Java线程和访问同一内存的非Java程序之间存在Java线程之间存在的相同内存可见性问题。我进一步假设着色器在GPU上运行,而不是在Java渲染线程中运行。
如果以上所有都是正确的,那么某处必须有一个内存屏障,以确保着色器可以看到渲染线程中的写入。我的问题归结为,内存障碍在哪里?创建它是我的责任吗?
答案 0 :(得分:0)
理想情况下,所有分配和填充都发生在渲染器线程上,因此没有线程安全问题。在这方面,直接ByteBuffers没有什么特别之处。如果一个应用程序正在从一个线程写入并且从另一个线程读取而没有同步,则可能存在竞争条件。
如果GLES驱动程序决定使用多个线程,它将负责发出适当的内存障碍。
修改(以匹配相关编辑):应用的责任是一次从一个线程访问EGL上下文(我称之为&#34 ;渲染器线程")。如果您从具有数据争用的缓冲区向GLES提交数据,那么您将度过糟糕的时光。只要渲染器线程具有一致的视图,您在该线程上使用GLES执行的所有操作都将按预期工作。
如果GLES实现恰好在不同的CPU线程或GPU上执行着色器,那么GLES驱动程序有责任处理内存一致性问题。