Синхронизация буфера обмена

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

  • GLX_SGIX_swap_group: Доступно только в системе X11.
  • NV_swap_group (WGL_NV_swap_group/GLX_NV_swap_group): Доступно только на графических процессорах Quadro с поддержкой Framelock.
  • GLX_OML_sync_control: Предлагает управление синхронизацией со счетчиком, предлагаемым для vsync и swap, но может потребоваться дополнительная настройка, чтобы реализовать его для подкачки групп. Также недоступна система NV и fglrx (?), Но есть поддержка как для окон, так и для системы X11.

Кажется, у каждого свои ограничения, особенно с точки зрения поддержки оборудования. Я читал, что программная синхронизация свопов также возможна, как барьер свопов, предлагаемый в Equalizer? Можно ли иметь указатель на то, как можно реализовать? Или, если есть альтернативы, я могу быть перенаправлен?

2 ответа

Если приемлемо наличие только одного окна, вы можете использовать отдельные окна просмотра для визуализации каждого из представлений. Например:

glClear(...);

glViewport(x1, y1, width1, height1); // all coordinates are in pixels
// draw scene 1

glViewport(x2, y2, width2, height2);
// draw scene 2

glViewport(x3, y3, width3, height3);
// draw scene 3

SwapBuffers(...); // actual method depends on your environment

Одним из возможных решений было бы включить ожидание VBlank для всех окон (хотя это предполагает, что все окна находятся на одном и том же или синхронизированных экранах) и вручную синхронизировать вызов SwapBuffer. Этот подход не является на 100% водонепроницаемым (так как команда замены буфера может быть выполнена очень близко к реальному кадру "siwtch", и некоторые потоки делают это, в то время как другие пропускают его, но это очень маловероятно и только временный сбой, так как "поздние" потоки задержат "ранние" в последнем кадре, и синхронизация восстановится).

Чтобы реализовать это, вы можете использовать какой-то простой барьер. Только не забудьте очистить конвейер GL вручную, чтобы работа действительно была выполнена, и SwapBuffers мог быть выполнен немедленно. Все, что каждый поток должен сделать в конце кадра, glFinish() и ждать барьера. Как только все нити достигли барьера, они немедленно выдают SwapBuffers(),

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