Вместо этого переключайте контексты OpenGL или переключайте цель визуализации контекста, что предпочтительнее? - PullRequest
6 голосов
/ 14 февраля 2012

В MacOS X вы можете визуализировать OpenGL на любой объект NSView по вашему выбору, просто создав NSOpenGLContext и затем вызвав -setView: для него.Однако вы можете связать только одно представление с одним контекстом OpenGL в любое время.Мой вопрос: если я хочу визуализировать OpenGL для двух разных представлений в одном окне (или, возможно, в двух разных окнах), у меня есть два варианта:

  1. Создать один контекст и всегда изменятьпредставление, вызывая setView в зависимости от ситуации каждый раз, когда я хочу отрендерить другое представление.Это будет работать, даже если представления находятся в разных окнах или на разных экранах.

  2. Создайте два объекта NSOpenGLContext и свяжите одно представление с любым из них.Эти два контекста могут быть общими, что означает, что большинство ресурсов (таких как текстуры, буферы и т. Д.) Будут доступны в обоих представлениях, не тратя вдвое больше памяти.В этом случае, однако, я должен продолжать переключать текущий контекст каждый раз, когда хочу рендерить в другое представление, вызывая -makeCurrentContext в нужном контексте, прежде чем делать какие-либо вызовы OpenGL.

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

С другой стороны, переключение представления может бытьтакже очень медленный, особенно если это может привести к изменению основного рендерера;например, если ваши два представления являются частью двух разных окон, расположенных на двух разных экранах, управляемых двумя разными графическими адаптерами.Даже если рендерер не меняется, я понятия не имею, выполняет ли система много дорогостоящей установки / очистки OpenGL при переключении вида, например, создание / уничтожение объектов рендеринга / кадрового буфера.

1 Ответ

4 голосов
/ 15 февраля 2012

Я исследовал переключение контекста между 3 окнами на Lion, где пытался решить некоторые проблемы с производительностью с помощью несколько неправильно используемой библиотеки VTK, которая сама по себе уже ужасно медленная.

Если вы переключаете контексты рендеринга или окна не имеют большого значения, потому что всегда есть накладные расходы на то, чтобы сделать их текущими для вызывающего потока как тройки. Я измерил примерно 50 мс на коммутатор, где некоторые накладные расходы ОС / оконного менеджера также высоки. Эти издержки также в значительной степени зависят от организации других вызовов GL, поскольку драйвер может быть вынужден ждать завершения команд, что может быть достигнуто вручную с помощью блокирующего вызова glFinish ().

Самая эффективная настройка, с которой я работал, похожа на вашу 2-ую, но имеет два выделенных потока рендеринга, имеющих свой контекст рендеринга (общий доступ) и окно, постоянно связанное. Вышеупомянутые контекстные переключатели / привязки выполняются только один раз при инициализации.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...