Как glClear() улучшает производительность?

Apple Technical Q & A для адресации мерцания (QA1650) включает следующий абзац. (Акцент мой.)

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

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

Как вызов glClear() может повысить производительность?

Ответ 1

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

Ответ 2

С длинной перспективой официальных комментариев по iOS 4, которая публикует принятый ответ...

Я думаю, что это следует рассматривать вместе с комментариями Apple о расширении GL_EXT_discard_framebuffer, которые всегда должны использоваться в конце фрейма, если это возможно (и действительно в другом месте). Когда вы отбрасываете буфер кадров, вы помещаете его содержимое в состояние undefined. Преимущество этого заключается в том, что при следующем подключении какого-либо другого буфера кадров никогда не нужно хранить текущее содержимое вашего буфера где-то, и аналогичным образом, когда вы снова восстанавливаете свой буфер, нет необходимости их извлекать. Все они должны быть копиями памяти GPU и поэтому довольно дешевы, но они далеки от свободного, и архитектура общей памяти iPhone предположительно означает, что могут возникнуть даже более сложные соображения.

На основе модели компоновки iOS разумно предположить, что даже если ваше приложение не связывает и не связывает фрейм-буферы в своем контексте, GPU должен выполнять эти задачи неявно, по крайней мере, один раз для каждого из ваших фреймов.

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

Ответ 3

Попробуйте уменьшить размер фреймбуфера в атрибутах glSurface, которые вы передаете SelectConfig.

Например, установите атрибуты на 0 для минимума или полностью опустите их, чтобы использовать значения по умолчанию, если у вас нет конкретного требования.

Ответ 4

Я могу определенно подтвердить, что вы должны обеспечить цвет для каждого пикселя на экране.

Я проверил это в приложении для тестирования голой кости, построенном на шаблоне OpenGL для XCode iPhone:

[context presentRenderbuffer:GL_RENDERBUFFER];  
glClear( GL_COLOR_BUFFER_BIT );

Если я оставлю строку glClear (или перемещаю ее дальше в цикле, после некоторых других вызовов OpenGL), поток (работает через CADisplayLink) вряд ли получит какие-либо обновления. Кажется, что синхронизация CPU/GPU идет haywire, и поток блокируется. Довольно страшные вещи, если вы спросите меня, и полностью не соответствуют моим ожиданиям.

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