Что нужно использовать для клиентской стороны OpenGL: glGetSynciv vs. glClientWaitSync?

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

GLint syncStatus;
glGetSynciv(*sync, GL_SYNC_STATUS, sizeof(GLint), NULL, &syncStatus);
bool finished = syncStatus == GL_SIGNALED;

против

bool finished = glClientWaitSync(*sync, 0 /*flags*/, 0 /*timeout*/) == ALREADY_SIGNALED;

Некоторые вопросы:

  • Выполняет ли glGetSynciv двусторонний переход на сервер GL?
  • Является ли какой-либо метод предпочтительным с точки зрения поддержки/ошибок драйверов?
  • Может ли метод зайти в тупик или не вернуться сразу?

В некотором контексте:

  • Это для видеопроигрывателя, который передает изображения с физического источника на GPU для рендеринга.
  • Один поток - это потоковая передача/непрерывная загрузка текстур, а другой поток передает их после завершения загрузки. Каждый кадр рендеринга мы проверяем, закончилась ли следующая текстура. Если это так, то мы начинаем рендерить эту новую текстуру, в противном случае продолжаем использовать старую текстуру.
  • Решение - только клиентская сторона, и я не хочу ждать вообще, но быстро продолжаю отображать правильную текстуру.

Оба метода имеют примеры людей, использующих их с целью не ждать, но никто, кажется, не обсуждает достоинства использования того или другого.

Ответ 1

Цитата Красной книги,

void glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei * lenght, значения GLint *);

Извлекает свойства объекта синхронизации. sync указывает дескриптор объекта синхронизации, из которого считывается свойство, указанное pname. bufSize - это размер в байтах буфера, адрес которого указан в значениях. lenght - это адрес целочисленной переменной, которая будет принимать количество байтов, записанных в значения

Пока для glClientWaitSync:

GLenum glClientWaitSync (синхронизация GLsync, флаги GLbitfields, тайм-аут GLuint64);

Заставляет клиент ждать, пока объект синхронизации станет сигналом. glClientWaitSync() будет ждать максимум времени наносекунд, чтобы объект стал сигналом перед генерированием таймаута. Параметр flags может использоваться для управления режимом промывки команды. Задание GL_SYNC_FLUSH_COMMANDS_BIT эквивалентно вызову glFlush() перед выполнением ожидания.

Итак, в основном glGetSynciv() используется, чтобы узнать, стал ли объект забора сигналом и glClientWaitSync() используется, чтобы ждать, пока объект забора не станет сигнализирован.

Если вы хотите узнать только, был ли объект привязки включен, я бы предложил использовать glGetSynciv(). Очевидно, что glClientWaitSync() займет больше времени, чем glGetSynciv(), но я предполагаю. Надеюсь, я помог тебе.