Частота кадров приложения OpenGL снизилась после обновления с iOS7.1 до iOS8.1
Приложение использует OpenGL ES2 и платформу GLKit, а также цикл рендеринга / обновления, предоставляемый GLKitViewController. Раньше он работал со скоростью 60 кадров в секунду на моем iPad2 с iOS7.1, но как только я обновил iPad2 до iOS8.1, тот же самый код теперь колеблется между 56-59 FPS. (Утлитизация процессора, однако, остается на уровне 40-60%, как и раньше).
Профилирование показывает, что команды рисования OpenGL используют гораздо большую долю процессорного времени, чем раньше. Похоже, самое большое изменение заключается в том, что вызовы "GLKBaseEffect prepareToDraw" занимают намного больше времени, чем раньше.
(Приложение использует один GLKBaseEffect, который реконфигурируется в различных точках во время цикла рендеринга, каждый раз вызывая запрос на prepareToDraw. Я понимаю, что возможно оптимизировать, имея несколько экземпляров GLKBaseEffect, и это то, что я рассматривал позже однако производительность на iOS7.1 была стабильной)
Сейчас я исследую трассировку OpenGL ES Analyzer в Instruments, чтобы определить вызовы OpenGL, сгенерированные "GLKBaseEffect prepareToDraw", чтобы увидеть, не кажется ли что-нибудь необычным, и обновлю сообщение соответствующим образом, как только мне удастся что-то выяснить.
Я был бы очень признателен за любые рекомендации о том, как продвигаться в этом направлении - почему вызовы GLKBaseEffect prepareToDraw могут занять больше времени на iOS8.1?
1 ответ
Причина проблемы была определена Джимом Хиллхаусом и подтверждена Frogblast в теме на форумах Apple Dev "Производительность OpenGL падает> 50% в iOS 8 GM": настройка свойства текста UITextField (или UILabel, в моем случае) в представление, являющееся подпредставлением GLKView, вызывает компоновку суперпредставления GLKView, которое затем вызывает освобождение и перераспределение кадровых буферов. Этого не было в iOS 7.
Обходной путь Джима Хиллхауса заключался в том, чтобы поместить подпредставление в UIViewController и внедрить его в GLKView. Я сделал то же самое, используя Контейнерный Вид, чтобы держать контроллер представления, и могу подтвердить, что он работает.