Метод QGLWidget paintGL() вызывается из какого потока Qt?

предположим, что я использую метод paintGL() QGLWidget для рисования в виджете с помощью OpenGL. После того, как Qt вызвал метод paintGL(), он автоматически запускает подкачку буфера. В OpenGL такая перестановка буфера обычно блокирует вызывающий поток до тех пор, пока не завершится рендеринг кадра в фоновый буфер, верно? Интересно, какой поток Qt вызывает paintGL, а также подкачку буфера. Это основной поток пользовательского интерфейса Qt? Если это так, не означает ли это, что блок во время замены буфера также блокирует весь пользовательский интерфейс? Я не мог найти никакой информации об этом процессе в целом.

Спасибо


person DyingSoul    schedule 15.10.2011    source источник


Ответы (2)


Я не очень часто использую QGLWidget, но учтите, что да, если swapBuffers() является синхронным, поток Qt GUI зависает. Это означает, что во время этой операции вы не сможете обрабатывать события.

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

Более того, эту статью хорошо объясняет ситуацию и представляет новые многопоточные возможности OpenGL в Qt 4.8, который сейчас находится в стадии кандидата на выпуск.

person Luca Carlon    schedule 16.10.2011
comment
Спасибо за ответ и ссылки :-). Параграф Buffer swap thread во второй ссылке в значительной степени объясняет эту проблему. Спасибо. - person DyingSoul; 16.10.2011

В OpenGL такая перестановка буфера обычно блокирует вызывающий поток до тех пор, пока не завершится рендеринг кадра в фоновый буфер, верно?

Это зависит от того, как это реализовано. Это означает, что он варьируется от оборудования к оборудованию и от драйвера к драйверу.

Если это так, не означает ли это, что блок во время замены буфера также блокирует весь пользовательский интерфейс?

Даже если он и блокируется, то только на 1/60 секунды. Может быть, 1/30, если ваша игра тормозит. Если вы очень медленный, 1/15. Максимум одно нажатие клавиши или действие мыши, которое дает пользователь, все еще будет в очереди сообщений.

Проблема с блокировкой не связана с пользовательским интерфейсом. Он будет достаточно отзывчивым, чтобы пользователь его не заметил. Но если у вас строгое время (например, для игры), я бы посоветовал вообще избегать paintGL. Вы должны рендерить, когда хотите, а не тогда, когда Qt говорит вам об этом.

person Nicol Bolas    schedule 15.10.2011
comment
Спасибо за Ваш ответ :-). Даже если характеристики блокировки зависят от реализации, по крайней мере блокировка должна произойти в какой-то момент, верно? В противном случае мы бы постоянно запрашивали больше кадров на стороне процессора, чем может отобразить графический процессор. - person DyingSoul; 16.10.2011
comment
Говоря о фактическом времени блокировки, я думаю, вы имеете в виду время ожидания синхронизации с дисплеем? Разве разница во времени, необходимом на стороне ЦП, с самим временем рендеринга не является худшим временем блокировки, которое мы могли бы? Целью моего приложения является не игра, а скорее научная визуализация. Думаю, мне придется рендерить очень сложные кадры с низкой частотой кадров. Предположим, что графическому процессору потребуется 1 секунда для рендеринга кадра, но всего несколько десятков миллисекунд, чтобы инициировать кадр на стороне процессора. Это полностью убьет мой основной поток графического интерфейса. - person DyingSoul; 16.10.2011
comment
@DyingSoul: Даже если характеристики блокировки зависят от реализации, по крайней мере блокировка должна произойти в какой-то момент, верно? Нет, это вообще не должно происходить. Если драйвер многопоточный или использует внутренний тройной буфер, он может просто поставить ваши команды в очередь и запустить их позже. - person Nicol Bolas; 16.10.2011