Мне нужно создать функцию C ++, которая будет возвращать количество секунд до следующего интервала Vsync в виде значения с плавающей запятой.
Зачем?
Я создаю программы, которые отображают прямоугольники, которые следуют за курсором мыши.
Якобы OpenGL предоставляет механизм vsync в функции glXSwapBuffers, но я считаю, что это ненадежно. С некоторыми драйверами карты вы получаете vsync; с другими вы не делаете. В некоторых случаях вы получаете vsync, но вы также получаете дополнительные 2 кадра задержки.
Но это не ошибка в OpenGL. Спецификация намеренно расплывчата:
Msgstr «Содержимое заднего буфера становится неопределенным.
Обновление обычно происходит во время вертикального отката
монитор,
а не сразу после вызова glXSwapBuffers. «Ключевое слово» обычно «… в основном, glXSwapBuffers не обещает приседания w.r.t. vsync.
В моей текущей попытке решить эту основную проблему я в настоящее время предполагаю начальное время синхронизации, а затем послесловия предполагаем, что фаза равна истекшему времени MOD 1 / (59,85 Гц), которое, кажется, синхронизируется с моим текущим монитором. Но это не очень хорошо работает, потому что я на самом деле не знаю начальную фазу. Так что я получил одну слезу. По крайней мере, он не двигается. Но мне действительно нужно как-то измерить текущую фазу vsync.
Нет, я не хочу полагаться на какой-нибудь вызов OpenGL, чтобы сделать vsync для меня. Из-за неопределенности в спецификации это дает реализации OpenGL возможность добавлять столько задержек, сколько пожелает.
Нет, я не хочу полагаться на какое-то расширение SGI или что-то еще, что должно быть установлено, чтобы оно работало. Это графика 101. Vsync. Просто нужен способ запросить его состояние. НЕКОТОРЫЕ встроенные, всегда установленные API должны иметь это.
Может быть, я могу создать вторичный поток, который каким-то образом ждет Vsync и записывает время, когда это происходит? Но учтите, что следующая последовательность:
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#include <linux/fb.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
int main()
{
int fb = open("/dev/fb0", O_RDWR);
assert(fb != -1);
int zero = 0;
if (ioctl(fb, FBIO_WAITFORVSYNC, &zero) == -1)
printf("fb ioctl failed: %s\n", strerror(errno));
}
НЕ работает в Debian. Результат:
% ./a.out
fb ioctl failed: Inappropriate ioctl for device
% ls -l /dev/fb0
crw-rw-rw- 1 root video 29, 0 Sep 1 20:52 /dev/fb0
Должен быть какой-то способ просто прочитать фазу с устройства или какой-то другой
OpenGL звонок. OpenGL это вещь для графики. Vsync — это графика 101.
Пожалуйста помоги.
Когда вы ищете FBIO_WAITFORVSYNC
в исходниках ядра Linux видно, что он реализован только для нескольких видеокарт, но не для всех.
Таким образом, если у вас есть одна из многих других карт, вы получаете «Несоответствующий ioctl для устройства», что означает, что он не реализован для данного драйвера видеокарты.
Может быть Как ждать VSYNC в приложении Xlib? дает вам подсказку в правильном направлении.
Это графика 101. Vsync. Просто нужен способ запросить его состояние. НЕКОТОРЫЕ встроенные, всегда установленные API должны иметь это.
Нет, не должно быть способа сделать это. По крайней мере, не то, что подвергается воздействию вы. И уж точно ничего кроссплатформенного.
В конце концов, вы не являетесь владельцем экрана. Система владеет экраном; вы арендуете только некоторую его часть и, таким образом, находитесь во власти системы. Система работает с vsync; Ваша задача — заполнить изображения, которые там отображаются.
Рассмотрим Vulkan, уровень которого примерно такой же низкий, как вы получите в эти дни без являющийся графический драйвер. Его интерфейс WSI явно разработан для избежать позволяя вам делать такие вещи, как «ждать до следующей vsync».
Его система представления действительно предлагает множество режимов, но единственные, в которых реализации требуется поддерживать это FIFO: строгий vsync, но не рвать. Конечно, WSI Vulkan, по крайней мере, позволяет вам выбирать, сколько буферизации изображения вы хотите. Но если вы используете FIFO только с двойным буфером и опаздываете с предоставлением этого изображения, то ваш своп не будет виден до следующей vsync.
Схема решения, которое лучше, чем отказаться:
Найдите на цифровом ключе чип MAX, который выводит сигнал синхронизации.
Установите карту RS232.
Подключите сигнал синхронизации к линии рукопожатия на RS232.
Используйте стандартный API termios, который будет работать на любом Linux.
Поместите удивительный продукт в керамический эпоксидный блок и продайте за 500 долларов.