OpenGL ES 2.0 — уменьшение копий памяти при рендеринге в текстуры

Допустим, у меня есть четыре слоя контента: A, B, C и D; каждый представляет один тип визуального контента.

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

Кроме того, слои B и D необходимо преобразовать в текстуры, чтобы применить визуальные эффекты. Чтобы уменьшить объем памяти, я использую только один FBO только с одной текстурой.

Итак, на данный момент я делаю:

  • Рендеринг содержимого;
  • Bind FBO > Render B content > Unbind FBO > Render texture (B content);
  • Рендер С;
  • Bind FBO > Render D content > Unbind FBO > Render texture (D content).

Моя основная проблема с этим подходом заключается в том, что каждый раз, когда я привязываю/отвязываю FBO, буфер кадра по умолчанию сохраняется/восстанавливается в/из памяти.

Я не могу сначала просто нарисовать слои B и D в FBO, так как я не могу изменить порядок рендеринга слоев.

Есть ли лучший способ сделать это и избежать множества сохранений/восстановлений основного фреймбуфера? Имейте в виду, что это пример, а реальный случай более сложный (больше слоев).


person amfcosta    schedule 06.08.2013    source источник
comment
Каждый раз, когда я привязываю/отвязываю FBO, буфер кадра по умолчанию сохраняется/восстанавливается в/из памяти. - Вы уверены в этом? Не является ли одним из основных принципов и преимуществ FBO тот факт, что этого не происходит, поскольку вообще нет необходимости вытеснять/восстанавливать фреймбуфер по умолчанию (хотя может быть, что аппаратное обеспечение ES ведет себя в этом отношении по-другому, что хотя сделать FBO довольно больно)?   -  person Christian Rau    schedule 06.08.2013
comment
Я не уверен, что это происходит на каждом чипе, но, согласно советам по производительности Adreno 200, каждый раз, когда вы связываете и отсоединяете FBO, драйвер разрешает GMEM в/из основной памяти.   -  person amfcosta    schedule 06.08.2013


Ответы (2)


Возможность быстрого переключения между целями рендеринга является основной первоначальной целью функции FBO. Как правило, это быстрее, чем старый подход pbuffer, потому что ему не нужно иметь дело с изменением контекста рендеринга. Кроме того, FBO не так зависят от EGL при распределении поверхностей рендеринга, как pbuffers. Если Adreno 200 не может быстро переключать FBO, то это проблема реализации, специфичная для Adreno.

person ClayMontgomery    schedule 06.08.2013

Драйвер вернет содержимое FBO обратно из памяти (что является дорогостоящей операцией), если вы не очистите FBO с помощью glClear() перед рисованием. Очистка FBO подскажет драйверу отказаться от текущего содержимого и не брать его из основной памяти. Если ваши FBO имеют буфер глубины, убедитесь, что вы также включили этот бит при вызове glClear().

Поскольку вы используете только один FBO, вы не сможете обойти его. Убедитесь, что ваши требования к памяти настолько строги, что вы не можете использовать второй FBO, поэтому вы можете отображать B в свой первый FBO, затем D во второй, а затем все ваши слои контента вместе на экране.

person user1906    schedule 07.08.2013
comment
Проблема в том, что мне потребуется более двух FBO, поскольку реальный случай сложнее, чем пример, который я использовал в вопросе. - person amfcosta; 09.08.2013
comment
Без подробностей трудно сказать, но, может быть, вы могли бы изменить свои вызовы рендеринга для комбинирования эффектов? Например, если у вас есть A, B и C, которые необходимо отрендерить в текстуру, вы можете отрендерить A и B, затем переключиться на экран FBO и отрендерить оба, затем отрендерить в C, вернуть экран FBO и отрендерить результаты. в C. Не идеальное решение, но сэкономит нагрузку на фреймбуфер. - person user1906; 09.08.2013