在 Android/Java 上安全使用 glMapBufferRange()
Safe usage of glMapBufferRange() on Android/Java
我在 Android 上使用来自 OpenGL-ES 3.0 的 glMapBufferRange()
的工作代码如下所示:
glBindBuffer(GL_ARRAY_BUFFER, myVertexBufferName);
glBufferData(GL_ARRAY_BUFFER, myVertexBufferSize, null, GL_STATIC_DRAW);
ByteBuffer mappedBuffer = (ByteBuffer)glMapBufferRange(
GL_ARRAY_BUFFER,
0, myVertexBufferSize,
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
// [fill buffer...]
glUnmapBuffer(GL_ARRAY_BUFFER);
我的问题是关于在第三行将 glMapBufferRange()
的结果向下转换为 ByteBuffer
。 glMapBufferRange()
是 declared to return a Buffer
:
public static Buffer glMapBufferRange (int target, int offset, int length, int access)
在我的测试平台上,函数 returns 是 ByteBuffer
的子类,因此转换有效,但对所有平台或支持 OpenGL-ES 3+ 的 Android 版本做出此假设并不看起来很安全。虽然这看起来很合理,但我还没有找到任何保证它的文档,如果得到保证,似乎该函数应该声明为返回 ByteBuffer
.
使用 glMapBufferRange()
返回的 Buffer
的正确方法是什么(最好有文档支持)?
如您所见,缺少文档。但是仍然有一个相当确定的参考:OpenGL Java 绑定的实现是 public Android 源代码的一部分。
如果您查看文件 glMapBufferRange.cpp 中 glMapBufferRange()
的 JNI 包装器的实现,您可以看到缓冲区是通过调用名为 [=12= 的函数分配的].基于此,可以安全地假设缓冲区确实是 ByteBuffer
.
虽然供应商可以更改 Android 代码,但似乎任何人都不太可能更改 Java 绑定的行为(除了修复错误)。如果您担心在以后的 Android 版本中实现可能会发生变化,您当然可以使用标准 Java 类型检查:
Buffer buf = glMapBufferRange(...);
ByteBuffer byteBuf = null;
if (buf instanceof ByteBuffer) {
byteBuf = (ByteBuffer)buf;
}
或者您可以使用更精细的反射,首先在返回的缓冲区上调用 getClass()
。下一个问题当然是如果返回的缓冲区不是 ByteBuffer
,你会怎么做。这真的是唯一对我有意义的类型。
我在 Android 上使用来自 OpenGL-ES 3.0 的 glMapBufferRange()
的工作代码如下所示:
glBindBuffer(GL_ARRAY_BUFFER, myVertexBufferName);
glBufferData(GL_ARRAY_BUFFER, myVertexBufferSize, null, GL_STATIC_DRAW);
ByteBuffer mappedBuffer = (ByteBuffer)glMapBufferRange(
GL_ARRAY_BUFFER,
0, myVertexBufferSize,
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
// [fill buffer...]
glUnmapBuffer(GL_ARRAY_BUFFER);
我的问题是关于在第三行将 glMapBufferRange()
的结果向下转换为 ByteBuffer
。 glMapBufferRange()
是 declared to return a Buffer
:
public static Buffer glMapBufferRange (int target, int offset, int length, int access)
在我的测试平台上,函数 returns 是 ByteBuffer
的子类,因此转换有效,但对所有平台或支持 OpenGL-ES 3+ 的 Android 版本做出此假设并不看起来很安全。虽然这看起来很合理,但我还没有找到任何保证它的文档,如果得到保证,似乎该函数应该声明为返回 ByteBuffer
.
使用 glMapBufferRange()
返回的 Buffer
的正确方法是什么(最好有文档支持)?
如您所见,缺少文档。但是仍然有一个相当确定的参考:OpenGL Java 绑定的实现是 public Android 源代码的一部分。
如果您查看文件 glMapBufferRange.cpp 中 glMapBufferRange()
的 JNI 包装器的实现,您可以看到缓冲区是通过调用名为 [=12= 的函数分配的].基于此,可以安全地假设缓冲区确实是 ByteBuffer
.
虽然供应商可以更改 Android 代码,但似乎任何人都不太可能更改 Java 绑定的行为(除了修复错误)。如果您担心在以后的 Android 版本中实现可能会发生变化,您当然可以使用标准 Java 类型检查:
Buffer buf = glMapBufferRange(...);
ByteBuffer byteBuf = null;
if (buf instanceof ByteBuffer) {
byteBuf = (ByteBuffer)buf;
}
或者您可以使用更精细的反射,首先在返回的缓冲区上调用 getClass()
。下一个问题当然是如果返回的缓冲区不是 ByteBuffer
,你会怎么做。这真的是唯一对我有意义的类型。