Точное время обновления окна GDK3/GTK3

У меня есть приложение, написанное на C с использованием GTK (хотя язык, вероятно, неважен для этого вопроса).

Это приложение имеет полноэкранный режимgtk_window с одним gtk_drawing_area. Для области рисования я зарегистрировал обратный вызов тика через gtk_widget_add_tick_callback, который просто вызывает gtk_widget_queue_draw каждый тик. Внутри обратного вызова области рисования draw я меняю цвет всего окна через равные промежутки времени (например, с черного на белый с частотой 1 Гц).

Скажем, в этом вызове обратного вызова отрисовки я хочу изменить окно с черного на белое. Я хотел бы знать точное время (с точностью до мс), когда изменение действительно отображается на экране (в идеале в тех же единицах, что и CLOCK_MONOTONIC). Я не думаю, что это то же самое, что GdkFrameClock, доступный в обратном вызове тика, который, как я понимаю, касается времени кадра, а не времени, когда кадр фактически отображается на экране.

Если я просто измерю время CLOCK_MONOTONIC в обратном вызове чертежа, а затем использую фотодиод для измерения, когда фактическое изменение происходит через подключенный A2D, фактическое изменение заключается в том, что отображение по понятным причинам задерживается на несколько интервалов обновления (в моем случае , 3 обновления экрана).

В качестве резюме: если я нахожусь в обратном вызове отрисовки виджета GTK, есть ли способ узнать время, когда дисплей будет фактически отображаться на мониторе, в единицах CLOCK_MONOTONIC? Или, в качестве альтернативы, есть ли способ, которым я могу заблокировать отдельный поток до тех пор, пока конкретная перерисовка, которая мне небезразлична, действительно не отобразится на экране (функция, которую я могу написать как wait_for_screen_flip())?

Обновление: в идеале одно и то же решение будет работать для любого компоновщика Linux (X11 или Wayland), поэтому я надеюсь на решение GTK/GDK, в котором компоновщик абстрагирован.


person David    schedule 24.01.2018    source источник
comment
Любое решение этого вопроса должно работать с GTK? Должен ли он быть переносимым на не-X11 (или вы даже стремитесь, например, только к окнам)?   -  person Uli Schlachter    schedule 27.01.2018
comment
Я использую только Linux, поэтому это может быть решение для Linux. Но в идеале он будет работать на любой комбинации оконного менеджера и композитора (мы используем и X11, и Wayland).   -  person David    schedule 27.01.2018


Ответы (3)


Я только что наткнулся на https://developer.gnome.org/gdk3/stable/gdk3-GdkFrameTimings.html#gdk-frame-timings-get-presentation-time, который, кажется, делает именно то, что вы хотите, и является частью Gdk. Я не знаю, как его использовать, и я не видел его примера, но https://developer.gnome.org/gdk3/stable/gdk3-GdkFrameTimings.html#gdk3-GdkFrameTimings.description говорит

Информация в GdkFrameTimings полезна для точной синхронизации видео с событиями или аудиопотоками, а также для измерения показателей качества отображения приложения, таких как задержка и дрожание.

person Uli Schlachter    schedule 11.02.2018
comment
Ух ты! Не знаю, как я мог это пропустить! Это именно то, что я искал (при условии, что он возвращает время реальной вертикальной синхронизации монитора, а не только время, когда кадр был передан X или Wayland). - person David; 11.02.2018

Подобно ответу Ули о расширении Present и PresentCompleteNotify для X11, Wayland имеет аналогичный протокол под названием wp_presentation_feedback:

https://cgit.freedesktop.org/wayland/wayland-protocols/tree/stable/presentation-time/presentation-time.xml

Этот протокол позволяет компоновщику Wayland информировать клиентов, когда их контент действительно отображался (осветлялся). Он не зависит от фактического используемого буферного механизма (EGL/SHM/и т. д.). Чтобы использовать его, вы вызываете wp_presentation_get_feedback перед wl_surface_commit; когда фиксация завершена, клиенту будет отправлено событие presented из нового объекта wp_presentation_feedback или discarded, если он никогда не отображался.

Обратная связь с презентацией в настоящее время реализована в Weston; он еще не реализован в Mutter, и я не думаю, что он реализован в KWin. GTK+ планирует поддерживать его, когда он станет доступен в Mutter, но я не очень хорошо понимаю, как он будет представлен через GTK+ API.

При этом, если вы можете получить доступ к дисплею Wayland, возможно, вы сможете использовать интерфейс напрямую самостоятельно.

person Daniel Stone    schedule 06.02.2018

Взгляните на https://cgit.freedesktop.org/xorg/proto/presentproto/tree/presentproto.txt. В частности, вы хотите PresentCompleteNotify событий. Обратите внимание, что они могут сообщить вам только позже, когда презентация действительно произошла, поэтому (я думаю) вы не будете знать заранее, когда это произойдет (но вы могли бы догадаться, основываясь на последних уведомлениях?).

Обратите внимание, что это

  • относительно новое расширение X11, поэтому может не везде поддерживаться
  • зависит от используемого драйвера (и, вероятно, множества других факторов) для качества данных
  • нельзя использовать из GTK, так как для этого требуется другой способ отображения на экране (вы рисуете в Pixmap, а затем используете PresentPixmap, чтобы сделать его видимым и запросить уведомление)

Также обратите внимание, что это расширение предоставляет множество других вещей. Например, вы можете сказать «Пожалуйста, покажите вовремя». Просто прочитайте спецификацию протокола от начала до конца. :-)

person Uli Schlachter    schedule 27.01.2018
comment
Привет Ули - Спасибо за это! Есть ли шанс, что такой API доступен в GTK/GDK, чтобы он не зависел от композитора (т.е. работал как для X11, так и для Wayland)? - person David; 29.01.2018
comment
По крайней мере, я ничего подобного в GTK/GDK не знаю, извините. Кроме того, я думаю, что wayland предоставляет какой-то собственный протокол для достижения этой цели, но я не знаю подробностей. Извини. - person Uli Schlachter; 30.01.2018
comment
Точно так же я ничего не нашел в документации GTK/GDK (но я, конечно, не эксперт), рад получить подтверждение. Если кто-то не предложит лучший ответ, я отмечу ваш ответ как принятый. - person David; 30.01.2018