Безопасное использование glMapBufferRange() на Android/Java

У меня есть рабочий код с помощью glMapBufferRange() из OpenGL-ES 3.0 на Android, который выглядит следующим образом:

  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() объявлено о возвращенииBuffer:

public static Buffer glMapBufferRange (int target, int offset, int length, int access)

На моей тестовой платформе функция возвращает подкласс ByteBuffer так что актеры работают, но сделать это предположение для всех платформ или версий Android, поддерживающих OpenGL-ES 3+, не очень безопасно. Хотя это кажется разумным, я не нашел никакой документации, которая гарантировала бы это, и если бы это было гарантировано, похоже, что функция должна быть объявлена ​​как возвращающая ByteBuffer,

Как правильно (желательно подтверждается документацией) использовать Buffer вернулся glMapBufferRange()?

1 ответ

Решение

Как вы уже нашли, документация отсутствует. Но есть еще довольно убедительная ссылка: реализация Java-привязок OpenGL является частью общедоступного исходного кода Android.

Если вы посмотрите на реализацию оболочки JNI для glMapBufferRange(), который находится в файле glMapBufferRange.cpp, вы можете увидеть, что буфер выделяется путем вызова функции с именем NewDirectByteBuffer(), Исходя из этого, можно с уверенностью предположить, что буфер действительно ByteBuffer,

Хотя производители могут изменять код Android, кажется маловероятным, что кто-либо изменит поведение привязок Java (за исключением, возможно, исправления ошибок). Если вы обеспокоены тем, что реализация может измениться в более поздних версиях Android, вы, безусловно, можете использовать стандартную проверку типов Java:

Buffer buf = glMapBufferRange(...);
ByteBuffer byteBuf = null;
if (buf instanceof ByteBuffer) {
    byteBuf = (ByteBuffer)buf;
}

Или вы можете использовать более сложное отражение, начиная с вызова getClass() на возвращенном буфере. Следующий вопрос, конечно, что вы делаете, если возвращаемый буфер не является ByteBuffer, Это действительно единственный тип, который имеет смысл для меня.

Другие вопросы по тегам