Многопоточное приложение X11 и OpenGL - PullRequest
8 голосов
/ 19 июня 2011

Я пытаюсь создать многопоточное приложение opengl с libx11 - с одним отдельным потоком на окно и одним потоком менеджера.

У меня есть цикл событий в потоке менеджера:

while(true)
  while(XQLength(mPlatformData->display)){
    XNextEvent(mPlatformData->display, &event);
    std::cout << "event" << std::endl;
  }
}

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

Когда я создаю окно, мне нужно отключить очередь событий, иначе GLXMakeCurrent просто зависнет - весь мой поток останавливается и ничего не делает.

Я не могу найти много информации о многопоточных приложениях X11 в сети, должен ли я обрабатывать свои события по-другому?

Ответы [ 3 ]

2 голосов
/ 20 июня 2011

Как сказал Эйл, вам следует проверить, что вы используете XInitThreads.

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

Если вам нужно больше этого, и поскольку вы используете низкоуровневый libX11, лучше всего просто открыть несколько соединений X11 и использовать одно соединение на окно верхнего уровня,Я сделал это 10 лет назад, когда играл в кроссплатформенный инструментарий BeOS, и когда все было в худшем состоянии, то сейчас.

Вы можете использовать это даже для обработки событий и дочерних окон верхнего уровня.Но для этого нужен какой-то очень хитрый код для масок XEvent.

2 голосов
/ 19 июня 2011

Известно, что у Xlib есть несколько неустранимых проблем во время выполнения, которые проявляются в ситуациях параллельного доступа. Я предполагаю, что вы столкнулись именно с одним из них.

Это одна из причин, по которой Xcb был создан в первую очередь: Исправить проблемы Xlib. GLX определен против Xlib, так что это может показаться ограничителем шоу, когда дело доходит до OpenGL. Однако есть Xlib, обертывающий вокруг Xcb, и его можно безопасно использовать для взаимодействия с GLX и все еще использовать Xcb для остальной части программы: http://xcb.freedesktop.org/opengl/

Я вижу два возможных решения:

  1. Поместите XLockDisplay / Mutex вокруг XNextEvent, и GLX вызывает каждого; вам не нужно блокироваться для обычного OpenGL, только функции с префиксом glX....

  2. Используйте Xcb для получения правильного поведения во время выполнения и следуйте руководству, которое я связал выше, чтобы заставить его работать с OpenGL / GLX.

1 голос
/ 20 июня 2011

Что вы делаете в ваших темах рендеринга?В любом случае, если вы используете соединение Display * в разных потоках, вам нужно вызвать XInitThreads.

Я получил хороший опыт работы с одним соединением Display на поток.Используйте XSelectInput для получения событий в вашем основном потоке.Идентификаторы окон доступны для разных подключений Display *.

...