Я занимаюсь разработкой большой игры, которая передает данные уровня (включая шейдеры) по мере продвижения по игровому миру. Я не хочу, чтобы в моей частоте смены кадров возникали проблемы, поскольку шейдеры компилируются / связываются или при первом использовании.
У меня есть шейдерная компиляция и компоновка, работающая в отдельном потоке с собственным контекстом open-gl. Но я не смог заставить предварительный прогрев шейдеров работать в отдельном потоке (чтобы не было снижения производительности при первом использовании шейдера).
Предварительное нагревание действительно не упоминается нигде в документах iOS или OpenGL. Это, однако, упоминается в OpenGL ES Analyzer (один из инструментов, доступных при профилировании из xcode). В этом инструменте я получаю предупреждение «Скомпилированный шейдер вне фазы предварительного нагрева» каждый раз, когда что-то отображается с помощью шейдера, который раньше не использовался для рендеринга чего-либо. «Расширенная деталь» гласит:
"OpenGL ES Analyzer обнаружил компиляцию шейдера, которая не является частью начальной фазы предварительного прогрева. Компиляция шейдера может быть трудоемкой операцией. Чтобы избежать их, прогрейте все шейдеры, используемые для рендеринга. Для этого сделайте предварительный прогрев, когда ваш приложение запускает и выполняет вызов рисования с каждой из используемых программ шейдеров, используя любые настройки состояния gl, с которыми программа шейдера будет использоваться в сочетании с такими состояниями, как смешивание, цветовая маска, логические операции, мультисэмплинг, форматы текстуры и точка все примитивные состояния могут влиять на компиляцию шейдеров. "
Термин «компиляция» здесь немного сбивает с толку. Вершинные и фрагментные шейдеры уже скомпилированы, и программа была связана. Но в первый раз, когда что-то рендерится с данным состоянием OpenGL, я думаю, что еще больше работает с шейдером, чтобы оптимизировать его для этого состояния.
У меня есть код для предварительного прогрева шейдеров путем рендеринга треугольника нулевого размера перед его первым использованием.
Если я скомпилирую, свяжу и предварительно разогрею шейдеры в основном потоке с тем же контекстом Open GL, что и при обычном рендеринге, то это сработает. Однако, если я делаю это в фоновом потоке с отдельным контекстом Open GL, он не работает (он все равно получает предупреждение Analyzer при первом использовании).
Итак ... возможно, предварительное нагревание шейдера в отдельном контексте не влияет на другие контексты. Или может случиться так, что у меня не все то же состояние, настроенное отдельный контекст. Существует много потенциальных состояний Open GL, которые, возможно, потребуется настроить. Я использую буфер закадрового рендеринга в фоновом потоке, чтобы его можно было считать частью состояния.
Кому-нибудь удалось запустить предварительный прогрев в фоновом потоке?