Переключить контексты OpenGL или переключить контекст рендеринга вместо этого, что предпочтительнее?

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

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

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

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

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

1 ответов


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

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

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

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