iPhone OpenGL ES glFlush () работает медленно - PullRequest
4 голосов
/ 17 августа 2011

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

glFlush() либо

1) последовательно занимает 0,0003 секунды

OR

2) чередуется между 0,019 и 0,030 секундами

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

Метод рисования вызывается CADisplayLink со следующей настройкой:

dLink = [[UIScreen mainScreen] displayLinkWithTarget:viewController selector:@selector(drawFrame)];
dLink.frameInterval = 1;
[dLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

Я нахожу невозможным определить причину одного из результатов. Кто-нибудь может предложить идеи?

Ответы [ 2 ]

3 голосов
/ 17 августа 2011

Выполнение точной синхронизации на вызовах iOS OpenGL ES в целом немного сложнее из-за использования отложенных средств рендеринга на основе плиток для устройств.Изменения состояния, рисование и другие действия могут быть отложены до непосредственного представления сцены.

Это часто может привести к тому, что что-то вроде glFlush() или -presentRenderBuffer: контекста будет выглядеть очень медленным, хотя на самом деле это просто вызывает выполнение всего отложенного рендеринга в этой точке.

Это не повлияет на ваш случай, когда вы закомментируете весь код для рисования, но glClear().Переменные тайминги, которые вы представляете в своем чередующемся примере, примерно соответствуют 1/53 или 1/33 секунды, что, как мне кажется, указывает на то, что он может просто блокироваться достаточно долго, чтобы соответствовать частоте обновления экрана.CADisplayLink должен поддерживать синхронизацию с обновлением экрана, но я мог иногда видеть, что ваш рисунок немного не соответствует этому.

Вы запускаете этот тест в главном потоке?Может быть что-то, что вызывает небольшую блокировку основного потока, слегка сбивая вас с времени обновления экрана.Я видел уменьшение этого вида колебаний, когда я переместил рендеринг в фоновый поток, но все же он был вызван CADisplayLink.Скорость рендеринга также увеличилась, как и я, особенно на многоядерном iPad 2.

Наконец, я не думаю, что вам нужно явно использовать glFlush() при использовании OpenGL ES на iOS.Ваш EAGLContext * метод presentRenderbuffer: должен быть всем, что требуется для отображения вашего кадра на экране.Я не вижу ни одного экземпляра glFlush() в моем приложении OpenGL ES здесь.В вашем случае это может быть избыточно.

1 голос
/ 22 августа 2011

Я нашел то, что, как мне кажется, было проблемой. Контроллер представления, который был присоединен к EAGLView, НЕ был установлен как корневой контроллер представления окна, как это должно было быть. Вместо этого вид был добавлен вручную как подпредставление в окно. Когда это было исправлено (наряду с несколькими другими связанными исправлениями), метод drawFrame теперь, кажется, идеально синхронизируется с обновлением экрана. Удачи!

...