Что вызывает колебания времени выполнения при представлении Renderbuffer? (OpenGL) - PullRequest
4 голосов
/ 24 марта 2009

Вот что происходит:

  • Функция drawGL вызывается в точном конце кадра благодаря usleep, как предлагается. Это уже поддерживает стабильную частоту кадров.

  • Фактическое представление рендербуфера происходит с помощью drawGL(). Измерение времени, которое требуется для этого, дает мне колебания времени выполнения, что приводит к заиканию в моей анимации. Этот таймер использует mach_absolute_time, поэтому он чрезвычайно точен .

  • В конце моего кадра я измеряю timeDifference. Да, это в среднем 1 миллисекунда, но сильно отклоняется , в диапазоне от 0,8 миллисекунды до 1,2 с пиками до более 2 миллисекунд.

Пример:

// Every something of a second I call tick
-(void)tick
{
  drawGL(); 
}

- (void)drawGL
{   
  // startTime using mach_absolute_time;

  glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); 
  [context presentRenderbuffer:GL_RENDERBUFFER_OES];

 // endTime using mach_absolute_time;
 // timeDifference = endTime - startTime;
}

Насколько я понимаю, после создания фрейм-буфера представление буфера рендеринга должно всегда занимать одно и то же усилие, независимо от сложности фрейма? Это правда? А если нет, как я могу предотвратить это?

Кстати, это пример приложения для iPhone. Итак, мы здесь говорим об OpenGL ES, хотя я не думаю, что это проблема конкретной платформы. Если это так, то что происходит? И разве это не должно происходить , а не ? И снова, если так, как я могу предотвратить это?

Ответы [ 5 ]

1 голос
/ 28 марта 2009

Быстрый поиск mach_absolute_time приводит к этой статье: Ссылка

Похоже, что точность таймера на iPhone составляет всего 166,67 нс (а может и хуже). Хотя это может объяснить большую разницу, это не объясняет, что есть разница вообще.

Три основные причины, вероятно, следующие:

  • Различные пути выполнения во время представления renderbuffer. Многое может произойти за 1 мс, и то, что вы вызываете одни и те же функции с одинаковыми параметрами, не означает, что выполняются одинаковые инструкции. Это особенно верно, если задействовано другое оборудование.
  • Прерывает / другие процессы, всегда происходит что-то еще, что отвлекает процессор. Насколько я знаю, iPhone OS не является операционной системой реального времени, и поэтому нет никакой гарантии, что любая операция будет завершена в течение определенного периода времени (и даже у операционной системы реального времени будут изменения во времени).
  • Если есть какие-либо другие вызовы OpenGL, все еще обрабатываемые GPU, которые могут задержать presentRenderbuffer. Это проще всего проверить, просто вызовите glFinish (), прежде чем узнаете время начала.
1 голос
/ 26 марта 2009

Мое любимое выражение OpenGL всех времен: "зависящее от реализации" . Я думаю, что это применимо здесь очень хорошо.

1 голос
/ 24 марта 2009

Отклонения, с которыми вы сталкиваетесь, могут быть вызваны множеством факторов, в том числе планировщиком ОС, который запускается и передает процессор другому процессу или аналогичными проблемами. На самом деле нормальный человек не скажет разницы между временем визуализации 1 и 2 мс. Движущиеся изображения работают с частотой 25 кадров в секунду, что означает, что каждый кадр показывается примерно 40 мс, и он выглядит плавным для человеческого глаза.

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

while(loop)
{
  lastFrameTime; // time it took for last frame to render
  timeSinceLastUpdate+= lastFrameTime;

  if(timeSinceLastUpdate > (1 second / DESIRED_UPDATES_PER_SECOND))
  {
     updateAnimation(timeSinceLastUpdate);
     timeSinceLastUpdate = 0;
  }

  // do the drawing

  presentScene();
}

Или вы можете просто передать lastFrameTime для обновления анимации в каждом кадре и интерполировать между состояниями анимации. Результат будет еще более плавным.

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

0 голосов
/ 26 марта 2009

Возможно ли, что таймер не является точным до уровня мс, даже если он возвращает десятичные дроби 0,8-> 2,0?

0 голосов
/ 25 марта 2009

Лучше не полагаться на высокую постоянную частоту кадров по ряду причин, наиболее важным из которых является то, что ОС может что-то делать в фоновом режиме, что замедляет работу. Лучше выбрать таймер и определить, сколько времени прошло каждый кадр, это должно обеспечить плавную анимацию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...